diff -Nru xfsprogs-3.1.9ubuntu2/aclocal.m4 xfsprogs-3.2.1ubuntu1/aclocal.m4 --- xfsprogs-3.1.9ubuntu2/aclocal.m4 2012-01-31 09:53:47.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/aclocal.m4 2013-02-14 01:41:04.000000000 +0000 @@ -1,7 +1,8 @@ -# generated automatically by aclocal 1.11.1 -*- Autoconf -*- +# generated automatically by aclocal 1.11.6 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, +# Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. diff -Nru xfsprogs-3.1.9ubuntu2/config.guess xfsprogs-3.2.1ubuntu1/config.guess --- xfsprogs-3.1.9ubuntu2/config.guess 2012-01-31 09:53:45.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/config.guess 2013-02-14 01:41:01.000000000 +0000 @@ -2,9 +2,9 @@ # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011 Free Software Foundation, Inc. +# 2011, 2012 Free Software Foundation, Inc. -timestamp='2011-05-11' +timestamp='2012-02-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -17,9 +17,7 @@ # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -57,8 +55,8 @@ Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free -Software Foundation, Inc. +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -145,7 +143,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward @@ -792,13 +790,12 @@ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) - case ${UNAME_MACHINE} in - pc98) - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) @@ -807,6 +804,9 @@ *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 @@ -861,6 +861,13 @@ i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; @@ -895,13 +902,16 @@ echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) - echo cris-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; frv:Linux:*:*) - echo frv-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu @@ -943,7 +953,7 @@ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) - echo or32-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu @@ -978,13 +988,13 @@ echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-tilera-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu @@ -1315,6 +1325,9 @@ i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 diff -Nru xfsprogs-3.1.9ubuntu2/config.sub xfsprogs-3.2.1ubuntu1/config.sub --- xfsprogs-3.1.9ubuntu2/config.sub 2012-01-31 09:53:45.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/config.sub 2013-02-14 01:41:01.000000000 +0000 @@ -2,9 +2,9 @@ # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011 Free Software Foundation, Inc. +# 2011, 2012 Free Software Foundation, Inc. -timestamp='2011-03-23' +timestamp='2012-04-18' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -21,9 +21,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -76,8 +74,8 @@ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free -Software Foundation, Inc. +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -132,6 +130,10 @@ os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] @@ -223,6 +225,12 @@ -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; -lynx*) os=-lynxos ;; @@ -247,17 +255,22 @@ # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ + | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ + | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ + | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ @@ -291,7 +304,7 @@ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ - | rx \ + | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ @@ -300,7 +313,7 @@ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ - | v850 | v850e \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) @@ -315,8 +328,7 @@ c6x) basic_machine=tic6x-unknown ;; - m6811 | m68hc11 | m6812 | m68hc12 | picochip) - # Motorola 68HC11/12. + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; @@ -329,7 +341,10 @@ strongarm | thumb | xscale) basic_machine=arm-unknown ;; - + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; xscaleeb) basic_machine=armeb-unknown ;; @@ -352,11 +367,13 @@ # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ + | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ + | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ @@ -365,8 +382,10 @@ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ + | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ @@ -400,7 +419,7 @@ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ - | romp-* | rs6000-* | rx-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ @@ -408,10 +427,11 @@ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile-* | tilegx-* \ + | tile*-* \ | tron-* \ | ubicom32-* \ - | v850-* | v850e-* | vax-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ @@ -711,7 +731,6 @@ i370-ibm* | ibm*) basic_machine=i370-ibm ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 @@ -808,10 +827,18 @@ ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; + msys) + basic_machine=i386-pc + os=-msys + ;; mvs) basic_machine=i370-ibm os=-mvs ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; ncr3000) basic_machine=i486-ncr os=-sysv4 @@ -1120,13 +1147,8 @@ basic_machine=t90-cray os=-unicos ;; - # This must be matched before tile*. - tilegx*) - basic_machine=tilegx-unknown - os=-linux-gnu - ;; tile*) - basic_machine=tile-unknown + basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) @@ -1336,7 +1358,7 @@ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ @@ -1521,6 +1543,9 @@ c4x-* | tic4x-*) os=-coff ;; + hexagon-*) + os=-elf + ;; tic54x-*) os=-coff ;; @@ -1548,9 +1573,6 @@ ;; m68000-sun) os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 ;; m68*-cisco) os=-aout diff -Nru xfsprogs-3.1.9ubuntu2/configure xfsprogs-3.2.1ubuntu1/configure --- xfsprogs-3.1.9ubuntu2/configure 2013-12-18 17:13:26.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/configure 2014-08-08 11:52:02.000000000 +0000 @@ -1,11 +1,9 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68. +# Generated by GNU Autoconf 2.69 for xfsprogs 3.1.10. # # -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software -# Foundation, Inc. +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation @@ -134,6 +132,31 @@ # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh @@ -167,7 +190,8 @@ else exitcode=1; echo positional parameters were not saved. fi -test x\$exitcode = x0 || exit 1" +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && @@ -220,21 +244,25 @@ if test "x$CONFIG_SHELL" != x; then : - # We cannot yet assume a decent shell, so we have to provide a - # neutralization value for shells without unset; and this also - # works around shells that cannot unset nonexistent variables. - # Preserve -v and -x to the replacement shell. - BASH_ENV=/dev/null - ENV=/dev/null - (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV - export CONFIG_SHELL - case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; - esac - exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 fi if test x$as_have_required = xno; then : @@ -336,6 +364,14 @@ } # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take @@ -457,6 +493,10 @@ chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). @@ -491,16 +531,16 @@ # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -512,28 +552,8 @@ as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -565,12 +585,12 @@ MAKEFLAGS= # Identity of this package. -PACKAGE_NAME= -PACKAGE_TARNAME= -PACKAGE_VERSION= -PACKAGE_STRING= -PACKAGE_BUGREPORT= -PACKAGE_URL= +PACKAGE_NAME='xfsprogs' +PACKAGE_TARNAME='xfsprogs' +PACKAGE_VERSION='3.1.10' +PACKAGE_STRING='xfsprogs 3.1.10' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' ac_unique_file="include/libxfs.h" ac_default_prefix=/usr @@ -615,6 +635,8 @@ have_zipped_manpages libblkid enable_blkid +have_sync_file_range +have_preadv have_fiemap have_fallocate have_getmntinfo @@ -816,7 +838,7 @@ localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE}' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' @@ -1231,8 +1253,6 @@ if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1318,7 +1338,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures this package to adapt to many kinds of systems. +\`configure' configures xfsprogs 3.1.10 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1366,7 +1386,7 @@ --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --docdir=DIR documentation root [DATAROOTDIR/doc/xfsprogs] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] @@ -1382,7 +1402,9 @@ fi if test -n "$ac_init_help"; then - + case $ac_init_help in + short | recursive ) echo "Configuration of xfsprogs 3.1.10:";; + esac cat <<\_ACEOF Optional Features: @@ -1487,10 +1509,10 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -configure -generated by GNU Autoconf 2.68 +xfsprogs configure 3.1.10 +generated by GNU Autoconf 2.69 -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1566,7 +1588,7 @@ test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext + test -x conftest$ac_exeext }; then : ac_retval=0 else @@ -1866,7 +1888,8 @@ main () { static int test_array [1 - 2 * !(($2) >= 0)]; -test_array [0] = 0 +test_array [0] = 0; +return test_array [0]; ; return 0; @@ -1882,7 +1905,8 @@ main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0 +test_array [0] = 0; +return test_array [0]; ; return 0; @@ -1908,7 +1932,8 @@ main () { static int test_array [1 - 2 * !(($2) < 0)]; -test_array [0] = 0 +test_array [0] = 0; +return test_array [0]; ; return 0; @@ -1924,7 +1949,8 @@ main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; -test_array [0] = 0 +test_array [0] = 0; +return test_array [0]; ; return 0; @@ -1958,7 +1984,8 @@ main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0 +test_array [0] = 0; +return test_array [0]; ; return 0; @@ -2030,8 +2057,8 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by $as_me, which was -generated by GNU Autoconf 2.68. Invocation command line was +It was created by xfsprogs $as_me 3.1.10, which was +generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2409,6 +2436,7 @@ + ac_config_headers="$ac_config_headers include/platform_defs.h" @@ -2600,7 +2628,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2640,7 +2668,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2693,7 +2721,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2734,7 +2762,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -2792,7 +2820,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2836,7 +2864,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3282,8 +3310,7 @@ /* end confdefs.h. */ #include #include -#include -#include +struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); @@ -3390,7 +3417,7 @@ for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue + as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in @@ -3466,7 +3493,7 @@ for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in @@ -3532,7 +3559,7 @@ for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in @@ -3599,7 +3626,7 @@ for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue + as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in @@ -3855,7 +3882,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3899,7 +3926,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4088,7 +4115,8 @@ ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else @@ -4323,7 +4351,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4363,7 +4391,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4489,10 +4517,6 @@ fi ;; -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - haiku*) lt_cv_deplibs_check_method=pass_all ;; @@ -4531,7 +4555,7 @@ ;; # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; @@ -4669,7 +4693,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4709,7 +4733,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4813,7 +4837,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4857,7 +4881,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4982,7 +5006,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5022,7 +5046,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5081,7 +5105,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5121,7 +5145,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5225,7 +5249,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5671,7 +5695,14 @@ LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) - LD="${LD-ld} -m elf_i386" + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac ;; powerpc64le-*) LD="${LD-ld} -m elf32lppclinux" @@ -5818,7 +5849,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5858,7 +5889,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5938,7 +5969,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5978,7 +6009,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6030,7 +6061,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6070,7 +6101,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6122,7 +6153,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6162,7 +6193,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6214,7 +6245,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6254,7 +6285,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6306,7 +6337,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6346,7 +6377,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7506,7 +7537,7 @@ lt_prog_compiler_static='-non_shared' ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) @@ -9676,17 +9707,6 @@ esac ;; -gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no @@ -9803,7 +9823,7 @@ ;; # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no @@ -10979,7 +10999,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -11019,7 +11039,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -11072,7 +11092,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -11113,7 +11133,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -11171,7 +11191,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -11215,7 +11235,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -11411,8 +11431,7 @@ /* end confdefs.h. */ #include #include -#include -#include +struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); @@ -11553,7 +11572,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -11593,7 +11612,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -11646,7 +11665,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -11687,7 +11706,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -11745,7 +11764,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -11789,7 +11808,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -11985,8 +12004,7 @@ /* end confdefs.h. */ #include #include -#include -#include +struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); @@ -12101,7 +12119,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MAKE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12143,7 +12161,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MAKE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12196,7 +12214,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_TAR="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12241,7 +12259,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ZIP="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12313,7 +12331,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_AWK="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12359,7 +12377,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12405,7 +12423,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ECHO="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12451,7 +12469,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_SORT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12510,7 +12528,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MSGFMT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12563,7 +12581,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MSGMERGE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12616,7 +12634,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_XGETTEXT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12670,7 +12688,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_RPM="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12719,7 +12737,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_RPMBUILD="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13261,7 +13279,7 @@ { struct fiemap *fiemap; - ioctl(0, FS_IOC_FIEMAP, 0, (unsigned long)fiemap); + ioctl(0, FS_IOC_FIEMAP, (unsigned long)fiemap); ; return 0; @@ -13279,6 +13297,68 @@ conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for preadv" >&5 +$as_echo_n "checking for preadv... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define _FILE_OFFSET_BITS 64 +#define _BSD_SOURCE +#include + +int +main () +{ + + preadv(0, 0, 0, 0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + have_preadv=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sync_file_range" >&5 +$as_echo_n "checking for sync_file_range... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define _GNU_SOURCE +#define _FILE_OFFSET_BITS 64 +#include + +int +main () +{ + + sync_file_range(0, 0, 0, 0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + have_sync_file_range=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + enable_blkid="$enable_blkid" if test "$enable_blkid" = "yes"; then @@ -13360,6 +13440,72 @@ +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +$as_echo_n "checking size of long... " >&6; } +if ${ac_cv_sizeof_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +$as_echo "$ac_cv_sizeof_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char *" >&5 +$as_echo_n "checking size of char *... " >&6; } +if ${ac_cv_sizeof_char_p+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char *))" "ac_cv_sizeof_char_p" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_char_p" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (char *) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_char_p=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char_p" >&5 +$as_echo "$ac_cv_sizeof_char_p" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_CHAR_P $ac_cv_sizeof_char_p +_ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __psint_t " >&5 $as_echo_n "checking for __psint_t ... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -13447,93 +13593,6 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if test "$cross_compiling" = yes -a -z "$ac_cv_sizeof_long"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cross compiling; assuming 32bit long and 32bit pointers" >&5 -$as_echo "$as_me: WARNING: Cross compiling; assuming 32bit long and 32bit pointers" >&2;} - fi - # The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 -$as_echo_n "checking size of long... " >&6; } -if ${ac_cv_sizeof_long+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_long" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (long) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_long=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 -$as_echo "$ac_cv_sizeof_long" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_LONG $ac_cv_sizeof_long -_ACEOF - - - # The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char *" >&5 -$as_echo_n "checking size of char *... " >&6; } -if ${ac_cv_sizeof_char_p+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char *))" "ac_cv_sizeof_char_p" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_char_p" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (char *) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_char_p=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char_p" >&5 -$as_echo "$ac_cv_sizeof_char_p" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_CHAR_P $ac_cv_sizeof_char_p -_ACEOF - - - if test $ac_cv_sizeof_long -eq 4 -o $ac_cv_sizeof_long -eq 0; then - $as_echo "#define HAVE_32BIT_LONG 1" >>confdefs.h - - fi - if test $ac_cv_sizeof_long -eq 8; then - $as_echo "#define HAVE_64BIT_LONG 1" >>confdefs.h - - fi - if test $ac_cv_sizeof_char_p -eq 4 -o $ac_cv_sizeof_char_p -eq 0; then - $as_echo "#define HAVE_32BIT_PTR 1" >>confdefs.h - - fi - if test $ac_cv_sizeof_char_p -eq 8; then - $as_echo "#define HAVE_64BIT_PTR 1" >>confdefs.h - - fi - have_zipped_manpages=false for d in ${prefix}/share/man ${prefix}/man ; do if test -f $d/man1/man.1.gz @@ -13954,16 +14013,16 @@ # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -14023,28 +14082,16 @@ as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -14065,8 +14112,8 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by $as_me, which was -generated by GNU Autoconf 2.68. Invocation command line was +This file was extended by xfsprogs $as_me 3.1.10, which was +generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -14131,11 +14178,11 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -config.status -configured by $0, generated by GNU Autoconf 2.68, +xfsprogs config.status 3.1.10 +configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -14224,7 +14271,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' diff -Nru xfsprogs-3.1.9ubuntu2/configure.ac xfsprogs-3.2.1ubuntu1/configure.ac --- xfsprogs-3.1.9ubuntu2/configure.ac 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/configure.ac 2014-05-02 00:09:15.000000000 +0000 @@ -1,4 +1,4 @@ -AC_INIT([xfsprogs], [3.1.9]) +AC_INIT([xfsprogs], [3.2.0-alpha2]) AC_PREREQ(2.50) AC_CONFIG_AUX_DIR([.]) AC_CONFIG_MACRO_DIR([m4]) @@ -112,12 +112,14 @@ AC_HAVE_PREADV AC_HAVE_SYNC_FILE_RANGE AC_HAVE_BLKID_TOPO($enable_blkid) +AC_HAVE_READDIR AC_CHECK_SIZEOF([long]) AC_CHECK_SIZEOF([char *]) AC_TYPE_PSINT AC_TYPE_PSUNSIGNED AC_TYPE_U32 +AC_TYPE_UMODE_T AC_MANUAL_FORMAT AC_CONFIG_FILES([include/builddefs]) diff -Nru xfsprogs-3.1.9ubuntu2/copy/xfs_copy.c xfsprogs-3.2.1ubuntu1/copy/xfs_copy.c --- xfsprogs-3.1.9ubuntu2/copy/xfs_copy.c 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/copy/xfs_copy.c 2014-06-19 22:42:17.000000000 +0000 @@ -217,28 +217,9 @@ } void -killall(void) -{ - int i; - - /* only the parent gets to kill things */ - - if (getpid() != parent_pid) - return; - - for (i = 0; i < num_targets; i++) { - if (target[i].state == ACTIVE) { - /* kill up target threads */ - pthread_kill(target[i].pid, SIGKILL); - pthread_mutex_unlock(&targ[i].wait); - } - } -} - -void handler(int sig) { - pid_t pid = getpid(); + pid_t pid; int status, i; pid = wait(&status); @@ -301,7 +282,7 @@ usage(void) { fprintf(stderr, - _("Usage: %s [-bd] [-L logfile] source target [target ...]\n"), + _("Usage: %s [-bdV] [-L logfile] source target [target ...]\n"), progname); exit(1); } @@ -400,8 +381,7 @@ if (buf->length > buf->size) { do_warn(_("assert error: buf->length = %d, buf->size = %d\n"), buf->length, buf->size); - killall(); - abort(); + exit(1); } if ((res = read(fd, buf->data, buf->length)) < 0) { @@ -434,6 +414,10 @@ off = XFS_AG_DADDR(mp, agno, XFS_SB_DADDR); buf->position = (xfs_off_t) off * (xfs_off_t) BBSIZE; length = buf->length = first_agbno * blocksize; + if (length == 0) { + do_log(_("ag header buffer invalid!\n")); + exit(1); + } /* handle alignment stuff */ @@ -449,7 +433,6 @@ if (buf->length % buf->min_io_size != 0) buf->length = roundup(buf->length, buf->min_io_size); - ASSERT(length != 0); read_wbuf(fd, buf, mp); ASSERT(buf->length >= length); @@ -591,11 +574,6 @@ parent_pid = getpid(); - if (atexit(killall)) { - do_log(_("%s: couldn't register atexit function.\n"), progname); - die_perror(); - } - /* open up source -- is it a file? */ open_flags = O_RDONLY; @@ -674,12 +652,24 @@ /* prepare the mount structure */ - sbp = libxfs_readbuf(xargs.ddev, XFS_SB_DADDR, 1, 0); memset(&mbuf, 0, sizeof(xfs_mount_t)); + libxfs_buftarg_init(&mbuf, xargs.ddev, xargs.logdev, xargs.rtdev); + sbp = libxfs_readbuf(mbuf.m_ddev_targp, XFS_SB_DADDR, 1, 0, + &xfs_sb_buf_ops); sb = &mbuf.m_sb; libxfs_sb_from_disk(sb, XFS_BUF_TO_SBP(sbp)); - mp = libxfs_mount(&mbuf, sb, xargs.ddev, xargs.logdev, xargs.rtdev, 1); + /* + * For now, V5 superblock filesystems are not supported without -d; + * we do not have the infrastructure yet to fix CRCs when a new UUID + * is generated. + */ + if (xfs_sb_version_hascrc(sb) && !duplicate) { + do_log(_("%s: Cannot yet copy V5 fs without '-d'\n"), progname); + exit(1); + } + + mp = libxfs_mount(&mbuf, sb, xargs.ddev, xargs.logdev, xargs.rtdev, 0); if (mp == NULL) { do_log(_("%s: %s filesystem failed to initialize\n" "%s: Aborting.\n"), progname, source_name, progname); @@ -710,7 +700,7 @@ if (source_blocksize > source_sectorsize) { /* get number of leftover sectors in last block of ag header */ - tmp_residue = ((XFS_AGFL_DADDR(mp) + 1) * source_sectorsize) + tmp_residue = ((XFS_AGFL_DADDR(mp) + 1) * BBSIZE) % source_blocksize; first_residue = (tmp_residue == 0) ? 0 : source_blocksize - tmp_residue; @@ -723,10 +713,10 @@ exit(1); } - first_agbno = (((XFS_AGFL_DADDR(mp) + 1) * source_sectorsize) + first_agbno = (((XFS_AGFL_DADDR(mp) + 1) * BBSIZE) + first_residue) / source_blocksize; ASSERT(first_agbno != 0); - ASSERT( ((((XFS_AGFL_DADDR(mp) + 1) * source_sectorsize) + ASSERT(((((XFS_AGFL_DADDR(mp) + 1) * BBSIZE) + first_residue) % source_blocksize) == 0); /* now open targets */ @@ -897,7 +887,6 @@ - (__uint64_t)mp->m_sb.sb_fdblocks + 10 * num_ags)); kids = num_targets; - block = (struct xfs_btree_block *) btree_buf.data; for (agno = 0; agno < num_ags && kids > 0; agno++) { /* read in first blocks of the ag */ @@ -934,7 +923,12 @@ for (;;) { /* none of this touches the w_buf buffer */ - ASSERT(current_level < btree_levels); + if (current_level >= btree_levels) { + do_log( + _("Error: current level %d >= btree levels %d\n"), + current_level, btree_levels); + exit(1); + } current_level++; @@ -947,7 +941,13 @@ ((char *)btree_buf.data + pos - btree_buf.position); - ASSERT(be32_to_cpu(block->bb_magic) == XFS_ABTB_MAGIC); + if (be32_to_cpu(block->bb_magic) != + (xfs_sb_version_hascrc(&mp->m_sb) ? + XFS_ABTB_CRC_MAGIC : XFS_ABTB_MAGIC)) { + do_log(_("Bad btree magic 0x%x\n"), + be32_to_cpu(block->bb_magic)); + exit(1); + } if (be16_to_cpu(block->bb_level) == 0) break; @@ -1152,9 +1152,6 @@ } check_errors(); - killall(); - pthread_exit(NULL); - /*NOTREACHED*/ return 0; } diff -Nru xfsprogs-3.1.9ubuntu2/db/addr.c xfsprogs-3.2.1ubuntu1/db/addr.c --- xfsprogs-3.1.9ubuntu2/db/addr.c 2009-02-17 01:14:58.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/addr.c 2014-05-02 00:09:15.000000000 +0000 @@ -85,16 +85,14 @@ fl = flist_scan(argv[1]); if (fl == NULL) return 0; - if (!flist_parse(fld, fl, iocur_top->data, 0)) { - flist_free(fl); - return 0; - } + if (!flist_parse(fld, fl, iocur_top->data, 0)) + goto out; + flist_print(fl); for (tfl = fl; tfl->child != NULL; tfl = tfl->child) { if ((tfl->flags & FL_OKLOW) && tfl->low < tfl->high) { dbprintf(_("array not allowed for addr command\n")); - flist_free(fl); - return 0; + goto out; } } fld = tfl->fld; @@ -103,7 +101,7 @@ next = inode_next_type(); if (next == TYP_NONE) { dbprintf(_("no next type for field %s\n"), fld->name); - return 0; + goto out; } fa = &ftattrtab[fld->ftyp]; ASSERT(fa->ftyp == fld->ftyp); @@ -111,9 +109,10 @@ if (adf == NULL) { dbprintf(_("no addr function for field %s (type %s)\n"), fld->name, fa->name); - return 0; + goto out; } (*adf)(iocur_top->data, tfl->offset, next); +out: flist_free(fl); return 0; } diff -Nru xfsprogs-3.1.9ubuntu2/db/agf.c xfsprogs-3.2.1ubuntu1/db/agf.c --- xfsprogs-3.1.9ubuntu2/db/agf.c 2009-02-17 01:14:58.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/agf.c 2014-05-02 00:09:15.000000000 +0000 @@ -69,6 +69,9 @@ { "freeblks", FLDT_EXTLEN, OI(OFF(freeblks)), C1, 0, TYP_NONE }, { "longest", FLDT_EXTLEN, OI(OFF(longest)), C1, 0, TYP_NONE }, { "btreeblks", FLDT_UINT32D, OI(OFF(btreeblks)), C1, 0, TYP_NONE }, + { "uuid", FLDT_UUID, OI(OFF(uuid)), C1, 0, TYP_NONE }, + { "lsn", FLDT_UINT64X, OI(OFF(lsn)), C1, 0, TYP_NONE }, + { "crc", FLDT_CRC, OI(OFF(crc)), C1, 0, TYP_NONE }, { NULL } }; diff -Nru xfsprogs-3.1.9ubuntu2/db/agfl.c xfsprogs-3.2.1ubuntu1/db/agfl.c --- xfsprogs-3.1.9ubuntu2/db/agfl.c 2009-02-17 01:14:58.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/agfl.c 2014-05-02 00:09:15.000000000 +0000 @@ -41,8 +41,24 @@ { NULL } }; +const field_t agfl_crc_hfld[] = { { + "", FLDT_AGFL_CRC, OI(0), C1, 0, TYP_NONE, }, + { NULL } +}; + #define OFF(f) bitize(offsetof(xfs_agfl_t, agfl_ ## f)) const field_t agfl_flds[] = { + { "bno", FLDT_AGBLOCKNZ, OI(OFF(magicnum)), agfl_bno_size, + FLD_ARRAY|FLD_COUNT, TYP_DATA }, + { NULL } +}; + +const field_t agfl_crc_flds[] = { + { "magicnum", FLDT_UINT32X, OI(OFF(magicnum)), C1, 0, TYP_NONE }, + { "seqno", FLDT_AGNUMBER, OI(OFF(seqno)), C1, 0, TYP_NONE }, + { "uuid", FLDT_UUID, OI(OFF(uuid)), C1, 0, TYP_NONE }, + { "lsn", FLDT_UINT64X, OI(OFF(lsn)), C1, 0, TYP_NONE }, + { "crc", FLDT_CRC, OI(OFF(crc)), C1, 0, TYP_NONE }, { "bno", FLDT_AGBLOCKNZ, OI(OFF(bno)), agfl_bno_size, FLD_ARRAY|FLD_COUNT, TYP_DATA }, { NULL } diff -Nru xfsprogs-3.1.9ubuntu2/db/agfl.h xfsprogs-3.2.1ubuntu1/db/agfl.h --- xfsprogs-3.1.9ubuntu2/db/agfl.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/agfl.h 2013-10-10 21:07:16.000000000 +0000 @@ -18,6 +18,8 @@ extern const struct field agfl_flds[]; extern const struct field agfl_hfld[]; +extern const struct field agfl_crc_flds[]; +extern const struct field agfl_crc_hfld[]; extern void agfl_init(void); extern int agfl_size(void *obj, int startoff, int idx); diff -Nru xfsprogs-3.1.9ubuntu2/db/agi.c xfsprogs-3.2.1ubuntu1/db/agi.c --- xfsprogs-3.1.9ubuntu2/db/agi.c 2009-02-17 01:14:58.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/agi.c 2014-06-19 22:42:17.000000000 +0000 @@ -54,6 +54,11 @@ { "dirino", FLDT_AGINO, OI(OFF(dirino)), C1, 0, TYP_INODE }, { "unlinked", FLDT_AGINONN, OI(OFF(unlinked)), CI(XFS_AGI_UNLINKED_BUCKETS), FLD_ARRAY, TYP_NONE }, + { "uuid", FLDT_UUID, OI(OFF(uuid)), C1, 0, TYP_NONE }, + { "lsn", FLDT_UINT64X, OI(OFF(lsn)), C1, 0, TYP_NONE }, + { "crc", FLDT_CRC, OI(OFF(crc)), C1, 0, TYP_NONE }, + { "free_root", FLDT_AGBLOCK, OI(OFF(free_root)), C1, 0, TYP_INOBT }, + { "free_level", FLDT_UINT32D, OI(OFF(free_level)), C1, 0, TYP_NONE }, { NULL } }; diff -Nru xfsprogs-3.1.9ubuntu2/db/attr.c xfsprogs-3.2.1ubuntu1/db/attr.c --- xfsprogs-3.1.9ubuntu2/db/attr.c 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/attr.c 2014-05-02 00:09:15.000000000 +0000 @@ -25,6 +25,7 @@ #include "attr.h" #include "io.h" #include "init.h" +#include "output.h" static int attr_leaf_entries_count(void *obj, int startoff); static int attr_leaf_hdr_count(void *obj, int startoff); @@ -54,7 +55,7 @@ FLD_COUNT, TYP_NONE }, { "entries", FLDT_ATTR_LEAF_ENTRY, OI(LOFF(entries)), attr_leaf_entries_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, - { "btree", FLDT_ATTR_NODE_ENTRY, OI(NOFF(btree)), attr_node_btree_count, + { "btree", FLDT_ATTR_NODE_ENTRY, OI(NOFF(__btree)), attr_node_btree_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, { "nvlist", FLDT_ATTR_LEAF_NAME, attr_leaf_nvlist_offset, attr_leaf_nvlist_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE }, @@ -143,89 +144,146 @@ #define HOFF(f) bitize(offsetof(xfs_da_node_hdr_t, f)) const field_t attr_node_hdr_flds[] = { { "info", FLDT_ATTR_BLKINFO, OI(HOFF(info)), C1, 0, TYP_NONE }, - { "count", FLDT_UINT16D, OI(HOFF(count)), C1, 0, TYP_NONE }, - { "level", FLDT_UINT16D, OI(HOFF(level)), C1, 0, TYP_NONE }, + { "count", FLDT_UINT16D, OI(HOFF(__count)), C1, 0, TYP_NONE }, + { "level", FLDT_UINT16D, OI(HOFF(__level)), C1, 0, TYP_NONE }, { NULL } }; -/*ARGSUSED*/ static int attr_leaf_entries_count( void *obj, int startoff) { - xfs_attr_leafblock_t *block; + struct xfs_attr_leafblock *leaf = obj; ASSERT(startoff == 0); - block = obj; - if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) + if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; - return be16_to_cpu(block->hdr.count); + return be16_to_cpu(leaf->hdr.count); +} + +static int +attr3_leaf_entries_count( + void *obj, + int startoff) +{ + struct xfs_attr3_leafblock *leaf = obj; + + ASSERT(startoff == 0); + if (be16_to_cpu(leaf->hdr.info.hdr.magic) != XFS_ATTR3_LEAF_MAGIC) + return 0; + return be16_to_cpu(leaf->hdr.count); } -/*ARGSUSED*/ static int attr_leaf_hdr_count( void *obj, int startoff) { - xfs_attr_leafblock_t *block; + struct xfs_attr_leafblock *leaf = obj; ASSERT(startoff == 0); - block = obj; - return be16_to_cpu(block->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC; + return be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC; } static int -attr_leaf_name_local_count( +attr3_leaf_hdr_count( void *obj, int startoff) { - xfs_attr_leafblock_t *block; - xfs_attr_leaf_entry_t *e; - int i; - int off; + struct xfs_attr3_leafblock *leaf = obj; + + ASSERT(startoff == 0); + return be16_to_cpu(leaf->hdr.info.hdr.magic) == XFS_ATTR3_LEAF_MAGIC; +} + +typedef int (*attr_leaf_entry_walk_f)(struct xfs_attr_leafblock *, + struct xfs_attr_leaf_entry *, int); +static int +attr_leaf_entry_walk( + void *obj, + int startoff, + attr_leaf_entry_walk_f func) +{ + struct xfs_attr_leafblock *leaf = obj; + struct xfs_attr3_icleaf_hdr leafhdr; + struct xfs_attr_leaf_entry *entries; + struct xfs_attr_leaf_entry *e; + int i; + int off; ASSERT(bitoffs(startoff) == 0); - off = byteize(startoff); - block = obj; - if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) + if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC && + be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR3_LEAF_MAGIC) return 0; - for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { - e = &block->entries[i]; + + off = byteize(startoff); + xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf); + entries = xfs_attr3_leaf_entryp(leaf); + + for (i = 0; i < leafhdr.count; i++) { + e = &entries[i]; if (be16_to_cpu(e->nameidx) == off) - return (e->flags & XFS_ATTR_LOCAL) != 0; + return func(leaf, e, i); } return 0; } static int +__attr_leaf_name_local_count( + struct xfs_attr_leafblock *leaf, + struct xfs_attr_leaf_entry *e, + int i) +{ + return (e->flags & XFS_ATTR_LOCAL) != 0; +} + +static int +attr_leaf_name_local_count( + void *obj, + int startoff) +{ + return attr_leaf_entry_walk(obj, startoff, + __attr_leaf_name_local_count); +} + +static int +__attr_leaf_name_local_name_count( + struct xfs_attr_leafblock *leaf, + struct xfs_attr_leaf_entry *e, + int i) +{ + struct xfs_attr_leaf_name_local *l; + + if (!(e->flags & XFS_ATTR_LOCAL)) + return 0; + + l = xfs_attr3_leaf_name_local(leaf, i); + return l->namelen; +} + +static int attr_leaf_name_local_name_count( void *obj, int startoff) { - xfs_attr_leafblock_t *block; - xfs_attr_leaf_entry_t *e; - int i; - xfs_attr_leaf_name_local_t *l; - int off; + return attr_leaf_entry_walk(obj, startoff, + __attr_leaf_name_local_name_count); +} - ASSERT(bitoffs(startoff) == 0); - off = byteize(startoff); - block = obj; - if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) +static int +__attr_leaf_name_local_value_count( + struct xfs_attr_leafblock *leaf, + struct xfs_attr_leaf_entry *e, + int i) +{ + struct xfs_attr_leaf_name_local *l; + + if (!(e->flags & XFS_ATTR_LOCAL)) return 0; - for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { - e = &block->entries[i]; - if (be16_to_cpu(e->nameidx) == off) { - if (e->flags & XFS_ATTR_LOCAL) { - l = xfs_attr_leaf_name_local(block, i); - return l->namelen; - } else - return 0; - } - } - return 0; + + l = xfs_attr3_leaf_name_local(leaf, i); + return be16_to_cpu(l->valuelen); } static int @@ -233,84 +291,66 @@ void *obj, int startoff) { - xfs_attr_leafblock_t *block; - xfs_attr_leaf_entry_t *e; - int i; - xfs_attr_leaf_name_local_t *l; - int off; + return attr_leaf_entry_walk(obj, startoff, + __attr_leaf_name_local_value_count); +} - ASSERT(bitoffs(startoff) == 0); - off = byteize(startoff); - block = obj; - if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) - return 0; - for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { - e = &block->entries[i]; - if (be16_to_cpu(e->nameidx) == off) { - if (e->flags & XFS_ATTR_LOCAL) { - l = xfs_attr_leaf_name_local(block, i); - return be16_to_cpu(l->valuelen); - } else - return 0; - } - } - return 0; +static int +__attr_leaf_name_local_value_offset( + struct xfs_attr_leafblock *leaf, + struct xfs_attr_leaf_entry *e, + int i) +{ + struct xfs_attr_leaf_name_local *l; + char *vp; + + l = xfs_attr3_leaf_name_local(leaf, i); + vp = (char *)&l->nameval[l->namelen]; + + return (int)bitize(vp - (char *)l); } -/*ARGSUSED*/ static int attr_leaf_name_local_value_offset( void *obj, int startoff, int idx) { - xfs_attr_leafblock_t *block; - xfs_attr_leaf_name_local_t *l; - char *vp; - int off; - xfs_attr_leaf_entry_t *e; - int i; - - ASSERT(bitoffs(startoff) == 0); - off = byteize(startoff); - block = obj; - if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) - return 0; - - for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { - e = &block->entries[i]; - if (be16_to_cpu(e->nameidx) == off) - break; - } - if (i >= be16_to_cpu(block->hdr.count)) - return 0; + return attr_leaf_entry_walk(obj, startoff, + __attr_leaf_name_local_value_offset); +} - l = xfs_attr_leaf_name_local(block, i); - vp = (char *)&l->nameval[l->namelen]; - return (int)bitize(vp - (char *)l); +static int +__attr_leaf_name_remote_count( + struct xfs_attr_leafblock *leaf, + struct xfs_attr_leaf_entry *e, + int i) +{ + return (e->flags & XFS_ATTR_LOCAL) == 0; } static int attr_leaf_name_remote_count( - void *obj, - int startoff) + void *obj, + int startoff) { - xfs_attr_leafblock_t *block; - xfs_attr_leaf_entry_t *e; - int i; - int off; + return attr_leaf_entry_walk(obj, startoff, + __attr_leaf_name_remote_count); +} - ASSERT(bitoffs(startoff) == 0); - off = byteize(startoff); - block = obj; - if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) +static int +__attr_leaf_name_remote_name_count( + struct xfs_attr_leafblock *leaf, + struct xfs_attr_leaf_entry *e, + int i) +{ + struct xfs_attr_leaf_name_remote *r; + + if (e->flags & XFS_ATTR_LOCAL) return 0; - for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { - e = &block->entries[i]; - if (be16_to_cpu(e->nameidx) == off) - return (e->flags & XFS_ATTR_LOCAL) == 0; - } - return 0; + + r = xfs_attr3_leaf_name_remote(leaf, i); + return r->namelen; } static int @@ -318,117 +358,125 @@ void *obj, int startoff) { - xfs_attr_leafblock_t *block; - xfs_attr_leaf_entry_t *e; - int i; - int off; - xfs_attr_leaf_name_remote_t *r; - - ASSERT(bitoffs(startoff) == 0); - off = byteize(startoff); - block = obj; - if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) - return 0; - for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { - e = &block->entries[i]; - if (be16_to_cpu(e->nameidx) == off) { - if (!(e->flags & XFS_ATTR_LOCAL)) { - r = xfs_attr_leaf_name_remote(block, i); - return r->namelen; - } else - return 0; - } - } - return 0; + return attr_leaf_entry_walk(obj, startoff, + __attr_leaf_name_remote_name_count); } -/*ARGSUSED*/ int attr_leaf_name_size( void *obj, int startoff, int idx) { - xfs_attr_leafblock_t *block; - xfs_attr_leaf_entry_t *e; - xfs_attr_leaf_name_local_t *l; - xfs_attr_leaf_name_remote_t *r; + struct xfs_attr_leafblock *leaf = obj; + struct xfs_attr_leaf_entry *e; + struct xfs_attr_leaf_name_local *l; + struct xfs_attr_leaf_name_remote *r; ASSERT(startoff == 0); - block = obj; - if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) + if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC && + be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR3_LEAF_MAGIC) return 0; - e = &block->entries[idx]; + e = &xfs_attr3_leaf_entryp(leaf)[idx]; if (e->flags & XFS_ATTR_LOCAL) { - l = xfs_attr_leaf_name_local(block, idx); + l = xfs_attr3_leaf_name_local(leaf, idx); return (int)bitize(xfs_attr_leaf_entsize_local(l->namelen, be16_to_cpu(l->valuelen))); } else { - r = xfs_attr_leaf_name_remote(block, idx); + r = xfs_attr3_leaf_name_remote(leaf, idx); return (int)bitize(xfs_attr_leaf_entsize_remote(r->namelen)); } } -/*ARGSUSED*/ static int attr_leaf_nvlist_count( void *obj, int startoff) { - xfs_attr_leafblock_t *block; + struct xfs_attr_leafblock *leaf = obj; ASSERT(startoff == 0); - block = obj; - if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) + if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; - return be16_to_cpu(block->hdr.count); + return be16_to_cpu(leaf->hdr.count); +} + +static int +attr3_leaf_nvlist_count( + void *obj, + int startoff) +{ + struct xfs_attr3_leafblock *leaf = obj; + + ASSERT(startoff == 0); + if (be16_to_cpu(leaf->hdr.info.hdr.magic) != XFS_ATTR3_LEAF_MAGIC) + return 0; + return be16_to_cpu(leaf->hdr.count); } -/*ARGSUSED*/ static int attr_leaf_nvlist_offset( void *obj, int startoff, int idx) { - xfs_attr_leafblock_t *block; - xfs_attr_leaf_entry_t *e; + struct xfs_attr_leafblock *leaf = obj; + struct xfs_attr_leaf_entry *e; ASSERT(startoff == 0); - block = obj; - e = &block->entries[idx]; + e = &xfs_attr3_leaf_entryp(leaf)[idx]; return bitize(be16_to_cpu(e->nameidx)); } -/*ARGSUSED*/ static int attr_node_btree_count( void *obj, int startoff) { - xfs_da_intnode_t *block; + struct xfs_da_intnode *node = obj; ASSERT(startoff == 0); /* this is a base structure */ - block = obj; - if (be16_to_cpu(block->hdr.info.magic) != XFS_DA_NODE_MAGIC) + if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC) + return 0; + return be16_to_cpu(node->hdr.__count); +} + +static int +attr3_node_btree_count( + void *obj, + int startoff) +{ + struct xfs_da3_intnode *node = obj; + + ASSERT(startoff == 0); + if (be16_to_cpu(node->hdr.info.hdr.magic) != XFS_DA3_NODE_MAGIC) return 0; - return be16_to_cpu(block->hdr.count); + return be16_to_cpu(node->hdr.__count); } -/*ARGSUSED*/ + static int attr_node_hdr_count( void *obj, int startoff) { - xfs_da_intnode_t *block; + struct xfs_da_intnode *node = obj; + + ASSERT(startoff == 0); + return be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC; +} + +static int +attr3_node_hdr_count( + void *obj, + int startoff) +{ + struct xfs_da3_intnode *node = obj; ASSERT(startoff == 0); - block = obj; - return be16_to_cpu(block->hdr.info.magic) == XFS_DA_NODE_MAGIC; + return be16_to_cpu(node->hdr.info.hdr.magic) == XFS_DA3_NODE_MAGIC; } -/*ARGSUSED*/ int attr_size( void *obj, @@ -437,3 +485,91 @@ { return bitize(mp->m_sb.sb_blocksize); } + +/* + * CRC enabled attribute block field definitions + */ +const field_t attr3_hfld[] = { + { "", FLDT_ATTR3, OI(0), C1, 0, TYP_NONE }, + { NULL } +}; + +#define L3OFF(f) bitize(offsetof(struct xfs_attr3_leafblock, f)) +#define N3OFF(f) bitize(offsetof(struct xfs_da3_intnode, f)) +const field_t attr3_flds[] = { + { "hdr", FLDT_ATTR3_LEAF_HDR, OI(L3OFF(hdr)), attr3_leaf_hdr_count, + FLD_COUNT, TYP_NONE }, + { "hdr", FLDT_DA3_NODE_HDR, OI(N3OFF(hdr)), attr3_node_hdr_count, + FLD_COUNT, TYP_NONE }, + { "entries", FLDT_ATTR_LEAF_ENTRY, OI(L3OFF(entries)), + attr3_leaf_entries_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, + { "btree", FLDT_ATTR_NODE_ENTRY, OI(N3OFF(__btree)), + attr3_node_btree_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, + { "nvlist", FLDT_ATTR_LEAF_NAME, attr_leaf_nvlist_offset, + attr3_leaf_nvlist_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE }, + { NULL } +}; + +#define LH3OFF(f) bitize(offsetof(struct xfs_attr3_leaf_hdr, f)) +const field_t attr3_leaf_hdr_flds[] = { + { "info", FLDT_DA3_BLKINFO, OI(LH3OFF(info)), C1, 0, TYP_NONE }, + { "count", FLDT_UINT16D, OI(LH3OFF(count)), C1, 0, TYP_NONE }, + { "usedbytes", FLDT_UINT16D, OI(LH3OFF(usedbytes)), C1, 0, TYP_NONE }, + { "firstused", FLDT_UINT16D, OI(LH3OFF(firstused)), C1, 0, TYP_NONE }, + { "holes", FLDT_UINT8D, OI(LH3OFF(holes)), C1, 0, TYP_NONE }, + { "pad1", FLDT_UINT8X, OI(LH3OFF(pad1)), C1, FLD_SKIPALL, TYP_NONE }, + { "freemap", FLDT_ATTR_LEAF_MAP, OI(LH3OFF(freemap)), + CI(XFS_ATTR_LEAF_MAPSIZE), FLD_ARRAY, TYP_NONE }, + { NULL } +}; + +/* + * Special read verifier for attribute buffers. Detect the magic number + * appropriately and set the correct verifier and call it. + */ +static void +xfs_attr3_db_read_verify( + struct xfs_buf *bp) +{ + __be32 magic32; + __be16 magic16; + + magic32 = *(__be32 *)bp->b_addr; + magic16 = ((struct xfs_da_blkinfo *)bp->b_addr)->magic; + + switch (magic16) { + case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC): + bp->b_ops = &xfs_attr3_leaf_buf_ops; + goto verify; + case cpu_to_be16(XFS_DA3_NODE_MAGIC): + bp->b_ops = &xfs_da3_node_buf_ops; + goto verify; + default: + break; + } + + switch (magic32) { + case cpu_to_be32(XFS_ATTR3_RMT_MAGIC): + bp->b_ops = &xfs_attr3_rmt_buf_ops; + break; + default: + dbprintf(_("Unknown attribute buffer type!\n")); + xfs_buf_ioerror(bp, EFSCORRUPTED); + return; + } +verify: + bp->b_ops->verify_read(bp); +} + +static void +xfs_attr3_db_write_verify( + struct xfs_buf *bp) +{ + dbprintf(_("Writing unknown attribute buffer type!\n")); + xfs_buf_ioerror(bp, EFSCORRUPTED); +} + +const struct xfs_buf_ops xfs_attr3_db_buf_ops = { + .verify_read = xfs_attr3_db_read_verify, + .verify_write = xfs_attr3_db_write_verify, +}; diff -Nru xfsprogs-3.1.9ubuntu2/db/attr.h xfsprogs-3.2.1ubuntu1/db/attr.h --- xfsprogs-3.1.9ubuntu2/db/attr.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/attr.h 2014-05-02 00:09:15.000000000 +0000 @@ -26,5 +26,12 @@ extern const field_t attr_node_entry_flds[]; extern const field_t attr_node_hdr_flds[]; +extern const field_t attr3_flds[]; +extern const field_t attr3_hfld[]; +extern const field_t attr3_leaf_hdr_flds[]; +extern const field_t attr3_node_hdr_flds[]; + extern int attr_leaf_name_size(void *obj, int startoff, int idx); extern int attr_size(void *obj, int startoff, int idx); + +extern const struct xfs_buf_ops xfs_attr3_db_buf_ops; diff -Nru xfsprogs-3.1.9ubuntu2/db/attrset.c xfsprogs-3.2.1ubuntu1/db/attrset.c --- xfsprogs-3.1.9ubuntu2/db/attrset.c 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/attrset.c 2014-06-19 22:42:17.000000000 +0000 @@ -146,7 +146,7 @@ dbprintf(_("cannot allocate buffer (%d)\n"), valuelen); goto out; } - memset(value, 0xfeedface, valuelen); + memset(value, 'v', valuelen); } else { value = NULL; } @@ -170,7 +170,7 @@ out: mp->m_flags &= ~LIBXFS_MOUNT_COMPAT_ATTR; if (ip) - libxfs_iput(ip, 0); + IRELE(ip); if (value) free(value); return 0; @@ -244,6 +244,6 @@ out: mp->m_flags &= ~LIBXFS_MOUNT_COMPAT_ATTR; if (ip) - libxfs_iput(ip, 0); + IRELE(ip); return 0; } diff -Nru xfsprogs-3.1.9ubuntu2/db/bit.c xfsprogs-3.2.1ubuntu1/db/bit.c --- xfsprogs-3.1.9ubuntu2/db/bit.c 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/bit.c 2014-05-02 00:09:15.000000000 +0000 @@ -128,57 +128,41 @@ return rval; } +/* + * The input data can be 8, 16, 32, and 64 sized numeric values + * aligned on a byte boundry, or odd sized numbers stored on odd + * aligned offset (for example the bmbt fields). + * + * The input data sent to this routine has been converted to big endian + * and has been adjusted in the array so that the first input bit is to + * be written in the first bit in the output. + * + * If the field length and the output buffer are byte aligned, then use + * memcpy from the input to the output, but if either entries are not byte + * aligned, then loop over the entire bit range reading the input value + * and set/clear the matching bit in the output. + * + * example when ibuf is not multiple of a byte in length: + * + * ibuf: | BBBBBBBB | bbbxxxxx | + * \\\\\\\\--\\\\ + * obuf+bitoff: | xBBBBBBB | Bbbbxxxx | + * + */ void setbitval( - void *obuf, /* buffer to write into */ - int bitoff, /* bit offset of where to write */ - int nbits, /* number of bits to write */ - void *ibuf) /* source bits */ + void *obuf, /* start of buffer to write into */ + int bitoff, /* bit offset into the output buffer */ + int nbits, /* number of bits to write */ + void *ibuf) /* source bits */ { - char *in = (char *)ibuf; - char *out = (char *)obuf; - - int bit; - -#if BYTE_ORDER == LITTLE_ENDIAN - int big = 0; -#else - int big = 1; -#endif - - /* only need to swap LE integers */ - if (big || (nbits!=16 && nbits!=32 && nbits!=64) ) { - /* We don't have type info, so we can only assume - * that 2,4 & 8 byte values are integers. sigh. - */ - - /* byte aligned ? */ - if (bitoff%NBBY) { - /* no - bit copy */ - for (bit=0; bitb[d++] = - XFS_FSB_TO_DADDR(mp, dfsbno) + k; - } + for (i = 0; i < nex; i++) { + bbmap->b[i].bm_bn = XFS_FSB_TO_DADDR(mp, bmp[i].startblock); + bbmap->b[i].bm_len = XFS_FSB_TO_BB(mp, bmp[i].blockcount); } + bbmap->nmaps = nex; } static xfs_fsblock_t diff -Nru xfsprogs-3.1.9ubuntu2/db/bmroot.c xfsprogs-3.2.1ubuntu1/db/bmroot.c --- xfsprogs-3.1.9ubuntu2/db/bmroot.c 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/bmroot.c 2013-10-10 21:07:16.000000000 +0000 @@ -91,13 +91,13 @@ int idx) { xfs_bmdr_block_t *block; - /* REFERENCED */ - xfs_dinode_t *dip; +#ifdef DEBUG + xfs_dinode_t *dip = obj; +#endif xfs_bmdr_key_t *kp; ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); - dip = obj; block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); ASSERT(XFS_DFORK_Q(dip) && (char *)block == XFS_DFORK_APTR(dip)); ASSERT(be16_to_cpu(block->bb_level) > 0); diff -Nru xfsprogs-3.1.9ubuntu2/db/btblock.c xfsprogs-3.2.1ubuntu1/db/btblock.c --- xfsprogs-3.1.9ubuntu2/db/btblock.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/btblock.c 2014-06-19 22:42:17.000000000 +0000 @@ -26,40 +26,78 @@ #include "bit.h" #include "init.h" - /* * Definition of the possible btree block layouts. */ struct xfs_db_btree { + uint32_t magic; size_t block_len; size_t key_len; size_t rec_len; size_t ptr_len; } btrees[] = { - [/*0x424d415*/0] = { /* BMAP */ + { XFS_BMAP_MAGIC, XFS_BTREE_LBLOCK_LEN, sizeof(xfs_bmbt_key_t), sizeof(xfs_bmbt_rec_t), sizeof(__be64), }, - [/*0x4142544*/2] = { /* ABTB */ + { XFS_ABTB_MAGIC, XFS_BTREE_SBLOCK_LEN, sizeof(xfs_alloc_key_t), sizeof(xfs_alloc_rec_t), sizeof(__be32), }, - [/*0x4142544*/3] = { /* ABTC */ + { XFS_ABTC_MAGIC, XFS_BTREE_SBLOCK_LEN, sizeof(xfs_alloc_key_t), sizeof(xfs_alloc_rec_t), sizeof(__be32), }, - [/*0x4941425*/4] = { /* IABT */ + { XFS_IBT_MAGIC, XFS_BTREE_SBLOCK_LEN, sizeof(xfs_inobt_key_t), sizeof(xfs_inobt_rec_t), sizeof(__be32), }, + { XFS_FIBT_MAGIC, + XFS_BTREE_SBLOCK_LEN, + sizeof(xfs_inobt_key_t), + sizeof(xfs_inobt_rec_t), + sizeof(__be32), + }, + { XFS_BMAP_CRC_MAGIC, + XFS_BTREE_LBLOCK_CRC_LEN, + sizeof(xfs_bmbt_key_t), + sizeof(xfs_bmbt_rec_t), + sizeof(__be64), + }, + { XFS_ABTB_CRC_MAGIC, + XFS_BTREE_SBLOCK_CRC_LEN, + sizeof(xfs_alloc_key_t), + sizeof(xfs_alloc_rec_t), + sizeof(__be32), + }, + { XFS_ABTC_CRC_MAGIC, + XFS_BTREE_SBLOCK_CRC_LEN, + sizeof(xfs_alloc_key_t), + sizeof(xfs_alloc_rec_t), + sizeof(__be32), + }, + { XFS_IBT_CRC_MAGIC, + XFS_BTREE_SBLOCK_CRC_LEN, + sizeof(xfs_inobt_key_t), + sizeof(xfs_inobt_rec_t), + sizeof(__be32), + }, + { XFS_FIBT_CRC_MAGIC, + XFS_BTREE_SBLOCK_CRC_LEN, + sizeof(xfs_inobt_key_t), + sizeof(xfs_inobt_rec_t), + sizeof(__be32), + }, + { 0, + }, }; /* @@ -68,8 +106,20 @@ * We use the least significant bit of the magic number as index into * the array of block defintions. */ -#define block_to_bt(bb) \ - (&btrees[be32_to_cpu((bb)->bb_magic) & 0xf]) +static struct xfs_db_btree * +block_to_bt( + struct xfs_btree_block *bb) +{ + struct xfs_db_btree *btp = &btrees[0]; + + do { + if (be32_to_cpu((bb)->bb_magic) == btp->magic) + return btp; + btp++; + } while (btp->magic != 0); + + return NULL; +} /* calculate max records. Only for non-leaves. */ static int @@ -208,6 +258,15 @@ { NULL } }; +const field_t bmapbta_crc_hfld[] = { + { "", FLDT_BMAPBTA_CRC, OI(0), C1, 0, TYP_NONE }, + { NULL } +}; +const field_t bmapbtd_crc_hfld[] = { + { "", FLDT_BMAPBTD_CRC, OI(0), C1, 0, TYP_NONE }, + { NULL } +}; + #define OFF(f) bitize(offsetof(struct xfs_btree_block, bb_ ## f)) const field_t bmapbta_flds[] = { { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, @@ -237,6 +296,45 @@ FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BMAPBTD }, { NULL } }; +/* crc enabled versions */ +const field_t bmapbta_crc_flds[] = { + { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, + { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE }, + { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE }, + { "leftsib", FLDT_DFSBNO, OI(OFF(u.l.bb_leftsib)), C1, 0, TYP_BMAPBTA }, + { "rightsib", FLDT_DFSBNO, OI(OFF(u.l.bb_rightsib)), C1, 0, TYP_BMAPBTA }, + { "bno", FLDT_DFSBNO, OI(OFF(u.l.bb_blkno)), C1, 0, TYP_BMAPBTD }, + { "lsn", FLDT_UINT64X, OI(OFF(u.l.bb_lsn)), C1, 0, TYP_NONE }, + { "uuid", FLDT_UUID, OI(OFF(u.l.bb_uuid)), C1, 0, TYP_NONE }, + { "owner", FLDT_INO, OI(OFF(u.l.bb_owner)), C1, 0, TYP_NONE }, + { "crc", FLDT_CRC, OI(OFF(u.l.bb_crc)), C1, 0, TYP_NONE }, + { "recs", FLDT_BMAPBTAREC, btblock_rec_offset, btblock_rec_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "keys", FLDT_BMAPBTAKEY, btblock_key_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "ptrs", FLDT_BMAPBTAPTR, btblock_ptr_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BMAPBTA }, + { NULL } +}; +const field_t bmapbtd_crc_flds[] = { + { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, + { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE }, + { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE }, + { "leftsib", FLDT_DFSBNO, OI(OFF(u.l.bb_leftsib)), C1, 0, TYP_BMAPBTD }, + { "rightsib", FLDT_DFSBNO, OI(OFF(u.l.bb_rightsib)), C1, 0, TYP_BMAPBTD }, + { "bno", FLDT_DFSBNO, OI(OFF(u.l.bb_blkno)), C1, 0, TYP_BMAPBTD }, + { "lsn", FLDT_UINT64X, OI(OFF(u.l.bb_lsn)), C1, 0, TYP_NONE }, + { "uuid", FLDT_UUID, OI(OFF(u.l.bb_uuid)), C1, 0, TYP_NONE }, + { "owner", FLDT_INO, OI(OFF(u.l.bb_owner)), C1, 0, TYP_NONE }, + { "crc", FLDT_CRC, OI(OFF(u.l.bb_crc)), C1, 0, TYP_NONE }, + { "recs", FLDT_BMAPBTDREC, btblock_rec_offset, btblock_rec_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "keys", FLDT_BMAPBTDKEY, btblock_key_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "ptrs", FLDT_BMAPBTDPTR, btblock_ptr_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BMAPBTD }, + { NULL } +}; #undef OFF #define KOFF(f) bitize(offsetof(xfs_bmbt_key_t, br_ ## f)) @@ -289,6 +387,11 @@ { NULL } }; +const field_t inobt_crc_hfld[] = { + { "", FLDT_INOBT_CRC, OI(0), C1, 0, TYP_NONE }, + { NULL } +}; + #define OFF(f) bitize(offsetof(struct xfs_btree_block, bb_ ## f)) const field_t inobt_flds[] = { { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, @@ -304,6 +407,25 @@ FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_INOBT }, { NULL } }; +const field_t inobt_crc_flds[] = { + { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, + { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE }, + { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE }, + { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_INOBT }, + { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_INOBT }, + { "bno", FLDT_DFSBNO, OI(OFF(u.s.bb_blkno)), C1, 0, TYP_INOBT }, + { "lsn", FLDT_UINT64X, OI(OFF(u.s.bb_lsn)), C1, 0, TYP_NONE }, + { "uuid", FLDT_UUID, OI(OFF(u.s.bb_uuid)), C1, 0, TYP_NONE }, + { "owner", FLDT_AGNUMBER, OI(OFF(u.s.bb_owner)), C1, 0, TYP_NONE }, + { "crc", FLDT_CRC, OI(OFF(u.s.bb_crc)), C1, 0, TYP_NONE }, + { "recs", FLDT_INOBTREC, btblock_rec_offset, btblock_rec_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "keys", FLDT_INOBTKEY, btblock_key_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "ptrs", FLDT_INOBTPTR, btblock_ptr_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_INOBT }, + { NULL } +}; #undef OFF #define KOFF(f) bitize(offsetof(xfs_inobt_key_t, ir_ ## f)) @@ -331,6 +453,11 @@ { NULL } }; +const field_t bnobt_crc_hfld[] = { + { "", FLDT_BNOBT_CRC, OI(0), C1, 0, TYP_NONE }, + { NULL } +}; + #define OFF(f) bitize(offsetof(struct xfs_btree_block, bb_ ## f)) const field_t bnobt_flds[] = { { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, @@ -346,6 +473,25 @@ FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BNOBT }, { NULL } }; +const field_t bnobt_crc_flds[] = { + { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, + { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE }, + { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE }, + { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_BNOBT }, + { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_BNOBT }, + { "bno", FLDT_DFSBNO, OI(OFF(u.s.bb_blkno)), C1, 0, TYP_BNOBT }, + { "lsn", FLDT_UINT64X, OI(OFF(u.s.bb_lsn)), C1, 0, TYP_NONE }, + { "uuid", FLDT_UUID, OI(OFF(u.s.bb_uuid)), C1, 0, TYP_NONE }, + { "owner", FLDT_AGNUMBER, OI(OFF(u.s.bb_owner)), C1, 0, TYP_NONE }, + { "crc", FLDT_CRC, OI(OFF(u.s.bb_crc)), C1, 0, TYP_NONE }, + { "recs", FLDT_BNOBTREC, btblock_rec_offset, btblock_rec_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "keys", FLDT_BNOBTKEY, btblock_key_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "ptrs", FLDT_BNOBTPTR, btblock_ptr_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BNOBT }, + { NULL } +}; #undef OFF #define KOFF(f) bitize(offsetof(xfs_alloc_key_t, ar_ ## f)) @@ -369,6 +515,11 @@ { NULL } }; +const field_t cntbt_crc_hfld[] = { + { "", FLDT_CNTBT_CRC, OI(0), C1, 0, TYP_NONE }, + { NULL } +}; + #define OFF(f) bitize(offsetof(struct xfs_btree_block, bb_ ## f)) const field_t cntbt_flds[] = { { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, @@ -379,6 +530,25 @@ { "recs", FLDT_CNTBTREC, btblock_rec_offset, btblock_rec_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { "keys", FLDT_CNTBTKEY, btblock_key_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "ptrs", FLDT_CNTBTPTR, btblock_ptr_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_CNTBT }, + { NULL } +}; +const field_t cntbt_crc_flds[] = { + { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, + { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE }, + { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE }, + { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_CNTBT }, + { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_CNTBT }, + { "bno", FLDT_DFSBNO, OI(OFF(u.s.bb_blkno)), C1, 0, TYP_CNTBT }, + { "lsn", FLDT_UINT64X, OI(OFF(u.s.bb_lsn)), C1, 0, TYP_NONE }, + { "uuid", FLDT_UUID, OI(OFF(u.s.bb_uuid)), C1, 0, TYP_NONE }, + { "owner", FLDT_AGNUMBER, OI(OFF(u.s.bb_owner)), C1, 0, TYP_NONE }, + { "crc", FLDT_CRC, OI(OFF(u.s.bb_crc)), C1, 0, TYP_NONE }, + { "recs", FLDT_CNTBTREC, btblock_rec_offset, btblock_rec_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "keys", FLDT_CNTBTKEY, btblock_key_offset, btblock_key_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { "ptrs", FLDT_CNTBTPTR, btblock_ptr_offset, btblock_key_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_CNTBT }, diff -Nru xfsprogs-3.1.9ubuntu2/db/btblock.h xfsprogs-3.2.1ubuntu1/db/btblock.h --- xfsprogs-3.1.9ubuntu2/db/btblock.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/btblock.h 2013-10-10 21:07:16.000000000 +0000 @@ -18,26 +18,36 @@ extern const struct field bmapbta_flds[]; extern const struct field bmapbta_hfld[]; +extern const struct field bmapbta_crc_flds[]; +extern const struct field bmapbta_crc_hfld[]; extern const struct field bmapbta_key_flds[]; extern const struct field bmapbta_rec_flds[]; extern const struct field bmapbtd_flds[]; extern const struct field bmapbtd_hfld[]; +extern const struct field bmapbtd_crc_flds[]; +extern const struct field bmapbtd_crc_hfld[]; extern const struct field bmapbtd_key_flds[]; extern const struct field bmapbtd_rec_flds[]; extern const struct field inobt_flds[]; extern const struct field inobt_hfld[]; +extern const struct field inobt_crc_flds[]; +extern const struct field inobt_crc_hfld[]; extern const struct field inobt_key_flds[]; extern const struct field inobt_rec_flds[]; extern const struct field bnobt_flds[]; extern const struct field bnobt_hfld[]; +extern const struct field bnobt_crc_flds[]; +extern const struct field bnobt_crc_hfld[]; extern const struct field bnobt_key_flds[]; extern const struct field bnobt_rec_flds[]; extern const struct field cntbt_flds[]; extern const struct field cntbt_hfld[]; +extern const struct field cntbt_crc_flds[]; +extern const struct field cntbt_crc_hfld[]; extern const struct field cntbt_key_flds[]; extern const struct field cntbt_rec_flds[]; diff -Nru xfsprogs-3.1.9ubuntu2/db/check.c xfsprogs-3.2.1ubuntu1/db/check.c --- xfsprogs-3.1.9ubuntu2/db/check.c 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/check.c 2014-05-02 00:09:15.000000000 +0000 @@ -31,6 +31,7 @@ #include "output.h" #include "init.h" #include "malloc.h" +#include "dir2.h" typedef enum { IS_USER_QUOTA, IS_PROJECT_QUOTA, IS_GROUP_QUOTA, @@ -277,14 +278,11 @@ inodata_t *id, int v, xfs_dablk_t dabno, freetab_t **freetabp); -static xfs_dir2_data_free_t - *process_data_dir_v2_freefind(xfs_dir2_data_t *data, - xfs_dir2_data_unused_t *dup); +static xfs_dir2_data_free_t *process_data_dir_v2_freefind( + struct xfs_dir2_data_hdr *data, + struct xfs_dir2_data_unused *dup); static void process_dir(xfs_dinode_t *dip, blkmap_t *blkmap, inodata_t *id); -static int process_dir_v1(xfs_dinode_t *dip, blkmap_t *blkmap, - int *dot, int *dotdot, inodata_t *id, - xfs_ino_t *parent); static int process_dir_v2(xfs_dinode_t *dip, blkmap_t *blkmap, int *dot, int *dotdot, inodata_t *id, xfs_ino_t *parent); @@ -298,10 +296,6 @@ dbm_t type, xfs_drfsbno_t *totd, xfs_drfsbno_t *toti, xfs_extnum_t *nex, blkmap_t **blkmapp, int whichfork); -static xfs_ino_t process_leaf_dir_v1(blkmap_t *blkmap, int *dot, - int *dotdot, inodata_t *id); -static xfs_ino_t process_leaf_dir_v1_int(int *dot, int *dotdot, - inodata_t *id); static xfs_ino_t process_leaf_node_dir_v2(blkmap_t *blkmap, int *dot, int *dotdot, inodata_t *id, xfs_fsize_t dirsize); @@ -311,16 +305,12 @@ static void process_leaf_node_dir_v2_int(inodata_t *id, int v, xfs_dablk_t dbno, freetab_t *freetab); -static xfs_ino_t process_node_dir_v1(blkmap_t *blkmap, int *dot, - int *dotdot, inodata_t *id); static void process_quota(qtype_t qtype, inodata_t *id, blkmap_t *blkmap); static void process_rtbitmap(blkmap_t *blkmap); static void process_rtsummary(blkmap_t *blkmap); static xfs_ino_t process_sf_dir_v2(xfs_dinode_t *dip, int *dot, int *dotdot, inodata_t *id); -static xfs_ino_t process_shortform_dir_v1(xfs_dinode_t *dip, int *dot, - int *dotdot, inodata_t *id); static void quota_add(xfs_dqid_t *p, xfs_dqid_t *g, xfs_dqid_t *u, int dq, xfs_qcnt_t bc, xfs_qcnt_t ic, xfs_qcnt_t rc); @@ -798,6 +788,20 @@ dbprintf(_("already have block usage information\n")); return 0; } + + /* + * XXX: check does not support CRC enabled filesystems. Return + * immediately, silently, with success but without doing anything here + * initially so that xfstests can run without modification on metadata + * enabled filesystems. + * + * XXX: ultimately we need to dump an error message here that xfstests + * filters out, or we need to actually do the work to make check support + * crc enabled filesystems. + */ + if (xfs_sb_version_hascrc(&mp->m_sb)) + return 0; + if (!init(argc, argv)) { if (serious_error) exitcode = 3; @@ -1132,7 +1136,7 @@ } if (blocks == 0) { dbprintf(_("blocktrash: no matching blocks\n")); - return 0; + goto out; } if (!sopt) dbprintf(_("blocktrash: seed %u\n"), seed); @@ -1157,6 +1161,7 @@ } } } +out: xfree(lentab); return 0; } @@ -1181,7 +1186,6 @@ return 0; } optind = 0; - count = 1; shownames = 0; fsb = XFS_DADDR_TO_FSB(mp, iocur_top->off >> BBSHIFT); agno = XFS_FSB_TO_AGNO(mp, fsb); @@ -1831,7 +1835,8 @@ if (mp->m_sb.sb_inoalignmt) sbversion |= XFS_SB_VERSION_ALIGNBIT; if ((mp->m_sb.sb_uquotino && mp->m_sb.sb_uquotino != NULLFSINO) || - (mp->m_sb.sb_gquotino && mp->m_sb.sb_gquotino != NULLFSINO)) + (mp->m_sb.sb_gquotino && mp->m_sb.sb_gquotino != NULLFSINO) || + (mp->m_sb.sb_pquotino && mp->m_sb.sb_pquotino != NULLFSINO)) sbversion |= XFS_SB_VERSION_QUOTABIT; quota_init(); return 1; @@ -1902,6 +1907,7 @@ break; default: dbprintf(_("bad option -%c for ncheck command\n"), c); + xfree(ilist); return 0; } } @@ -1983,7 +1989,7 @@ push_cur(); if (nex > 1) make_bbmap(&bbmap, nex, bmp); - set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bmp->startblock), + set_cur(&typtab[TYP_DIR2], XFS_FSB_TO_DADDR(mp, bmp->startblock), mp->m_dirblkfsbs * blkbb, DB_RING_IGN, nex > 1 ? &bbmap : NULL); for (x = 0; !v && x < nex; x++) { for (b = bmp[x].startblock; @@ -2184,11 +2190,11 @@ xfs_dir2_dataptr_t addr; xfs_dir2_data_free_t *bf; int bf_err; - xfs_dir2_block_t *block; + struct xfs_dir2_data_hdr *block; xfs_dir2_block_tail_t *btp = NULL; inodata_t *cid; int count; - xfs_dir2_data_t *data; + struct xfs_dir2_data_hdr *data; xfs_dir2_db_t db; xfs_dir2_data_entry_t *dep; xfs_dir2_data_free_t *dfp; @@ -2210,19 +2216,19 @@ data = iocur_top->data; block = iocur_top->data; - if (be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC && - be32_to_cpu(data->hdr.magic) != XFS_DIR2_DATA_MAGIC) { + if (be32_to_cpu(block->magic) != XFS_DIR2_BLOCK_MAGIC && + be32_to_cpu(data->magic) != XFS_DIR2_DATA_MAGIC) { if (!sflag || v) dbprintf(_("bad directory data magic # %#x for dir ino " "%lld block %d\n"), - be32_to_cpu(data->hdr.magic), id->ino, dabno); + be32_to_cpu(data->magic), id->ino, dabno); error++; return NULLFSINO; } db = xfs_dir2_da_to_db(mp, dabno); - bf = data->hdr.bestfree; - ptr = (char *)data->u; - if (be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { + bf = xfs_dir3_data_bestfree_p(data); + ptr = (char *)xfs_dir3_data_unused_p(data); + if (be32_to_cpu(block->magic) == XFS_DIR2_BLOCK_MAGIC) { btp = xfs_dir2_block_tail_p(mp, block); lep = xfs_dir2_block_leaf_p(btp); endptr = (char *)lep; @@ -2305,7 +2311,7 @@ (int)((char *)dep - (char *)data)); error++; } - tagp = xfs_dir2_data_entry_tag_p(dep); + tagp = xfs_dir3_data_entry_tag_p(mp, dep); if ((char *)tagp >= endptr) { if (!sflag || v) dbprintf(_("dir %lld block %d bad entry at %d\n"), @@ -2320,7 +2326,7 @@ xname.name = dep->name; xname.len = dep->namelen; dir_hash_add(mp->m_dirnameops->hashname(&xname), addr); - ptr += xfs_dir2_data_entsize(dep->namelen); + ptr += xfs_dir3_data_entsize(mp, dep->namelen); count++; lastfree = 0; lino = be64_to_cpu(dep->inumber); @@ -2368,7 +2374,7 @@ (*dot)++; } } - if (be32_to_cpu(data->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { + if (be32_to_cpu(data->magic) == XFS_DIR2_BLOCK_MAGIC) { endptr = (char *)data + mp->m_dirblksize; for (i = stale = 0; lep && i < be32_to_cpu(btp->count); i++) { if ((char *)&lep[i] >= endptr) { @@ -2400,9 +2406,8 @@ id->ino, dabno); error++; } - if (be32_to_cpu(data->hdr.magic) == XFS_DIR2_BLOCK_MAGIC && - count != be32_to_cpu(btp->count) - - be32_to_cpu(btp->stale)) { + if (be32_to_cpu(data->magic) == XFS_DIR2_BLOCK_MAGIC && + count != be32_to_cpu(btp->count) - be32_to_cpu(btp->stale)) { if (!sflag || v) dbprintf(_("dir %lld block %d bad block tail count %d " "(stale %d)\n"), @@ -2410,7 +2415,7 @@ be32_to_cpu(btp->stale)); error++; } - if (be32_to_cpu(data->hdr.magic) == XFS_DIR2_BLOCK_MAGIC && + if (be32_to_cpu(data->magic) == XFS_DIR2_BLOCK_MAGIC && stale != be32_to_cpu(btp->stale)) { if (!sflag || v) dbprintf(_("dir %lld block %d bad stale tail count %d\n"), @@ -2435,18 +2440,19 @@ static xfs_dir2_data_free_t * process_data_dir_v2_freefind( - xfs_dir2_data_t *data, + struct xfs_dir2_data_hdr *data, xfs_dir2_data_unused_t *dup) { - xfs_dir2_data_free_t *dfp; + struct xfs_dir2_data_free *bf; + struct xfs_dir2_data_free *dfp; xfs_dir2_data_aoff_t off; off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)data); - if (be16_to_cpu(dup->length) < be16_to_cpu(data->hdr. - bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length)) + bf = xfs_dir3_data_bestfree_p(data); + if (be16_to_cpu(dup->length) < + be16_to_cpu(bf[XFS_DIR2_DATA_FD_COUNT - 1].length)) return NULL; - for (dfp = &data->hdr.bestfree[0]; dfp < &data->hdr. - bestfree[XFS_DIR2_DATA_FD_COUNT]; dfp++) { + for (dfp = bf; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) { if (be16_to_cpu(dfp->offset) == 0) return NULL; if (be16_to_cpu(dfp->offset) == off) @@ -2467,14 +2473,9 @@ xfs_ino_t parent; dot = dotdot = 0; - if (xfs_sb_version_hasdirv2(&mp->m_sb)) { - if (process_dir_v2(dip, blkmap, &dot, &dotdot, id, &parent)) - return; - } else - { - if (process_dir_v1(dip, blkmap, &dot, &dotdot, id, &parent)) - return; - } + if (process_dir_v2(dip, blkmap, &dot, &dotdot, id, &parent)) + return; + bno = XFS_INO_TO_FSB(mp, id->ino); if (dot == 0) { if (!sflag || id->ilist || CHECK_BLIST(bno)) @@ -2500,38 +2501,6 @@ } static int -process_dir_v1( - xfs_dinode_t *dip, - blkmap_t *blkmap, - int *dot, - int *dotdot, - inodata_t *id, - xfs_ino_t *parent) -{ - xfs_fsize_t size = be64_to_cpu(dip->di_size); - - if (size <= XFS_DFORK_DSIZE(dip, mp) && - dip->di_format == XFS_DINODE_FMT_LOCAL) - *parent = process_shortform_dir_v1(dip, dot, dotdot, id); - else if (size == XFS_LBSIZE(mp) && - (dip->di_format == XFS_DINODE_FMT_EXTENTS || - dip->di_format == XFS_DINODE_FMT_BTREE)) - *parent = process_leaf_dir_v1(blkmap, dot, dotdot, id); - else if (size >= XFS_LBSIZE(mp) && - (dip->di_format == XFS_DINODE_FMT_EXTENTS || - dip->di_format == XFS_DINODE_FMT_BTREE)) - *parent = process_node_dir_v1(blkmap, dot, dotdot, id); - else { - dbprintf(_("bad size (%lld) or format (%d) for directory inode " - "%lld\n"), - size, dip->di_format, id->ino); - error++; - return 1; - } - return 0; -} - -static int process_dir_v2( xfs_dinode_t *dip, blkmap_t *blkmap, @@ -2713,7 +2682,8 @@ error++; return; } - if ((unsigned int)XFS_DFORK_ASIZE(dip, mp) >= XFS_LITINO(mp)) { + if ((unsigned int)XFS_DFORK_ASIZE(dip, mp) >= + XFS_LITINO(mp, idic.di_version)) { if (v) dbprintf(_("bad fork offset %d for inode %lld\n"), idic.di_forkoff, id->ino); @@ -2764,7 +2734,8 @@ addlink_inode(id); } else if (id->ino == mp->m_sb.sb_uquotino || - id->ino == mp->m_sb.sb_gquotino) { + id->ino == mp->m_sb.sb_gquotino || + id->ino == mp->m_sb.sb_pquotino) { type = DBM_QUOTA; blkmap = blkmap_alloc(idic.di_nextents); addlink_inode(id); @@ -2840,7 +2811,7 @@ break; } if (ic) { - dqprid = xfs_get_projid(idic); /* dquot ID is u32 */ + dqprid = xfs_get_projid(&idic); /* dquot ID is u32 */ quota_add(&dqprid, &idic.di_gid, &idic.di_uid, 0, bc, ic, rc); } @@ -2883,11 +2854,11 @@ process_quota(IS_USER_QUOTA, id, blkmap); else if (id->ino == mp->m_sb.sb_gquotino && (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) && - (mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD)) + (mp->m_sb.sb_qflags & XFS_GQUOTA_CHKD)) process_quota(IS_GROUP_QUOTA, id, blkmap); - else if (id->ino == mp->m_sb.sb_gquotino && + else if (id->ino == mp->m_sb.sb_pquotino && (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) && - (mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD)) + (mp->m_sb.sb_qflags & XFS_PQUOTA_CHKD)) process_quota(IS_PROJECT_QUOTA, id, blkmap); } if (blkmap) @@ -2931,121 +2902,6 @@ } static xfs_ino_t -process_leaf_dir_v1( - blkmap_t *blkmap, - int *dot, - int *dotdot, - inodata_t *id) -{ - xfs_fsblock_t bno; - xfs_ino_t parent; - - bno = blkmap_get(blkmap, 0); - if (bno == NULLFSBLOCK) { - if (!sflag || id->ilist) - dbprintf(_("block 0 for directory inode %lld is " - "missing\n"), - id->ino); - error++; - return 0; - } - push_cur(); - set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bno), blkbb, DB_RING_IGN, - NULL); - if (iocur_top->data == NULL) { - if (!sflag || id->ilist || CHECK_BLIST(bno)) - dbprintf(_("can't read block 0 for directory inode " - "%lld\n"), - id->ino); - error++; - pop_cur(); - return 0; - } - parent = process_leaf_dir_v1_int(dot, dotdot, id); - pop_cur(); - return parent; -} - -static xfs_ino_t -process_leaf_dir_v1_int( - int *dot, - int *dotdot, - inodata_t *id) -{ - xfs_fsblock_t bno; - inodata_t *cid; - xfs_dir_leaf_entry_t *entry; - int i; - xfs_dir_leafblock_t *leaf; - xfs_ino_t lino; - xfs_dir_leaf_name_t *namest; - xfs_ino_t parent = 0; - int v; - - bno = XFS_DADDR_TO_FSB(mp, iocur_top->bb); - v = verbose || id->ilist || CHECK_BLIST(bno); - leaf = iocur_top->data; - if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) { - if (!sflag || id->ilist || CHECK_BLIST(bno)) - dbprintf(_("bad directory leaf magic # %#x for dir ino " - "%lld\n"), - be16_to_cpu(leaf->hdr.info.magic), id->ino); - error++; - return NULLFSINO; - } - entry = &leaf->entries[0]; - for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { - namest = xfs_dir_leaf_namestruct(leaf, - be16_to_cpu(entry->nameidx)); - lino = XFS_GET_DIR_INO8(namest->inumber); - cid = find_inode(lino, 1); - if (v) - dbprintf(_("dir %lld entry %*.*s %lld\n"), id->ino, - entry->namelen, entry->namelen, namest->name, - lino); - if (cid) - addlink_inode(cid); - else { - if (!sflag) - dbprintf(_("dir %lld entry %*.*s bad inode " - "number %lld\n"), - id->ino, entry->namelen, entry->namelen, - namest->name, lino); - error++; - } - if (entry->namelen == 2 && namest->name[0] == '.' && - namest->name[1] == '.') { - if (parent) { - if (!sflag || id->ilist || CHECK_BLIST(bno)) - dbprintf(_("multiple .. entries in dir " - "%lld (%lld, %lld)\n"), - id->ino, parent, lino); - error++; - } else - parent = cid ? lino : NULLFSINO; - (*dotdot)++; - } else if (entry->namelen != 1 || namest->name[0] != '.') { - if (cid != NULL) { - if (!cid->parent) - cid->parent = id; - addname_inode(cid, (char *)namest->name, - entry->namelen); - } - } else { - if (lino != id->ino) { - if (!sflag) - dbprintf(_("dir %lld entry . inode " - "number mismatch (%lld)\n"), - id->ino, lino); - error++; - } - (*dot)++; - } - } - return parent; -} - -static xfs_ino_t process_leaf_node_dir_v2( blkmap_t *blkmap, int *dot, @@ -3092,7 +2948,7 @@ push_cur(); if (nex > 1) make_bbmap(&bbmap, nex, bmp); - set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bmp->startblock), + set_cur(&typtab[TYP_DIR2], XFS_FSB_TO_DADDR(mp, bmp->startblock), mp->m_dirblkfsbs * blkbb, DB_RING_IGN, nex > 1 ? &bbmap : NULL); free(bmp); @@ -3166,7 +3022,7 @@ error++; return; } - maxent = XFS_DIR2_MAX_FREE_BESTS(mp); + maxent = xfs_dir3_free_max_bests(mp); if (be32_to_cpu(free->hdr.firstdb) != xfs_dir2_da_to_db(mp, dabno - mp->m_dirfreeblk) * maxent) { if (!sflag || v) @@ -3233,6 +3089,7 @@ xfs_dir2_leaf_tail_t *ltp; xfs_da_intnode_t *node; int stale; + struct xfs_da3_icnode_hdr nodehdr; leaf = iocur_top->data; switch (be16_to_cpu(leaf->hdr.info.magic)) { @@ -3281,13 +3138,12 @@ break; case XFS_DA_NODE_MAGIC: node = iocur_top->data; - if (be16_to_cpu(node->hdr.level) < 1 || - be16_to_cpu(node->hdr.level) > - XFS_DA_NODE_MAXDEPTH) { + xfs_da3_node_hdr_from_disk(&nodehdr, node); + if (nodehdr.level < 1 || nodehdr.level > XFS_DA_NODE_MAXDEPTH) { if (!sflag || v) dbprintf(_("bad node block level %d for dir ino " "%lld block %d\n"), - be16_to_cpu(node->hdr.level), id->ino, + nodehdr.level, id->ino, dabno); error++; } @@ -3301,7 +3157,7 @@ error++; return; } - lep = leaf->ents; + lep = xfs_dir3_leaf_ents_p(leaf); for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) { if (be32_to_cpu(lep[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; @@ -3325,71 +3181,6 @@ } } -static xfs_ino_t -process_node_dir_v1( - blkmap_t *blkmap, - int *dot, - int *dotdot, - inodata_t *id) -{ - xfs_fsblock_t bno; - xfs_fileoff_t dbno; - xfs_ino_t lino; - xfs_ino_t parent; - int t; - int v; - int v2; - - v = verbose || id->ilist; - parent = 0; - dbno = NULLFILEOFF; - push_cur(); - while ((dbno = blkmap_next_off(blkmap, dbno, &t)) != NULLFILEOFF) { - bno = blkmap_get(blkmap, dbno); - v2 = bno != NULLFSBLOCK && CHECK_BLIST(bno); - if (bno == NULLFSBLOCK && dbno == 0) { - if (!sflag || v) - dbprintf(_("can't read root block for directory " - "inode %lld\n"), - id->ino); - error++; - } - if (v || v2) - dbprintf(_("dir inode %lld block %u=%llu\n"), id->ino, - (__uint32_t)dbno, (xfs_dfsbno_t)bno); - if (bno == NULLFSBLOCK) - continue; - pop_cur(); - push_cur(); - set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bno), blkbb, - DB_RING_IGN, NULL); - if (iocur_top->data == NULL) { - if (!sflag || v || v2) - dbprintf(_("can't read block %u for directory " - "inode %lld\n"), - (__uint32_t)dbno, id->ino); - error++; - continue; - } - if (be16_to_cpu(((xfs_da_intnode_t *)iocur_top->data)-> - hdr.info.magic) == XFS_DA_NODE_MAGIC) - continue; - lino = process_leaf_dir_v1_int(dot, dotdot, id); - if (lino) { - if (parent) { - if (!sflag || v || v2) - dbprintf(_("multiple .. entries in dir " - "%lld\n"), - id->ino); - error++; - } else - parent = lino; - } - } - pop_cur(); - return parent; -} - static void process_quota( qtype_t qtype, @@ -3633,20 +3424,20 @@ int i8; xfs_ino_t lino; int offset; - xfs_dir2_sf_t *sf; + struct xfs_dir2_sf_hdr *sf; xfs_dir2_sf_entry_t *sfe; int v; - sf = (xfs_dir2_sf_t *)XFS_DFORK_DPTR(dip); + sf = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip); addlink_inode(id); v = verbose || id->ilist; if (v) dbprintf(_("dir %lld entry . %lld\n"), id->ino, id->ino); (*dot)++; sfe = xfs_dir2_sf_firstentry(sf); - offset = XFS_DIR2_DATA_FIRST_OFFSET; - for (i = sf->hdr.count - 1, i8 = 0; i >= 0; i--) { - if ((__psint_t)sfe + xfs_dir2_sf_entsize_byentry(sf, sfe) - + offset = xfs_dir3_data_first_offset(mp); + for (i = sf->count - 1, i8 = 0; i >= 0; i--) { + if ((__psint_t)sfe + xfs_dir3_sf_entsize(mp, sf, sfe->namelen) - (__psint_t)sf > be64_to_cpu(dip->di_size)) { if (!sflag) dbprintf(_("dir %llu bad size in entry at %d\n"), @@ -3655,7 +3446,7 @@ error++; break; } - lino = xfs_dir2_sf_get_inumber(sf, xfs_dir2_sf_inumberp(sfe)); + lino = xfs_dir3_sfe_get_ino(mp, sf, sfe); if (lino > XFS_DIR2_MAX_SHORT_INUM) i8++; cid = find_inode(lino, 1); @@ -3685,8 +3476,8 @@ } offset = xfs_dir2_sf_get_offset(sfe) + - xfs_dir2_data_entsize(sfe->namelen); - sfe = xfs_dir2_sf_nextentry(sf, sfe); + xfs_dir3_sf_entsize(mp, sf, sfe->namelen); + sfe = xfs_dir3_sf_nextentry(mp, sf, sfe); } if (i < 0 && (__psint_t)sfe - (__psint_t)sf != be64_to_cpu(dip->di_size)) { @@ -3696,13 +3487,13 @@ (uint)((char *)sfe - (char *)sf)); error++; } - if (offset + (sf->hdr.count + 2) * sizeof(xfs_dir2_leaf_entry_t) + + if (offset + (sf->count + 2) * sizeof(xfs_dir2_leaf_entry_t) + sizeof(xfs_dir2_block_tail_t) > mp->m_dirblksize) { if (!sflag) dbprintf(_("dir %llu offsets too high\n"), id->ino); error++; } - lino = xfs_dir2_sf_get_inumber(sf, &sf->hdr.parent); + lino = xfs_dir2_sf_get_parent_ino(sf); if (lino > XFS_DIR2_MAX_SHORT_INUM) i8++; cid = find_inode(lino, 1); @@ -3716,78 +3507,17 @@ } if (v) dbprintf(_("dir %lld entry .. %lld\n"), id->ino, lino); - if (i8 != sf->hdr.i8count) { + if (i8 != sf->i8count) { if (!sflag) dbprintf(_("dir %lld i8count mismatch is %d should be " "%d\n"), - id->ino, sf->hdr.i8count, i8); + id->ino, sf->i8count, i8); error++; } (*dotdot)++; return cid ? lino : NULLFSINO; } -static xfs_ino_t -process_shortform_dir_v1( - xfs_dinode_t *dip, - int *dot, - int *dotdot, - inodata_t *id) -{ - inodata_t *cid; - int i; - xfs_ino_t lino; - xfs_dir_shortform_t *sf; - xfs_dir_sf_entry_t *sfe; - int v; - - sf = (xfs_dir_shortform_t *)XFS_DFORK_DPTR(dip); - addlink_inode(id); - v = verbose || id->ilist; - if (v) - dbprintf(_("dir %lld entry . %lld\n"), id->ino, id->ino); - (*dot)++; - sfe = &sf->list[0]; - for (i = sf->hdr.count - 1; i >= 0; i--) { - lino = XFS_GET_DIR_INO8(sfe->inumber); - cid = find_inode(lino, 1); - if (cid == NULL) { - if (!sflag) - dbprintf(_("dir %lld entry %*.*s bad inode " - "number %lld\n"), - id->ino, sfe->namelen, sfe->namelen, - sfe->name, lino); - error++; - } else { - addlink_inode(cid); - if (!cid->parent) - cid->parent = id; - addname_inode(cid, (char *)sfe->name, sfe->namelen); - } - if (v) - dbprintf(_("dir %lld entry %*.*s %lld\n"), id->ino, - sfe->namelen, sfe->namelen, sfe->name, lino); - sfe = xfs_dir_sf_nextentry(sfe); - } - if ((__psint_t)sfe - (__psint_t)sf != be64_to_cpu(dip->di_size)) - dbprintf(_("dir %llu size is %lld, should be %d\n"), - id->ino, be64_to_cpu(dip->di_size), - (int)((char *)sfe - (char *)sf)); - lino = XFS_GET_DIR_INO8(sf->hdr.parent); - cid = find_inode(lino, 1); - if (cid) - addlink_inode(cid); - else { - if (!sflag) - dbprintf(_("dir %lld entry .. bad inode number %lld\n"), - id->ino, lino); - error++; - } - if (v) - dbprintf(_("dir %lld entry .. %lld\n"), id->ino, lino); - (*dotdot)++; - return cid ? lino : NULLFSINO; -} static void quota_add( @@ -3896,11 +3626,11 @@ qgdo = mp->m_sb.sb_gquotino != 0 && mp->m_sb.sb_gquotino != NULLFSINO && (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) && - (mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD); - qpdo = mp->m_sb.sb_gquotino != 0 && - mp->m_sb.sb_gquotino != NULLFSINO && + (mp->m_sb.sb_qflags & XFS_GQUOTA_CHKD); + qpdo = mp->m_sb.sb_pquotino != 0 && + mp->m_sb.sb_pquotino != NULLFSINO && (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) && - (mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD); + (mp->m_sb.sb_qflags & XFS_PQUOTA_CHKD); if (qudo) qudata = xcalloc(QDATA_HASH_SIZE, sizeof(qdata_t *)); if (qgdo) @@ -4093,6 +3823,7 @@ xfs_agblock_t bno; uint count; int i; + __be32 *freelist; if (XFS_SB_BLOCK(mp) != XFS_AGFL_BLOCK(mp) && XFS_AGF_BLOCK(mp) != XFS_AGFL_BLOCK(mp) && @@ -4112,9 +3843,22 @@ return; } i = be32_to_cpu(agf->agf_flfirst); + + /* verify agf values before proceeding */ + if (be32_to_cpu(agf->agf_flfirst) >= XFS_AGFL_SIZE(mp) || + be32_to_cpu(agf->agf_fllast) >= XFS_AGFL_SIZE(mp)) { + dbprintf(_("agf %d freelist blocks bad, skipping " + "freelist scan\n"), i); + pop_cur(); + return; + } + + /* open coded XFS_BUF_TO_AGFL_BNO */ + freelist = xfs_sb_version_hascrc(&((mp)->m_sb)) ? &agfl->agfl_bno[0] + : (__be32 *)agfl; count = 0; for (;;) { - bno = be32_to_cpu(agfl->agfl_bno[i]); + bno = be32_to_cpu(freelist[i]); set_dbmap(seqno, bno, 1, DBM_FREELIST, seqno, XFS_AGFL_BLOCK(mp)); count++; diff -Nru xfsprogs-3.1.9ubuntu2/db/convert.c xfsprogs-3.2.1ubuntu1/db/convert.c --- xfsprogs-3.1.9ubuntu2/db/convert.c 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/convert.c 2014-05-02 00:09:15.000000000 +0000 @@ -200,7 +200,6 @@ if (cur_agno != NULLAGNUMBER && (conmask & M(AGNUMBER)) == 0) { cvals[CT_AGNUMBER].agnumber = cur_agno; mask |= M(AGNUMBER); - conmask |= ~ctydescs[CT_AGNUMBER].allowed; } v = 0; for (c = (ctype_t)0; c < NCTS; c++) { diff -Nru xfsprogs-3.1.9ubuntu2/db/dir2.c xfsprogs-3.2.1ubuntu1/db/dir2.c --- xfsprogs-3.1.9ubuntu2/db/dir2.c 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/dir2.c 2014-05-02 00:09:15.000000000 +0000 @@ -22,9 +22,9 @@ #include "faddr.h" #include "fprint.h" #include "field.h" -#include "dir.h" #include "dir2.h" #include "init.h" +#include "output.h" static int dir2_block_hdr_count(void *obj, int startoff); static int dir2_block_leaf_count(void *obj, int startoff); @@ -59,13 +59,13 @@ { NULL } }; -#define BOFF(f) bitize(offsetof(xfs_dir2_block_t, f)) -#define DOFF(f) bitize(offsetof(xfs_dir2_data_t, f)) -#define FOFF(f) bitize(offsetof(xfs_dir2_free_t, f)) -#define LOFF(f) bitize(offsetof(xfs_dir2_leaf_t, f)) -#define NOFF(f) bitize(offsetof(xfs_da_intnode_t, f)) +#define BOFF(f) bitize(offsetof(struct xfs_dir2_data_hdr, f)) +#define DOFF(f) bitize(offsetof(struct xfs_dir2_data_hdr, f)) +#define FOFF(f) bitize(offsetof(struct xfs_dir2_free, f)) +#define LOFF(f) bitize(offsetof(struct xfs_dir2_leaf, f)) +#define NOFF(f) bitize(offsetof(struct xfs_da_intnode, f)) const field_t dir2_flds[] = { - { "bhdr", FLDT_DIR2_DATA_HDR, OI(BOFF(hdr)), dir2_block_hdr_count, + { "bhdr", FLDT_DIR2_DATA_HDR, OI(BOFF(magic)), dir2_block_hdr_count, FLD_COUNT, TYP_NONE }, { "bu", FLDT_DIR2_DATA_UNION, dir2_block_u_offset, dir2_block_u_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE }, @@ -73,7 +73,7 @@ dir2_block_leaf_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE }, { "btail", FLDT_DIR2_BLOCK_TAIL, dir2_block_tail_offset, dir2_block_tail_count, FLD_OFFSET|FLD_COUNT, TYP_NONE }, - { "dhdr", FLDT_DIR2_DATA_HDR, OI(DOFF(hdr)), dir2_data_hdr_count, + { "dhdr", FLDT_DIR2_DATA_HDR, OI(DOFF(magic)), dir2_data_hdr_count, FLD_COUNT, TYP_NONE }, { "du", FLDT_DIR2_DATA_UNION, dir2_data_u_offset, dir2_data_u_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE }, @@ -81,13 +81,13 @@ FLD_COUNT, TYP_NONE }, { "lbests", FLDT_DIR2_DATA_OFF, dir2_leaf_bests_offset, dir2_leaf_bests_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE }, - { "lents", FLDT_DIR2_LEAF_ENTRY, OI(LOFF(ents)), dir2_leaf_ents_count, + { "lents", FLDT_DIR2_LEAF_ENTRY, OI(LOFF(__ents)), dir2_leaf_ents_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, { "ltail", FLDT_DIR2_LEAF_TAIL, dir2_leaf_tail_offset, dir2_leaf_tail_count, FLD_OFFSET|FLD_COUNT, TYP_NONE }, - { "nhdr", FLDT_DIR_NODE_HDR, OI(NOFF(hdr)), dir2_node_hdr_count, + { "nhdr", FLDT_DA_NODE_HDR, OI(NOFF(hdr)), dir2_node_hdr_count, FLD_COUNT, TYP_NONE }, - { "nbtree", FLDT_DIR_NODE_ENTRY, OI(NOFF(btree)), dir2_node_btree_count, + { "nbtree", FLDT_DA_NODE_ENTRY, OI(NOFF(__btree)), dir2_node_btree_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, { "fhdr", FLDT_DIR2_FREE_HDR, OI(FOFF(hdr)), dir2_free_hdr_count, FLD_COUNT, TYP_NONE }, @@ -145,7 +145,7 @@ #define LHOFF(f) bitize(offsetof(xfs_dir2_leaf_hdr_t, f)) const field_t dir2_leaf_hdr_flds[] = { - { "info", FLDT_DIR_BLKINFO, OI(LHOFF(info)), C1, 0, TYP_NONE }, + { "info", FLDT_DA_BLKINFO, OI(LHOFF(info)), C1, 0, TYP_NONE }, { "count", FLDT_UINT16D, OI(LHOFF(count)), C1, 0, TYP_NONE }, { "stale", FLDT_UINT16D, OI(LHOFF(stale)), C1, 0, TYP_NONE }, { NULL } @@ -166,153 +166,227 @@ { NULL } }; -/*ARGSUSED*/ +#define DBOFF(f) bitize(offsetof(xfs_da_blkinfo_t, f)) +const field_t da_blkinfo_flds[] = { + { "forw", FLDT_DIRBLOCK, OI(DBOFF(forw)), C1, 0, TYP_INODATA }, + { "back", FLDT_DIRBLOCK, OI(DBOFF(back)), C1, 0, TYP_INODATA }, + { "magic", FLDT_UINT16X, OI(DBOFF(magic)), C1, 0, TYP_NONE }, + { "pad", FLDT_UINT16X, OI(DBOFF(pad)), C1, FLD_SKIPALL, TYP_NONE }, + { NULL } +}; + +#define EOFF(f) bitize(offsetof(xfs_da_node_entry_t, f)) +const field_t da_node_entry_flds[] = { + { "hashval", FLDT_UINT32X, OI(EOFF(hashval)), C1, 0, TYP_NONE }, + { "before", FLDT_DIRBLOCK, OI(EOFF(before)), C1, 0, TYP_INODATA }, + { NULL } +}; + +#define HOFF(f) bitize(offsetof(xfs_da_node_hdr_t, f)) +const field_t da_node_hdr_flds[] = { + { "info", FLDT_DA_BLKINFO, OI(HOFF(info)), C1, 0, TYP_NONE }, + { "count", FLDT_UINT16D, OI(HOFF(__count)), C1, 0, TYP_NONE }, + { "level", FLDT_UINT16D, OI(HOFF(__level)), C1, 0, TYP_NONE }, + { NULL } +}; + +/* + * Worker functions shared between either dir2/dir3 or block/data formats + */ +static int +__dir2_block_tail_offset( + struct xfs_dir2_data_hdr *block, + int startoff, + int idx) +{ + struct xfs_dir2_block_tail *btp; + + ASSERT(startoff == 0); + ASSERT(idx == 0); + btp = xfs_dir2_block_tail_p(mp, block); + return bitize((int)((char *)btp - (char *)block)); +} + +static int +__dir2_data_entries_count( + char *ptr, + char *endptr) +{ + int i; + + for (i = 0; ptr < endptr; i++) { + struct xfs_dir2_data_entry *dep; + struct xfs_dir2_data_unused *dup; + + dup = (xfs_dir2_data_unused_t *)ptr; + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) + ptr += be16_to_cpu(dup->length); + else { + dep = (xfs_dir2_data_entry_t *)ptr; + ptr += xfs_dir3_data_entsize(mp, dep->namelen); + } + } + return i; +} + +static char * +__dir2_data_entry_offset( + char *ptr, + char *endptr, + int idx) +{ + int i; + + for (i = 0; i < idx; i++) { + struct xfs_dir2_data_entry *dep; + struct xfs_dir2_data_unused *dup; + + ASSERT(ptr < endptr); + dup = (xfs_dir2_data_unused_t *)ptr; + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) + ptr += be16_to_cpu(dup->length); + else { + dep = (xfs_dir2_data_entry_t *)ptr; + ptr += xfs_dir3_data_entsize(mp, dep->namelen); + } + } + return ptr; +} + +/* + * Block format functions + */ static int dir2_block_hdr_count( void *obj, int startoff) { - xfs_dir2_block_t *block; + struct xfs_dir2_data_hdr *block = obj; ASSERT(startoff == 0); - block = obj; - return be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC; + return be32_to_cpu(block->magic) == XFS_DIR2_BLOCK_MAGIC; +} + +static int +dir3_block_hdr_count( + void *obj, + int startoff) +{ + struct xfs_dir2_data_hdr *block = obj; + + ASSERT(startoff == 0); + return be32_to_cpu(block->magic) == XFS_DIR3_BLOCK_MAGIC; } -/*ARGSUSED*/ static int dir2_block_leaf_count( void *obj, int startoff) { - xfs_dir2_block_t *block; - xfs_dir2_block_tail_t *btp; + struct xfs_dir2_data_hdr *block = obj; + struct xfs_dir2_block_tail *btp; ASSERT(startoff == 0); - block = obj; - if (be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC) + if (be32_to_cpu(block->magic) != XFS_DIR2_BLOCK_MAGIC && + be32_to_cpu(block->magic) != XFS_DIR3_BLOCK_MAGIC) return 0; btp = xfs_dir2_block_tail_p(mp, block); return be32_to_cpu(btp->count); } -/*ARGSUSED*/ static int dir2_block_leaf_offset( void *obj, int startoff, int idx) { - xfs_dir2_block_t *block; - xfs_dir2_block_tail_t *btp; - xfs_dir2_leaf_entry_t *lep; + struct xfs_dir2_data_hdr *block = obj; + struct xfs_dir2_block_tail *btp; + struct xfs_dir2_leaf_entry *lep; ASSERT(startoff == 0); - block = obj; - ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); + ASSERT(be32_to_cpu(block->magic) == XFS_DIR2_BLOCK_MAGIC || + be32_to_cpu(block->magic) == XFS_DIR3_BLOCK_MAGIC); btp = xfs_dir2_block_tail_p(mp, block); lep = xfs_dir2_block_leaf_p(btp) + idx; return bitize((int)((char *)lep - (char *)block)); } -/*ARGSUSED*/ static int dir2_block_tail_count( void *obj, int startoff) { - xfs_dir2_block_t *block; + struct xfs_dir2_data_hdr *block = obj; + + ASSERT(startoff == 0); + return be32_to_cpu(block->magic) == XFS_DIR2_BLOCK_MAGIC; +} + +static int +dir3_block_tail_count( + void *obj, + int startoff) +{ + struct xfs_dir2_data_hdr *block = obj; ASSERT(startoff == 0); - block = obj; - return be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC; + return be32_to_cpu(block->magic) == XFS_DIR3_BLOCK_MAGIC; } -/*ARGSUSED*/ static int dir2_block_tail_offset( void *obj, int startoff, int idx) { - xfs_dir2_block_t *block; - xfs_dir2_block_tail_t *btp; + struct xfs_dir2_data_hdr *block = obj; - ASSERT(startoff == 0); - ASSERT(idx == 0); - block = obj; - ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); - btp = xfs_dir2_block_tail_p(mp, block); - return bitize((int)((char *)btp - (char *)block)); + ASSERT(be32_to_cpu(block->magic) == XFS_DIR2_BLOCK_MAGIC || + be32_to_cpu(block->magic) == XFS_DIR3_BLOCK_MAGIC); + return __dir2_block_tail_offset(block, startoff, idx); } -/*ARGSUSED*/ static int dir2_block_u_count( void *obj, int startoff) { - xfs_dir2_block_t *block; - xfs_dir2_block_tail_t *btp; - xfs_dir2_data_entry_t *dep; - xfs_dir2_data_unused_t *dup; - char *endptr; - int i; - char *ptr; + struct xfs_dir2_data_hdr *block = obj; + struct xfs_dir2_block_tail *btp; ASSERT(startoff == 0); - block = obj; - if (be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC) + if (be32_to_cpu(block->magic) != XFS_DIR2_BLOCK_MAGIC && + be32_to_cpu(block->magic) != XFS_DIR3_BLOCK_MAGIC) return 0; + btp = xfs_dir2_block_tail_p(mp, block); - ptr = (char *)block->u; - endptr = (char *)xfs_dir2_block_leaf_p(btp); - for (i = 0; ptr < endptr; i++) { - dup = (xfs_dir2_data_unused_t *)ptr; - if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) - ptr += be16_to_cpu(dup->length); - else { - dep = (xfs_dir2_data_entry_t *)ptr; - ptr += xfs_dir2_data_entsize(dep->namelen); - } - } - return i; + return __dir2_data_entries_count((char *)xfs_dir3_data_unused_p(block), + (char *)xfs_dir2_block_leaf_p(btp)); } -/*ARGSUSED*/ static int dir2_block_u_offset( void *obj, int startoff, int idx) { - xfs_dir2_block_t *block; - xfs_dir2_block_tail_t *btp; - xfs_dir2_data_entry_t *dep; - xfs_dir2_data_unused_t *dup; - char *endptr; - int i; + struct xfs_dir2_data_hdr *block = obj; + struct xfs_dir2_block_tail *btp; char *ptr; ASSERT(startoff == 0); - block = obj; - ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); + ASSERT(be32_to_cpu(block->magic) == XFS_DIR2_BLOCK_MAGIC || + be32_to_cpu(block->magic) == XFS_DIR3_BLOCK_MAGIC); btp = xfs_dir2_block_tail_p(mp, block); - ptr = (char *)block->u; - endptr = (char *)xfs_dir2_block_leaf_p(btp); - for (i = 0; i < idx; i++) { - ASSERT(ptr < endptr); - dup = (xfs_dir2_data_unused_t *)ptr; - if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) - ptr += be16_to_cpu(dup->length); - else { - dep = (xfs_dir2_data_entry_t *)ptr; - ptr += xfs_dir2_data_entsize(dep->namelen); - } - } + ptr = __dir2_data_entry_offset((char *)xfs_dir3_data_unused_p(block), + (char *)xfs_dir2_block_leaf_p(btp), idx); return bitize((int)(ptr - (char *)block)); } +/* + * Data block format functions + */ static int dir2_data_union_freetag_count( void *obj, @@ -422,13 +496,12 @@ end = (char *)&dep->namelen + sizeof(dep->namelen); if (end > (char *)obj + mp->m_dirblksize) return 0; - tagp = xfs_dir2_data_entry_tag_p(dep); + tagp = xfs_dir3_data_entry_tag_p(mp, dep); } end = (char *)tagp + sizeof(*tagp); return end <= (char *)obj + mp->m_dirblksize; } -/*ARGSUSED*/ static int dir2_data_union_tag_offset( void *obj, @@ -445,88 +518,65 @@ return bitize((int)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)dup)); dep = (xfs_dir2_data_entry_t *)dup; - return bitize((int)((char *)xfs_dir2_data_entry_tag_p(dep) - + return bitize((int)((char *)xfs_dir3_data_entry_tag_p(mp, dep) - (char *)dep)); } -/*ARGSUSED*/ static int dir2_data_hdr_count( void *obj, int startoff) { - xfs_dir2_data_t *data; + struct xfs_dir2_data_hdr *data = obj; + + ASSERT(startoff == 0); + return be32_to_cpu(data->magic) == XFS_DIR2_DATA_MAGIC; +} + +static int +dir3_data_hdr_count( + void *obj, + int startoff) +{ + struct xfs_dir2_data_hdr *data = obj; ASSERT(startoff == 0); - data = obj; - return be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC; + return be32_to_cpu(data->magic) == XFS_DIR3_DATA_MAGIC; } -/*ARGSUSED*/ static int dir2_data_u_count( void *obj, int startoff) { - xfs_dir2_data_t *data; - xfs_dir2_data_entry_t *dep; - xfs_dir2_data_unused_t *dup; - char *endptr; - int i; - char *ptr; + struct xfs_dir2_data_hdr *data = obj; ASSERT(startoff == 0); - data = obj; - if (be32_to_cpu(data->hdr.magic) != XFS_DIR2_DATA_MAGIC) + if (be32_to_cpu(data->magic) != XFS_DIR2_DATA_MAGIC && + be32_to_cpu(data->magic) != XFS_DIR3_DATA_MAGIC) return 0; - ptr = (char *)data->u; - endptr = (char *)data + mp->m_dirblksize; - for (i = 0; ptr < endptr; i++) { - dup = (xfs_dir2_data_unused_t *)ptr; - if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) - ptr += be16_to_cpu(dup->length); - else { - dep = (xfs_dir2_data_entry_t *)ptr; - ptr += xfs_dir2_data_entsize(dep->namelen); - } - } - return i; + + return __dir2_data_entries_count((char *)xfs_dir3_data_unused_p(data), + (char *)data + mp->m_dirblksize); } -/*ARGSUSED*/ static int dir2_data_u_offset( void *obj, int startoff, int idx) { - xfs_dir2_data_t *data; - xfs_dir2_data_entry_t *dep; - xfs_dir2_data_unused_t *dup; - /*REFERENCED*/ - char *endptr; - int i; + struct xfs_dir2_data_hdr *data = obj; char *ptr; ASSERT(startoff == 0); - data = obj; - ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC); - ptr = (char *)data->u; - endptr = (char *)data + mp->m_dirblksize; - for (i = 0; i < idx; i++) { - ASSERT(ptr < endptr); - dup = (xfs_dir2_data_unused_t *)ptr; - if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) - ptr += be16_to_cpu(dup->length); - else { - dep = (xfs_dir2_data_entry_t *)ptr; - ptr += xfs_dir2_data_entsize(dep->namelen); - } - } + ASSERT(be32_to_cpu(data->magic) == XFS_DIR2_DATA_MAGIC || + be32_to_cpu(data->magic) == XFS_DIR3_DATA_MAGIC); + ptr = __dir2_data_entry_offset((char *)xfs_dir3_data_unused_p(data), + (char *)data + mp->m_dirblksize, idx); return bitize((int)(ptr - (char *)data)); } -/*ARGSUSED*/ int dir2_data_union_size( void *obj, @@ -543,164 +593,259 @@ return bitize(be16_to_cpu(dup->length)); else { dep = (xfs_dir2_data_entry_t *)dup; - return bitize(xfs_dir2_data_entsize(dep->namelen)); + return bitize(xfs_dir3_data_entsize(mp, dep->namelen)); } } -/*ARGSUSED*/ +static int +dir3_data_union_ftype_offset( + void *obj, + int startoff, + int idx) +{ + xfs_dir2_data_entry_t *dep; + xfs_dir2_data_unused_t *dup; + + ASSERT(bitoffs(startoff) == 0); + ASSERT(idx == 0); + dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff)); + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) + return bitize((int)((char *)xfs_dir2_data_unused_tag_p(dup) - + (char *)dup)); + dep = (xfs_dir2_data_entry_t *)dup; + return bitize((int)((char *)&dep->name[dep->namelen] - (char *)dep)); +} + +/* + * Free block functions + */ static int dir2_free_bests_count( void *obj, int startoff) { - xfs_dir2_free_t *free; + struct xfs_dir2_free *free = obj; ASSERT(startoff == 0); - free = obj; if (be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC) return 0; return be32_to_cpu(free->hdr.nvalid); } -/*ARGSUSED*/ +static int +dir3_free_bests_count( + void *obj, + int startoff) +{ + struct xfs_dir3_free *free = obj; + + ASSERT(startoff == 0); + if (be32_to_cpu(free->hdr.hdr.magic) != XFS_DIR3_FREE_MAGIC) + return 0; + return be32_to_cpu(free->hdr.nvalid); +} + static int dir2_free_hdr_count( void *obj, int startoff) { - xfs_dir2_free_t *free; + struct xfs_dir2_free *free = obj; ASSERT(startoff == 0); - free = obj; return be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC; } -/*ARGSUSED*/ +static int +dir3_free_hdr_count( + void *obj, + int startoff) +{ + struct xfs_dir3_free *free = obj; + + ASSERT(startoff == 0); + return be32_to_cpu(free->hdr.hdr.magic) == XFS_DIR3_FREE_MAGIC; +} + +/* + * Leaf block functions + */ static int dir2_leaf_bests_count( void *obj, int startoff) { - xfs_dir2_leaf_t *leaf; - xfs_dir2_leaf_tail_t *ltp; + struct xfs_dir2_leaf *leaf = obj; + struct xfs_dir2_leaf_tail *ltp; ASSERT(startoff == 0); - leaf = obj; - if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAF1_MAGIC) + if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAF1_MAGIC && + be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR3_LEAF1_MAGIC) return 0; ltp = xfs_dir2_leaf_tail_p(mp, leaf); return be32_to_cpu(ltp->bestcount); } -/*ARGSUSED*/ static int dir2_leaf_bests_offset( void *obj, int startoff, int idx) { + struct xfs_dir2_leaf *leaf = obj; + struct xfs_dir2_leaf_tail *ltp; __be16 *lbp; - xfs_dir2_leaf_t *leaf; - xfs_dir2_leaf_tail_t *ltp; ASSERT(startoff == 0); - leaf = obj; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC || + be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR3_LEAF1_MAGIC); ltp = xfs_dir2_leaf_tail_p(mp, leaf); lbp = xfs_dir2_leaf_bests_p(ltp) + idx; return bitize((int)((char *)lbp - (char *)leaf)); } -/*ARGSUSED*/ static int dir2_leaf_ents_count( void *obj, int startoff) { - xfs_dir2_leaf_t *leaf; + struct xfs_dir2_leaf *leaf = obj; ASSERT(startoff == 0); - leaf = obj; if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAF1_MAGIC && be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAFN_MAGIC) return 0; return be16_to_cpu(leaf->hdr.count); } -/*ARGSUSED*/ +static int +dir3_leaf_ents_count( + void *obj, + int startoff) +{ + struct xfs_dir3_leaf *leaf = obj; + + ASSERT(startoff == 0); + if (be16_to_cpu(leaf->hdr.info.hdr.magic) != XFS_DIR3_LEAF1_MAGIC && + be16_to_cpu(leaf->hdr.info.hdr.magic) != XFS_DIR3_LEAFN_MAGIC) + return 0; + return be16_to_cpu(leaf->hdr.count); +} + static int dir2_leaf_hdr_count( void *obj, int startoff) { - xfs_dir2_leaf_t *leaf; + struct xfs_dir2_leaf *leaf = obj; ASSERT(startoff == 0); - leaf = obj; return be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC || be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC; } -/*ARGSUSED*/ +static int +dir3_leaf_hdr_count( + void *obj, + int startoff) +{ + struct xfs_dir3_leaf *leaf = obj; + + ASSERT(startoff == 0); + return be16_to_cpu(leaf->hdr.info.hdr.magic) == XFS_DIR3_LEAF1_MAGIC || + be16_to_cpu(leaf->hdr.info.hdr.magic) == XFS_DIR3_LEAFN_MAGIC; +} + static int dir2_leaf_tail_count( void *obj, int startoff) { - xfs_dir2_leaf_t *leaf; + struct xfs_dir2_leaf *leaf = obj; ASSERT(startoff == 0); - leaf = obj; return be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC; } -/*ARGSUSED*/ +static int +dir3_leaf_tail_count( + void *obj, + int startoff) +{ + struct xfs_dir3_leaf *leaf = obj; + + ASSERT(startoff == 0); + return be16_to_cpu(leaf->hdr.info.hdr.magic) == XFS_DIR3_LEAF1_MAGIC; +} + static int dir2_leaf_tail_offset( void *obj, int startoff, int idx) { - xfs_dir2_leaf_t *leaf; - xfs_dir2_leaf_tail_t *ltp; + struct xfs_dir2_leaf *leaf = obj; + struct xfs_dir2_leaf_tail *ltp; ASSERT(startoff == 0); ASSERT(idx == 0); - leaf = obj; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC || + be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR3_LEAF1_MAGIC); ltp = xfs_dir2_leaf_tail_p(mp, leaf); return bitize((int)((char *)ltp - (char *)leaf)); } -/*ARGSUSED*/ +/* + * Node format functions + */ static int dir2_node_btree_count( void *obj, int startoff) { - xfs_da_intnode_t *node; + xfs_da_intnode_t *node = obj; ASSERT(startoff == 0); - node = obj; if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC) return 0; - return be16_to_cpu(node->hdr.count); + return be16_to_cpu(node->hdr.__count); +} + +static int +dir3_node_btree_count( + void *obj, + int startoff) +{ + struct xfs_da3_intnode *node = obj; + + ASSERT(startoff == 0); + if (be16_to_cpu(node->hdr.info.hdr.magic) != XFS_DA3_NODE_MAGIC) + return 0; + return be16_to_cpu(node->hdr.__count); } -/*ARGSUSED*/ static int dir2_node_hdr_count( void *obj, int startoff) { - xfs_da_intnode_t *node; + struct xfs_da_intnode *node = obj; ASSERT(startoff == 0); - node = obj; return be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC; } -/*ARGSUSED*/ +static int +dir3_node_hdr_count( + void *obj, + int startoff) +{ + struct xfs_da3_intnode *node = obj; + + ASSERT(startoff == 0); + return be16_to_cpu(node->hdr.info.hdr.magic) == XFS_DA3_NODE_MAGIC; +} + int dir2_size( void *obj, @@ -709,3 +854,185 @@ { return bitize(mp->m_dirblksize); } + +/* + * CRC enabled structure definitions + */ +const field_t dir3_hfld[] = { + { "", FLDT_DIR3, OI(0), C1, 0, TYP_NONE }, + { NULL } +}; + +#define B3OFF(f) bitize(offsetof(struct xfs_dir3_data_hdr, f)) +#define D3OFF(f) bitize(offsetof(struct xfs_dir3_data_hdr, f)) +#define F3OFF(f) bitize(offsetof(struct xfs_dir3_free, f)) +#define L3OFF(f) bitize(offsetof(struct xfs_dir3_leaf, f)) +#define N3OFF(f) bitize(offsetof(struct xfs_da3_intnode, f)) +const field_t dir3_flds[] = { + { "bhdr", FLDT_DIR3_DATA_HDR, OI(B3OFF(hdr)), dir3_block_hdr_count, + FLD_COUNT, TYP_NONE }, + { "bu", FLDT_DIR3_DATA_UNION, dir2_block_u_offset, dir2_block_u_count, + FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE }, + { "bleaf", FLDT_DIR2_LEAF_ENTRY, dir2_block_leaf_offset, + dir2_block_leaf_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE }, + { "btail", FLDT_DIR2_BLOCK_TAIL, dir2_block_tail_offset, + dir3_block_tail_count, FLD_OFFSET|FLD_COUNT, TYP_NONE }, + { "dhdr", FLDT_DIR3_DATA_HDR, OI(D3OFF(hdr)), dir3_data_hdr_count, + FLD_COUNT, TYP_NONE }, + { "du", FLDT_DIR3_DATA_UNION, dir2_data_u_offset, dir2_data_u_count, + FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE }, + { "lhdr", FLDT_DIR3_LEAF_HDR, OI(L3OFF(hdr)), dir3_leaf_hdr_count, + FLD_COUNT, TYP_NONE }, + { "lbests", FLDT_DIR2_DATA_OFF, dir2_leaf_bests_offset, + dir2_leaf_bests_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE }, + { "lents", FLDT_DIR2_LEAF_ENTRY, OI(L3OFF(__ents)), dir3_leaf_ents_count, + FLD_ARRAY|FLD_COUNT, TYP_NONE }, + { "ltail", FLDT_DIR2_LEAF_TAIL, dir2_leaf_tail_offset, + dir3_leaf_tail_count, FLD_OFFSET|FLD_COUNT, TYP_NONE }, + { "nhdr", FLDT_DA3_NODE_HDR, OI(N3OFF(hdr)), dir3_node_hdr_count, + FLD_COUNT, TYP_NONE }, + { "nbtree", FLDT_DA_NODE_ENTRY, OI(N3OFF(__btree)), dir3_node_btree_count, + FLD_ARRAY|FLD_COUNT, TYP_NONE }, + { "fhdr", FLDT_DIR3_FREE_HDR, OI(F3OFF(hdr)), dir3_free_hdr_count, + FLD_COUNT, TYP_NONE }, + { "fbests", FLDT_DIR2_DATA_OFFNZ, OI(F3OFF(bests)), + dir3_free_bests_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, + { NULL } +}; + +#define D3EOFF(f) bitize(offsetof(xfs_dir2_data_entry_t, f)) +#define D3UOFF(f) bitize(offsetof(xfs_dir2_data_unused_t, f)) +const field_t dir3_data_union_flds[] = { + { "freetag", FLDT_UINT16X, OI(D3UOFF(freetag)), + dir2_data_union_freetag_count, FLD_COUNT, TYP_NONE }, + { "inumber", FLDT_INO, OI(D3EOFF(inumber)), + dir2_data_union_inumber_count, FLD_COUNT, TYP_INODE }, + { "length", FLDT_DIR2_DATA_OFF, OI(D3UOFF(length)), + dir2_data_union_length_count, FLD_COUNT, TYP_NONE }, + { "namelen", FLDT_UINT8D, OI(D3EOFF(namelen)), + dir2_data_union_namelen_count, FLD_COUNT, TYP_NONE }, + { "name", FLDT_CHARNS, OI(D3EOFF(name)), dir2_data_union_name_count, + FLD_COUNT, TYP_NONE }, + { "filetype", FLDT_UINT8D, dir3_data_union_ftype_offset, C1, + FLD_OFFSET, TYP_NONE }, + { "tag", FLDT_DIR2_DATA_OFF, dir2_data_union_tag_offset, + dir2_data_union_tag_count, FLD_OFFSET|FLD_COUNT, TYP_NONE }, + { NULL } +}; + +#define DBH3OFF(f) bitize(offsetof(struct xfs_dir3_blk_hdr, f)) +const field_t dir3_blkhdr_flds[] = { + { "magic", FLDT_UINT32X, OI(DBH3OFF(magic)), C1, 0, TYP_NONE }, + { "crc", FLDT_CRC, OI(DBH3OFF(crc)), C1, 0, TYP_NONE }, + { "bno", FLDT_DFSBNO, OI(DBH3OFF(blkno)), C1, 0, TYP_BMAPBTD }, + { "lsn", FLDT_UINT64X, OI(DBH3OFF(lsn)), C1, 0, TYP_NONE }, + { "uuid", FLDT_UUID, OI(DBH3OFF(uuid)), C1, 0, TYP_NONE }, + { "owner", FLDT_INO, OI(DBH3OFF(owner)), C1, 0, TYP_NONE }, + { NULL } +}; + +#define DH3OFF(f) bitize(offsetof(struct xfs_dir3_data_hdr, f)) +const field_t dir3_data_hdr_flds[] = { + { "hdr", FLDT_DIR3_BLKHDR, OI(DH3OFF(hdr)), C1, 0, TYP_NONE }, + { "bestfree", FLDT_DIR2_DATA_FREE, OI(DH3OFF(best_free)), + CI(XFS_DIR2_DATA_FD_COUNT), FLD_ARRAY, TYP_NONE }, + { NULL } +}; + +#define LH3OFF(f) bitize(offsetof(struct xfs_dir3_leaf_hdr, f)) +const field_t dir3_leaf_hdr_flds[] = { + { "info", FLDT_DA3_BLKINFO, OI(LH3OFF(info)), C1, 0, TYP_NONE }, + { "count", FLDT_UINT16D, OI(LH3OFF(count)), C1, 0, TYP_NONE }, + { "stale", FLDT_UINT16D, OI(LH3OFF(stale)), C1, 0, TYP_NONE }, + { NULL } +}; + +#define FH3OFF(f) bitize(offsetof(struct xfs_dir3_free_hdr, f)) +const field_t dir3_free_hdr_flds[] = { + { "hdr", FLDT_DIR3_BLKHDR, OI(FH3OFF(hdr)), C1, 0, TYP_NONE }, + { "firstdb", FLDT_INT32D, OI(FH3OFF(firstdb)), C1, 0, TYP_NONE }, + { "nvalid", FLDT_INT32D, OI(FH3OFF(nvalid)), C1, 0, TYP_NONE }, + { "nused", FLDT_INT32D, OI(FH3OFF(nused)), C1, 0, TYP_NONE }, + { NULL } +}; + + +#define DB3OFF(f) bitize(offsetof(struct xfs_da3_blkinfo, f)) +const field_t da3_blkinfo_flds[] = { + { "hdr", FLDT_DA_BLKINFO, OI(DB3OFF(hdr)), C1, 0, TYP_NONE }, + { "crc", FLDT_CRC, OI(DB3OFF(crc)), C1, 0, TYP_NONE }, + { "bno", FLDT_DFSBNO, OI(DB3OFF(blkno)), C1, 0, TYP_BMAPBTD }, + { "lsn", FLDT_UINT64X, OI(DB3OFF(lsn)), C1, 0, TYP_NONE }, + { "uuid", FLDT_UUID, OI(DB3OFF(uuid)), C1, 0, TYP_NONE }, + { "owner", FLDT_INO, OI(DB3OFF(owner)), C1, 0, TYP_NONE }, + { NULL } +}; + +#define H3OFF(f) bitize(offsetof(struct xfs_da3_node_hdr, f)) +const field_t da3_node_hdr_flds[] = { + { "info", FLDT_DA3_BLKINFO, OI(H3OFF(info)), C1, 0, TYP_NONE }, + { "count", FLDT_UINT16D, OI(H3OFF(__count)), C1, 0, TYP_NONE }, + { "level", FLDT_UINT16D, OI(H3OFF(__level)), C1, 0, TYP_NONE }, + { "pad", FLDT_UINT32D, OI(H3OFF(__pad32)), C1, 0, TYP_NONE }, + { NULL } +}; + +/* + * Special read verifier for directory buffers. Detect the magic number + * appropriately and set the correct verifier and call it. + */ +static void +xfs_dir3_db_read_verify( + struct xfs_buf *bp) +{ + __be32 magic32; + __be16 magic16; + + magic32 = *(__be32 *)bp->b_addr; + magic16 = ((struct xfs_da_blkinfo *)bp->b_addr)->magic; + + switch (magic32) { + case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC): + bp->b_ops = &xfs_dir3_block_buf_ops; + goto verify; + case cpu_to_be32(XFS_DIR3_DATA_MAGIC): + bp->b_ops = &xfs_dir3_data_buf_ops; + goto verify; + case cpu_to_be32(XFS_DIR3_FREE_MAGIC): + bp->b_ops = &xfs_dir3_free_buf_ops; + goto verify; + default: + break; + } + + switch (magic16) { + case cpu_to_be16(XFS_DIR3_LEAF1_MAGIC): + bp->b_ops = &xfs_dir3_leaf1_buf_ops; + break; + case cpu_to_be16(XFS_DIR3_LEAFN_MAGIC): + bp->b_ops = &xfs_dir3_leafn_buf_ops; + break; + case cpu_to_be16(XFS_DA3_NODE_MAGIC): + bp->b_ops = &xfs_da3_node_buf_ops; + break; + default: + dbprintf(_("Unknown directory buffer type!\n")); + xfs_buf_ioerror(bp, EFSCORRUPTED); + return; + } +verify: + bp->b_ops->verify_read(bp); +} + +static void +xfs_dir3_db_write_verify( + struct xfs_buf *bp) +{ + dbprintf(_("Writing unknown directory buffer type!\n")); + xfs_buf_ioerror(bp, EFSCORRUPTED); +} + +const struct xfs_buf_ops xfs_dir3_db_buf_ops = { + .verify_read = xfs_dir3_db_read_verify, + .verify_write = xfs_dir3_db_write_verify, +}; diff -Nru xfsprogs-3.1.9ubuntu2/db/dir2.h xfsprogs-3.2.1ubuntu1/db/dir2.h --- xfsprogs-3.1.9ubuntu2/db/dir2.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/dir2.h 2014-05-02 00:09:15.000000000 +0000 @@ -16,16 +16,49 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -extern const field_t dir2_flds[]; -extern const field_t dir2_hfld[]; +/* + * common types across directory formats + */ extern const field_t dir2_block_tail_flds[]; extern const field_t dir2_data_free_flds[]; -extern const field_t dir2_data_hdr_flds[]; extern const field_t dir2_data_union_flds[]; -extern const field_t dir2_free_hdr_flds[]; +extern const field_t dir2_leaf_tail_flds[]; extern const field_t dir2_leaf_entry_flds[]; + +extern const field_t da_node_entry_flds[]; + +/* + * dirv2 specific types + */ +extern const field_t dir2_flds[]; +extern const field_t dir2_hfld[]; +extern const field_t dir2_data_hdr_flds[]; +extern const field_t dir2_free_hdr_flds[]; extern const field_t dir2_leaf_hdr_flds[]; -extern const field_t dir2_leaf_tail_flds[]; + +extern const field_t da_blkinfo_flds[]; +extern const field_t da_node_hdr_flds[]; + +/* + * dirv3 specific types + */ +extern const field_t dir3_flds[]; +extern const field_t dir3_hfld[]; +extern const field_t dir3_blkhdr_flds[]; +extern const field_t dir3_data_hdr_flds[]; +extern const field_t dir3_free_hdr_flds[]; +extern const field_t dir3_leaf_hdr_flds[]; +extern const field_t dir3_data_union_flds[]; + +extern const field_t da3_blkinfo_flds[]; +extern const field_t da3_node_hdr_flds[]; + +static inline xfs_dir2_inou_t *xfs_dir2_sf_inumberp(xfs_dir2_sf_entry_t *sfep) +{ + return (xfs_dir2_inou_t *)&(sfep)->name[(sfep)->namelen]; +} extern int dir2_data_union_size(void *obj, int startoff, int idx); extern int dir2_size(void *obj, int startoff, int idx); + +extern const struct xfs_buf_ops xfs_dir3_db_buf_ops; diff -Nru xfsprogs-3.1.9ubuntu2/db/dir2sf.c xfsprogs-3.2.1ubuntu1/db/dir2sf.c --- xfsprogs-3.1.9ubuntu2/db/dir2sf.c 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/dir2sf.c 2013-10-10 21:07:17.000000000 +0000 @@ -22,7 +22,9 @@ #include "fprint.h" #include "field.h" #include "bit.h" +#include "dir2.h" #include "dir2sf.h" +#include "init.h" static int dir2_inou_i4_count(void *obj, int startoff); static int dir2_inou_i8_count(void *obj, int startoff); @@ -31,9 +33,9 @@ static int dir2_sf_list_count(void *obj, int startoff); static int dir2_sf_list_offset(void *obj, int startoff, int idx); -#define OFF(f) bitize(offsetof(xfs_dir2_sf_t, f)) +#define OFF(f) bitize(offsetof(struct xfs_dir2_sf_hdr, f)) const field_t dir2sf_flds[] = { - { "hdr", FLDT_DIR2_SF_HDR, OI(OFF(hdr)), C1, 0, TYP_NONE }, + { "hdr", FLDT_DIR2_SF_HDR, OI(OFF(count)), C1, 0, TYP_NONE }, { "list", FLDT_DIR2_SF_ENTRY, dir2_sf_list_offset, dir2_sf_list_count, FLD_ARRAY|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { NULL } @@ -73,11 +75,12 @@ void *obj, int startoff) { - xfs_dir2_sf_t *sf; + struct xfs_dinode *dip = obj; + struct xfs_dir2_sf_hdr *sf; ASSERT(bitoffs(startoff) == 0); - sf = (xfs_dir2_sf_t *)XFS_DFORK_DPTR(obj); - return sf->hdr.i8count == 0; + sf = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip); + return sf->i8count == 0; } /*ARGSUSED*/ @@ -86,11 +89,12 @@ void *obj, int startoff) { - xfs_dir2_sf_t *sf; + struct xfs_dinode *dip = obj; + struct xfs_dir2_sf_hdr *sf; ASSERT(bitoffs(startoff) == 0); - sf = (xfs_dir2_sf_t *)XFS_DFORK_DPTR(obj); - return sf->hdr.i8count != 0; + sf = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip); + return sf->i8count != 0; } /*ARGSUSED*/ @@ -100,12 +104,13 @@ int startoff, int idx) { - xfs_dir2_sf_t *sf; + struct xfs_dinode *dip = obj; + struct xfs_dir2_sf_hdr *sf; ASSERT(bitoffs(startoff) == 0); ASSERT(idx == 0); - sf = (xfs_dir2_sf_t *)XFS_DFORK_DPTR(obj); - return bitize(sf->hdr.i8count ? + sf = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip); + return bitize(sf->i8count ? (uint)sizeof(xfs_dir2_ino8_t) : (uint)sizeof(xfs_dir2_ino4_t)); } @@ -122,7 +127,6 @@ return e->namelen; } -/*ARGSUSED*/ static int dir2_sf_entry_inumber_offset( void *obj, @@ -137,6 +141,35 @@ return bitize((int)((char *)xfs_dir2_sf_inumberp(e) - (char *)e)); } +static int +dir3_sf_entry_inumber_offset( + void *obj, + int startoff, + int idx) +{ + xfs_dir2_sf_entry_t *e; + + ASSERT(bitoffs(startoff) == 0); + ASSERT(idx == 0); + e = (xfs_dir2_sf_entry_t *)((char *)obj + byteize(startoff)); + /* plus 1 to skip the ftype entry */ + return bitize((int)((char *)xfs_dir2_sf_inumberp(e) + 1 - (char *)e)); +} + +static int +dir3_sf_entry_ftype_offset( + void *obj, + int startoff, + int idx) +{ + xfs_dir2_sf_entry_t *e; + + ASSERT(bitoffs(startoff) == 0); + ASSERT(idx == 0); + e = (xfs_dir2_sf_entry_t *)((char *)obj + byteize(startoff)); + return bitize((int)((char *)&e->name[e->namelen] - (char *)e)); +} + int dir2_sf_entry_size( void *obj, @@ -145,14 +178,14 @@ { xfs_dir2_sf_entry_t *e; int i; - xfs_dir2_sf_t *sf; + struct xfs_dir2_sf_hdr *sf; ASSERT(bitoffs(startoff) == 0); - sf = (xfs_dir2_sf_t *)((char *)obj + byteize(startoff)); + sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff)); e = xfs_dir2_sf_firstentry(sf); for (i = 0; i < idx; i++) - e = xfs_dir2_sf_nextentry(sf, e); - return bitize((int)xfs_dir2_sf_entsize_byentry(sf, e)); + e = xfs_dir3_sf_nextentry(mp, sf, e); + return bitize((int)xfs_dir3_sf_entsize(mp, sf, e->namelen)); } /*ARGSUSED*/ @@ -162,12 +195,12 @@ int startoff, int idx) { - xfs_dir2_sf_t *sf; + struct xfs_dir2_sf_hdr *sf; ASSERT(bitoffs(startoff) == 0); ASSERT(idx == 0); - sf = (xfs_dir2_sf_t *)((char *)obj + byteize(startoff)); - return bitize(xfs_dir2_sf_hdr_size(sf->hdr.i8count)); + sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff)); + return bitize(xfs_dir2_sf_hdr_size(sf->i8count)); } static int @@ -175,11 +208,11 @@ void *obj, int startoff) { - xfs_dir2_sf_t *sf; + struct xfs_dir2_sf_hdr *sf; ASSERT(bitoffs(startoff) == 0); - sf = (xfs_dir2_sf_t *)((char *)obj + byteize(startoff)); - return sf->hdr.count; + sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff)); + return sf->count; } static int @@ -190,13 +223,13 @@ { xfs_dir2_sf_entry_t *e; int i; - xfs_dir2_sf_t *sf; + struct xfs_dir2_sf_hdr *sf; ASSERT(bitoffs(startoff) == 0); - sf = (xfs_dir2_sf_t *)((char *)obj + byteize(startoff)); + sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff)); e = xfs_dir2_sf_firstentry(sf); for (i = 0; i < idx; i++) - e = xfs_dir2_sf_nextentry(sf, e); + e = xfs_dir3_sf_nextentry(mp, sf, e); return bitize((int)((char *)e - (char *)sf)); } @@ -209,13 +242,35 @@ { xfs_dir2_sf_entry_t *e; int i; - xfs_dir2_sf_t *sf; + struct xfs_dir2_sf_hdr *sf; ASSERT(bitoffs(startoff) == 0); ASSERT(idx == 0); - sf = (xfs_dir2_sf_t *)((char *)obj + byteize(startoff)); + sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff)); e = xfs_dir2_sf_firstentry(sf); - for (i = 0; i < sf->hdr.count; i++) - e = xfs_dir2_sf_nextentry(sf, e); + for (i = 0; i < sf->count; i++) + e = xfs_dir3_sf_nextentry(mp, sf, e); return bitize((int)((char *)e - (char *)sf)); } + +#define OFF(f) bitize(offsetof(struct xfs_dir2_sf_hdr, f)) +const field_t dir3sf_flds[] = { + { "hdr", FLDT_DIR2_SF_HDR, OI(OFF(count)), C1, 0, TYP_NONE }, + { "list", FLDT_DIR3_SF_ENTRY, dir2_sf_list_offset, dir2_sf_list_count, + FLD_ARRAY|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { NULL } +}; + +#define E3OFF(f) bitize(offsetof(xfs_dir2_sf_entry_t, f)) +const field_t dir3_sf_entry_flds[] = { + { "namelen", FLDT_UINT8D, OI(EOFF(namelen)), C1, 0, TYP_NONE }, + { "offset", FLDT_DIR2_SF_OFF, OI(EOFF(offset)), C1, 0, TYP_NONE }, + { "name", FLDT_CHARNS, OI(EOFF(name)), dir2_sf_entry_name_count, + FLD_COUNT, TYP_NONE }, + { "inumber", FLDT_DIR2_INOU, dir3_sf_entry_inumber_offset, C1, + FLD_OFFSET, TYP_NONE }, + { "filetype", FLDT_UINT8D, dir3_sf_entry_ftype_offset, C1, + FLD_OFFSET, TYP_NONE }, + { NULL } +}; + diff -Nru xfsprogs-3.1.9ubuntu2/db/dir2sf.h xfsprogs-3.2.1ubuntu1/db/dir2sf.h --- xfsprogs-3.1.9ubuntu2/db/dir2sf.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/dir2sf.h 2013-10-10 21:07:17.000000000 +0000 @@ -21,6 +21,9 @@ extern const field_t dir2_sf_hdr_flds[]; extern const field_t dir2_sf_entry_flds[]; +extern const field_t dir3sf_flds[]; +extern const field_t dir3_sf_entry_flds[]; + extern int dir2sf_size(void *obj, int startoff, int idx); extern int dir2_inou_size(void *obj, int startoff, int idx); extern int dir2_sf_entry_size(void *obj, int startoff, int idx); diff -Nru xfsprogs-3.1.9ubuntu2/db/dir.c xfsprogs-3.2.1ubuntu1/db/dir.c --- xfsprogs-3.1.9ubuntu2/db/dir.c 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/dir.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "bit.h" -#include "type.h" -#include "faddr.h" -#include "fprint.h" -#include "field.h" -#include "dir.h" -#include "io.h" -#include "init.h" - -static int dir_leaf_entries_count(void *obj, int startoff); -static int dir_leaf_hdr_count(void *obj, int startoff); -static int dir_leaf_name_count(void *obj, int startoff); -static int dir_leaf_namelist_count(void *obj, int startoff); -static int dir_leaf_namelist_offset(void *obj, int startoff, int idx); -static int dir_node_btree_count(void *obj, int startoff); -static int dir_node_hdr_count(void *obj, int startoff); - -const field_t dir_hfld[] = { - { "", FLDT_DIR, OI(0), C1, 0, TYP_NONE }, - { NULL } -}; - -#define LOFF(f) bitize(offsetof(xfs_dir_leafblock_t, f)) -#define NOFF(f) bitize(offsetof(xfs_da_intnode_t, f)) -const field_t dir_flds[] = { - { "lhdr", FLDT_DIR_LEAF_HDR, OI(LOFF(hdr)), dir_leaf_hdr_count, - FLD_COUNT, TYP_NONE }, - { "nhdr", FLDT_DIR_NODE_HDR, OI(NOFF(hdr)), dir_node_hdr_count, - FLD_COUNT, TYP_NONE }, - { "entries", FLDT_DIR_LEAF_ENTRY, OI(LOFF(entries)), - dir_leaf_entries_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, - { "btree", FLDT_DIR_NODE_ENTRY, OI(NOFF(btree)), - dir_node_btree_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, - { "namelist", FLDT_DIR_LEAF_NAME, dir_leaf_namelist_offset, - dir_leaf_namelist_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE }, - { NULL } -}; - -#define BOFF(f) bitize(offsetof(xfs_da_blkinfo_t, f)) -const field_t dir_blkinfo_flds[] = { - { "forw", FLDT_DIRBLOCK, OI(BOFF(forw)), C1, 0, TYP_INODATA }, - { "back", FLDT_DIRBLOCK, OI(BOFF(back)), C1, 0, TYP_INODATA }, - { "magic", FLDT_UINT16X, OI(BOFF(magic)), C1, 0, TYP_NONE }, - { "pad", FLDT_UINT16X, OI(BOFF(pad)), C1, FLD_SKIPALL, TYP_NONE }, - { NULL } -}; - -#define LEOFF(f) bitize(offsetof(xfs_dir_leaf_entry_t, f)) -const field_t dir_leaf_entry_flds[] = { - { "hashval", FLDT_UINT32X, OI(LEOFF(hashval)), C1, 0, TYP_NONE }, - { "nameidx", FLDT_UINT16D, OI(LEOFF(nameidx)), C1, 0, TYP_NONE }, - { "namelen", FLDT_UINT8D, OI(LEOFF(namelen)), C1, 0, TYP_NONE }, - { "pad2", FLDT_UINT8X, OI(LEOFF(pad2)), C1, FLD_SKIPALL, TYP_NONE }, - { NULL } -}; - -#define LHOFF(f) bitize(offsetof(xfs_dir_leaf_hdr_t, f)) -const field_t dir_leaf_hdr_flds[] = { - { "info", FLDT_DIR_BLKINFO, OI(LHOFF(info)), C1, 0, TYP_NONE }, - { "count", FLDT_UINT16D, OI(LHOFF(count)), C1, 0, TYP_NONE }, - { "namebytes", FLDT_UINT16D, OI(LHOFF(namebytes)), C1, 0, TYP_NONE }, - { "firstused", FLDT_UINT16D, OI(LHOFF(firstused)), C1, 0, TYP_NONE }, - { "holes", FLDT_UINT8D, OI(LHOFF(holes)), C1, 0, TYP_NONE }, - { "pad1", FLDT_UINT8X, OI(LHOFF(pad1)), C1, FLD_SKIPALL, TYP_NONE }, - { "freemap", FLDT_DIR_LEAF_MAP, OI(LHOFF(freemap)), - CI(XFS_DIR_LEAF_MAPSIZE), FLD_ARRAY, TYP_NONE }, - { NULL } -}; - -#define LMOFF(f) bitize(offsetof(xfs_dir_leaf_map_t, f)) -const field_t dir_leaf_map_flds[] = { - { "base", FLDT_UINT16D, OI(LMOFF(base)), C1, 0, TYP_NONE }, - { "size", FLDT_UINT16D, OI(LMOFF(size)), C1, 0, TYP_NONE }, - { NULL } -}; - -#define LNOFF(f) bitize(offsetof(xfs_dir_leaf_name_t, f)) -const field_t dir_leaf_name_flds[] = { - { "inumber", FLDT_DIR_INO, OI(LNOFF(inumber)), C1, 0, TYP_INODE }, - { "name", FLDT_CHARNS, OI(LNOFF(name)), dir_leaf_name_count, FLD_COUNT, - TYP_NONE }, - { NULL } -}; - -#define EOFF(f) bitize(offsetof(xfs_da_node_entry_t, f)) -const field_t dir_node_entry_flds[] = { - { "hashval", FLDT_UINT32X, OI(EOFF(hashval)), C1, 0, TYP_NONE }, - { "before", FLDT_DIRBLOCK, OI(EOFF(before)), C1, 0, TYP_INODATA }, - { NULL } -}; - -#define HOFF(f) bitize(offsetof(xfs_da_node_hdr_t, f)) -const field_t dir_node_hdr_flds[] = { - { "info", FLDT_DIR_BLKINFO, OI(HOFF(info)), C1, 0, TYP_NONE }, - { "count", FLDT_UINT16D, OI(HOFF(count)), C1, 0, TYP_NONE }, - { "level", FLDT_UINT16D, OI(HOFF(level)), C1, 0, TYP_NONE }, - { NULL } -}; - -/*ARGSUSED*/ -static int -dir_leaf_entries_count( - void *obj, - int startoff) -{ - xfs_dir_leafblock_t *block; - - ASSERT(startoff == 0); - block = obj; - if (be16_to_cpu(block->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) - return 0; - return be16_to_cpu(block->hdr.count); -} - -/*ARGSUSED*/ -static int -dir_leaf_hdr_count( - void *obj, - int startoff) -{ - xfs_dir_leafblock_t *block; - - ASSERT(startoff == 0); - block = obj; - return be16_to_cpu(block->hdr.info.magic) == XFS_DIR_LEAF_MAGIC; -} - -static int -dir_leaf_name_count( - void *obj, - int startoff) -{ - xfs_dir_leafblock_t *block; - xfs_dir_leaf_entry_t *e; - int i; - int off; - - ASSERT(bitoffs(startoff) == 0); - off = byteize(startoff); - block = obj; - if (be16_to_cpu(block->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) - return 0; - for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { - e = &block->entries[i]; - if (be16_to_cpu(e->nameidx) == off) - return e->namelen; - } - return 0; -} - -/*ARGSUSED*/ -int -dir_leaf_name_size( - void *obj, - int startoff, - int idx) -{ - xfs_dir_leafblock_t *block; - xfs_dir_leaf_entry_t *e; - - ASSERT(startoff == 0); - block = obj; - if (be16_to_cpu(block->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) - return 0; - e = &block->entries[idx]; - return bitize((int)xfs_dir_leaf_entsize_byentry(e)); -} - -/*ARGSUSED*/ -static int -dir_leaf_namelist_count( - void *obj, - int startoff) -{ - xfs_dir_leafblock_t *block; - - ASSERT(startoff == 0); - block = obj; - if (be16_to_cpu(block->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) - return 0; - return be16_to_cpu(block->hdr.count); -} - -/*ARGSUSED*/ -static int -dir_leaf_namelist_offset( - void *obj, - int startoff, - int idx) -{ - xfs_dir_leafblock_t *block; - xfs_dir_leaf_entry_t *e; - - ASSERT(startoff == 0); - block = obj; - e = &block->entries[idx]; - return bitize(be16_to_cpu(e->nameidx)); -} - -/*ARGSUSED*/ -static int -dir_node_btree_count( - void *obj, - int startoff) -{ - xfs_da_intnode_t *block; - - ASSERT(startoff == 0); /* this is a base structure */ - block = obj; - if (be16_to_cpu(block->hdr.info.magic) != XFS_DA_NODE_MAGIC) - return 0; - return be16_to_cpu(block->hdr.count); -} - -/*ARGSUSED*/ -static int -dir_node_hdr_count( - void *obj, - int startoff) -{ - xfs_da_intnode_t *block; - - ASSERT(startoff == 0); - block = obj; - return be16_to_cpu(block->hdr.info.magic) == XFS_DA_NODE_MAGIC; -} - -/*ARGSUSED*/ -int -dir_size( - void *obj, - int startoff, - int idx) -{ - return bitize(mp->m_sb.sb_blocksize); -} diff -Nru xfsprogs-3.1.9ubuntu2/db/dir.h xfsprogs-3.2.1ubuntu1/db/dir.h --- xfsprogs-3.1.9ubuntu2/db/dir.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/dir.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -extern const field_t dir_flds[]; -extern const field_t dir_hfld[]; -extern const field_t dir_blkinfo_flds[]; -extern const field_t dir_leaf_entry_flds[]; -extern const field_t dir_leaf_hdr_flds[]; -extern const field_t dir_leaf_map_flds[]; -extern const field_t dir_leaf_name_flds[]; -extern const field_t dir_node_entry_flds[]; -extern const field_t dir_node_hdr_flds[]; - -extern int dir_leaf_name_size(void *obj, int startoff, int idx); -extern int dir_size(void *obj, int startoff, int idx); diff -Nru xfsprogs-3.1.9ubuntu2/db/dirshort.c xfsprogs-3.2.1ubuntu1/db/dirshort.c --- xfsprogs-3.1.9ubuntu2/db/dirshort.c 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/dirshort.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "type.h" -#include "faddr.h" -#include "fprint.h" -#include "field.h" -#include "bit.h" -#include "dirshort.h" - -static int dir_sf_entry_name_count(void *obj, int startoff); -static int dir_shortform_list_count(void *obj, int startoff); -static int dir_shortform_list_offset(void *obj, int startoff, int idx); - -#define OFF(f) bitize(offsetof(xfs_dir_shortform_t, f)) -const field_t dir_shortform_flds[] = { - { "hdr", FLDT_DIR_SF_HDR, OI(OFF(hdr)), C1, 0, TYP_NONE }, - { "list", FLDT_DIR_SF_ENTRY, dir_shortform_list_offset, - dir_shortform_list_count, FLD_ARRAY|FLD_COUNT|FLD_OFFSET, TYP_NONE }, - { NULL } -}; - -#define HOFF(f) bitize(offsetof(xfs_dir_sf_hdr_t, f)) -const field_t dir_sf_hdr_flds[] = { - { "parent", FLDT_DIR_INO, OI(HOFF(parent)), C1, 0, TYP_INODE }, - { "count", FLDT_UINT8D, OI(HOFF(count)), C1, 0, TYP_NONE }, - { NULL } -}; - -#define EOFF(f) bitize(offsetof(xfs_dir_sf_entry_t, f)) -const field_t dir_sf_entry_flds[] = { - { "inumber", FLDT_DIR_INO, OI(EOFF(inumber)), C1, 0, TYP_INODE }, - { "namelen", FLDT_UINT8D, OI(EOFF(namelen)), C1, 0, TYP_NONE }, - { "name", FLDT_CHARNS, OI(EOFF(name)), dir_sf_entry_name_count, - FLD_COUNT, TYP_NONE }, - { NULL } -}; - -static int -dir_sf_entry_name_count( - void *obj, - int startoff) -{ - xfs_dir_sf_entry_t *e; - - ASSERT(bitoffs(startoff) == 0); - e = (xfs_dir_sf_entry_t *)((char *)obj + byteize(startoff)); - return e->namelen; -} - -int -dir_sf_entry_size( - void *obj, - int startoff, - int idx) -{ - xfs_dir_sf_entry_t *e; - int i; - xfs_dir_shortform_t *sf; - - ASSERT(bitoffs(startoff) == 0); - sf = (xfs_dir_shortform_t *)((char *)obj + byteize(startoff)); - e = &sf->list[0]; - for (i = 0; i < idx; i++) - e = xfs_dir_sf_nextentry(e); - return bitize((int)xfs_dir_sf_entsize_byentry(e)); -} - -static int -dir_shortform_list_count( - void *obj, - int startoff) -{ - xfs_dir_shortform_t *sf; - - ASSERT(bitoffs(startoff) == 0); - sf = (xfs_dir_shortform_t *)((char *)obj + byteize(startoff)); - return sf->hdr.count; -} - -static int -dir_shortform_list_offset( - void *obj, - int startoff, - int idx) -{ - xfs_dir_sf_entry_t *e; - int i; - xfs_dir_shortform_t *sf; - - ASSERT(bitoffs(startoff) == 0); - sf = (xfs_dir_shortform_t *)((char *)obj + byteize(startoff)); - e = &sf->list[0]; - for (i = 0; i < idx; i++) - e = xfs_dir_sf_nextentry(e); - return bitize((int)((char *)e - (char *)sf)); -} - -int -dirshort_size( - void *obj, - int startoff, - int idx) -{ - xfs_dir_sf_entry_t *e; - int i; - xfs_dir_shortform_t *sf; - - ASSERT(bitoffs(startoff) == 0); - ASSERT(idx == 0); - sf = (xfs_dir_shortform_t *)((char *)obj + byteize(startoff)); - e = &sf->list[0]; - for (i = 0; i < sf->hdr.count; i++) - e = xfs_dir_sf_nextentry(e); - return bitize((int)((char *)e - (char *)sf)); -} diff -Nru xfsprogs-3.1.9ubuntu2/db/dirshort.h xfsprogs-3.2.1ubuntu1/db/dirshort.h --- xfsprogs-3.1.9ubuntu2/db/dirshort.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/dirshort.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -extern const field_t dir_sf_entry_flds[]; -extern const field_t dir_sf_hdr_flds[]; -extern const field_t dir_shortform_flds[]; -extern const field_t dirshort_hfld[]; - -extern int dir_sf_entry_size(void *obj, int startoff, int idx); -extern int dirshort_size(void *obj, int startoff, int idx); diff -Nru xfsprogs-3.1.9ubuntu2/db/dquot.c xfsprogs-3.2.1ubuntu1/db/dquot.c --- xfsprogs-3.1.9ubuntu2/db/dquot.c 2009-02-17 01:14:58.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/dquot.c 2014-05-02 00:09:15.000000000 +0000 @@ -48,6 +48,9 @@ { "diskdq", FLDT_DISK_DQUOT, OI(DDOFF(diskdq)), C1, 0, TYP_NONE }, { "fill", FLDT_CHARS, OI(DDOFF(fill)), CI(DDSZC(fill)), FLD_SKIPALL, TYP_NONE }, + { "crc", FLDT_CRC, OI(DDOFF(crc)), C1, 0, TYP_NONE }, + { "lsn", FLDT_UINT64X, OI(DDOFF(lsn)), C1, 0, TYP_NONE }, + { "uuid", FLDT_UUID, OI(DDOFF(uuid)), C1, 0, TYP_NONE }, { NULL } }; @@ -130,10 +133,13 @@ dbprintf(_("dquot command requires one %s id argument\n"), s); return 0; } - ino = (dogrp || doprj) ? mp->m_sb.sb_gquotino : mp->m_sb.sb_uquotino; - if (ino == 0 || ino == NULLFSINO || - (dogrp && (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT)) || - (doprj && (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT))) { + ino = mp->m_sb.sb_uquotino; + if (doprj) + ino = mp->m_sb.sb_pquotino; + else if (dogrp) + ino = mp->m_sb.sb_gquotino; + + if (ino == 0 || ino == NULLFSINO) { dbprintf(_("no %s quota inode present\n"), s); return 0; } diff -Nru xfsprogs-3.1.9ubuntu2/db/field.c xfsprogs-3.2.1ubuntu1/db/field.c --- xfsprogs-3.1.9ubuntu2/db/field.c 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/field.c 2014-05-02 00:09:15.000000000 +0000 @@ -29,13 +29,12 @@ #include "agfl.h" #include "agi.h" #include "sb.h" -#include "dir.h" -#include "dirshort.h" #include "attr.h" #include "attrshort.h" #include "dquot.h" #include "dir2.h" #include "dir2sf.h" +#include "symlink.h" const ftattr_t ftattrtab[] = { { FLDT_AEXTNUM, "aextnum", fp_num, "%d", SI(bitsz(xfs_aextnum_t)), @@ -48,6 +47,8 @@ agf_flds }, { FLDT_AGFL, "agfl", NULL, (char *)agfl_flds, agfl_size, FTARG_SIZE, NULL, agfl_flds }, + { FLDT_AGFL_CRC, "agfl", NULL, (char *)agfl_crc_flds, agfl_size, + FTARG_SIZE, NULL, agfl_crc_flds }, { FLDT_AGI, "agi", NULL, (char *)agi_flds, agi_size, FTARG_SIZE, NULL, agi_flds }, { FLDT_AGINO, "agino", fp_num, "%u", SI(bitsz(xfs_agino_t)), @@ -56,6 +57,8 @@ FTARG_SKIPNULL, fa_agino, NULL }, { FLDT_AGNUMBER, "agnumber", fp_num, "%u", SI(bitsz(xfs_agnumber_t)), FTARG_DONULL, NULL, NULL }, + +/* attr fields */ { FLDT_ATTR, "attr", NULL, (char *)attr_flds, attr_size, FTARG_SIZE, NULL, attr_flds }, { FLDT_ATTR_BLKINFO, "attr_blkinfo", NULL, (char *)attr_blkinfo_flds, @@ -84,8 +87,21 @@ fa_attrblock, NULL }, { FLDT_ATTRSHORT, "attrshort", NULL, (char *)attr_shortform_flds, attrshort_size, FTARG_SIZE, NULL, attr_shortform_flds }, + +/* attr3 specific fields */ + { FLDT_ATTR3, "attr3", NULL, (char *)attr3_flds, attr_size, FTARG_SIZE, + NULL, attr3_flds }, + { FLDT_ATTR3_LEAF_HDR, "attr3_leaf_hdr", NULL, + (char *)attr3_leaf_hdr_flds, SI(bitsz(struct xfs_attr3_leaf_hdr)), + 0, NULL, attr3_leaf_hdr_flds }, + { FLDT_ATTR3_NODE_HDR, "attr3_node_hdr", NULL, + (char *)da3_node_hdr_flds, SI(bitsz(struct xfs_da3_node_hdr)), + 0, NULL, da3_node_hdr_flds }, + { FLDT_BMAPBTA, "bmapbta", NULL, (char *)bmapbta_flds, btblock_size, FTARG_SIZE, NULL, bmapbta_flds }, + { FLDT_BMAPBTA_CRC, "bmapbta", NULL, (char *)bmapbta_crc_flds, + btblock_size, FTARG_SIZE, NULL, bmapbta_crc_flds }, { FLDT_BMAPBTAKEY, "bmapbtakey", fp_sarray, (char *)bmapbta_key_flds, SI(bitsz(xfs_bmbt_key_t)), 0, NULL, bmapbta_key_flds }, { FLDT_BMAPBTAPTR, "bmapbtaptr", fp_num, "%llu", @@ -94,6 +110,8 @@ SI(bitsz(xfs_bmbt_rec_t)), 0, NULL, bmapbta_rec_flds }, { FLDT_BMAPBTD, "bmapbtd", NULL, (char *)bmapbtd_flds, btblock_size, FTARG_SIZE, NULL, bmapbtd_flds }, + { FLDT_BMAPBTD_CRC, "bmapbtd", NULL, (char *)bmapbtd_crc_flds, + btblock_size, FTARG_SIZE, NULL, bmapbtd_crc_flds }, { FLDT_BMAPBTDKEY, "bmapbtdkey", fp_sarray, (char *)bmapbtd_key_flds, SI(bitsz(xfs_bmbt_key_t)), 0, NULL, bmapbtd_key_flds }, { FLDT_BMAPBTDPTR, "bmapbtdptr", fp_num, "%llu", @@ -114,6 +132,8 @@ SI(bitsz(xfs_bmdr_ptr_t)), 0, fa_dfsbno, NULL }, { FLDT_BNOBT, "bnobt", NULL, (char *)bnobt_flds, btblock_size, FTARG_SIZE, NULL, bnobt_flds }, + { FLDT_BNOBT_CRC, "bnobt", NULL, (char *)bnobt_crc_flds, btblock_size, + FTARG_SIZE, NULL, bnobt_crc_flds }, { FLDT_BNOBTKEY, "bnobtkey", fp_sarray, (char *)bnobt_key_flds, SI(bitsz(xfs_alloc_key_t)), 0, NULL, bnobt_key_flds }, { FLDT_BNOBTPTR, "bnobtptr", fp_num, "%u", SI(bitsz(xfs_alloc_ptr_t)), @@ -135,12 +155,19 @@ { FLDT_CHARS, "chars", fp_num, "%c", SI(bitsz(char)), 0, NULL, NULL }, { FLDT_CNTBT, "cntbt", NULL, (char *)cntbt_flds, btblock_size, FTARG_SIZE, NULL, cntbt_flds }, + { FLDT_CNTBT_CRC, "cntbt", NULL, (char *)cntbt_crc_flds, btblock_size, + FTARG_SIZE, NULL, cntbt_crc_flds }, { FLDT_CNTBTKEY, "cntbtkey", fp_sarray, (char *)cntbt_key_flds, SI(bitsz(xfs_alloc_key_t)), 0, NULL, cntbt_key_flds }, { FLDT_CNTBTPTR, "cntbtptr", fp_num, "%u", SI(bitsz(xfs_alloc_ptr_t)), 0, fa_agblock, NULL }, { FLDT_CNTBTREC, "cntbtrec", fp_sarray, (char *)cntbt_rec_flds, SI(bitsz(xfs_alloc_rec_t)), 0, NULL, cntbt_rec_flds }, + +/* CRC field */ + { FLDT_CRC, "crc", fp_crc, "%#x (%s)", SI(bitsz(__uint32_t)), + 0, NULL, NULL }, + { FLDT_DEV, "dev", fp_num, "%#x", SI(bitsz(xfs_dev_t)), 0, NULL, NULL }, { FLDT_DFILOFFA, "dfiloffa", fp_num, "%llu", SI(bitsz(xfs_dfiloff_t)), 0, fa_dfiloffa, NULL }, @@ -156,8 +183,10 @@ SI(bitsz(__int8_t)), 0, NULL, NULL }, { FLDT_DINODE_U, "dinode_u", NULL, (char *)inode_u_flds, inode_u_size, FTARG_SIZE|FTARG_OKEMPTY, NULL, inode_u_flds }, - { FLDT_DIR, "dir", NULL, (char *)dir_flds, dir_size, FTARG_SIZE, NULL, - dir_flds }, + { FLDT_DINODE_V3, "dinode_v3", NULL, (char *)inode_v3_flds, + SI(bitsz(xfs_dinode_t)), 0, NULL, inode_v3_flds }, + +/* dir v2 fields */ { FLDT_DIR2, "dir2", NULL, (char *)dir2_flds, dir2_size, FTARG_SIZE, NULL, dir2_flds }, { FLDT_DIR2_BLOCK_TAIL, "dir2_block_tail", NULL, @@ -199,33 +228,41 @@ SI(bitsz(xfs_dir2_sf_off_t)), 0, NULL, NULL }, { FLDT_DIR2SF, "dir2sf", NULL, (char *)dir2sf_flds, dir2sf_size, FTARG_SIZE, NULL, dir2sf_flds }, - { FLDT_DIR_BLKINFO, "dir_blkinfo", NULL, (char *)dir_blkinfo_flds, - SI(bitsz(struct xfs_da_blkinfo)), 0, NULL, dir_blkinfo_flds }, - { FLDT_DIR_INO, "dir_ino", fp_num, "%llu", SI(bitsz(xfs_dir_ino_t)), 0, - fa_ino, NULL }, - { FLDT_DIR_LEAF_ENTRY, "dir_leaf_entry", fp_sarray, - (char *)dir_leaf_entry_flds, SI(bitsz(struct xfs_dir_leaf_entry)), 0, - NULL, dir_leaf_entry_flds }, - { FLDT_DIR_LEAF_HDR, "dir_leaf_hdr", NULL, (char *)dir_leaf_hdr_flds, - SI(bitsz(struct xfs_dir_leaf_hdr)), 0, NULL, dir_leaf_hdr_flds }, - { FLDT_DIR_LEAF_MAP, "dir_leaf_map", fp_sarray, - (char *)dir_leaf_map_flds, SI(bitsz(struct xfs_dir_leaf_map)), 0, - NULL, dir_leaf_map_flds }, - { FLDT_DIR_LEAF_NAME, "dir_leaf_name", NULL, (char *)dir_leaf_name_flds, - dir_leaf_name_size, FTARG_SIZE, NULL, dir_leaf_name_flds }, - { FLDT_DIR_NODE_ENTRY, "dir_node_entry", fp_sarray, - (char *)dir_node_entry_flds, SI(bitsz(struct xfs_da_node_entry)), 0, - NULL, dir_node_entry_flds }, - { FLDT_DIR_NODE_HDR, "dir_node_hdr", NULL, (char *)dir_node_hdr_flds, - SI(bitsz(struct xfs_da_node_hdr)), 0, NULL, dir_node_hdr_flds }, - { FLDT_DIR_SF_ENTRY, "dir_sf_entry", NULL, (char *)dir_sf_entry_flds, - dir_sf_entry_size, FTARG_SIZE, NULL, dir_sf_entry_flds }, - { FLDT_DIR_SF_HDR, "dir_sf_hdr", NULL, (char *)dir_sf_hdr_flds, - SI(bitsz(struct xfs_dir_sf_hdr)), 0, NULL, dir_sf_hdr_flds }, + +/* dir v3 fields */ + { FLDT_DIR3, "dir3", NULL, (char *)dir3_flds, dir2_size, FTARG_SIZE, + NULL, dir3_flds }, + { FLDT_DIR3_BLKHDR, "dir3_blk_hdr", NULL, (char *)dir3_blkhdr_flds, + SI(bitsz(struct xfs_dir3_blk_hdr)), 0, NULL, dir3_blkhdr_flds }, + { FLDT_DIR3_DATA_HDR, "dir3_data_hdr", NULL, (char *)dir3_data_hdr_flds, + SI(bitsz(struct xfs_dir3_data_hdr)), 0, NULL, dir3_data_hdr_flds }, + { FLDT_DIR3_FREE_HDR, "dir3_free_hdr", NULL, (char *)dir3_free_hdr_flds, + SI(bitsz(struct xfs_dir3_free_hdr)), 0, NULL, dir3_free_hdr_flds }, + { FLDT_DIR3_LEAF_HDR, "dir3_leaf_hdr", NULL, (char *)dir3_leaf_hdr_flds, + SI(bitsz(struct xfs_dir3_leaf_hdr)), 0, NULL, dir3_leaf_hdr_flds }, + { FLDT_DIR3_DATA_UNION, "dir3_data_union", NULL, + (char *)dir3_data_union_flds, dir2_data_union_size, FTARG_SIZE, NULL, + dir3_data_union_flds }, + { FLDT_DIR3_SF_ENTRY, "dir3_sf_entry", NULL, (char *)dir3_sf_entry_flds, + dir2_sf_entry_size, FTARG_SIZE, NULL, dir3_sf_entry_flds }, + { FLDT_DIR3SF, "dir3sf", NULL, (char *)dir3sf_flds, dir2sf_size, + FTARG_SIZE, NULL, dir3sf_flds }, + +/* dir v2/3 node fields */ + { FLDT_DA_BLKINFO, "dir_blkinfo", NULL, (char *)da_blkinfo_flds, + SI(bitsz(struct xfs_da_blkinfo)), 0, NULL, da_blkinfo_flds }, + { FLDT_DA_NODE_ENTRY, "dir_node_entry", fp_sarray, + (char *)da_node_entry_flds, SI(bitsz(struct xfs_da_node_entry)), 0, + NULL, da_node_entry_flds }, + { FLDT_DA_NODE_HDR, "dir_node_hdr", NULL, (char *)da_node_hdr_flds, + SI(bitsz(struct xfs_da_node_hdr)), 0, NULL, da_node_hdr_flds }, + { FLDT_DA3_BLKINFO, "dir_blkinfo", NULL, (char *)da3_blkinfo_flds, + SI(bitsz(struct xfs_da3_blkinfo)), 0, NULL, da3_blkinfo_flds }, + { FLDT_DA3_NODE_HDR, "dir_node_hdr", NULL, (char *)da3_node_hdr_flds, + SI(bitsz(struct xfs_da3_node_hdr)), 0, NULL, da3_node_hdr_flds }, + { FLDT_DIRBLOCK, "dirblock", fp_num, "%u", SI(bitsz(__uint32_t)), 0, fa_dirblock, NULL }, - { FLDT_DIRSHORT, "dirshort", NULL, (char *)dir_shortform_flds, - dirshort_size, FTARG_SIZE, NULL, dir_shortform_flds }, { FLDT_DISK_DQUOT, "disk_dquot", NULL, (char *)disk_dquot_flds, SI(bitsz(xfs_disk_dquot_t)), 0, NULL, disk_dquot_flds }, { FLDT_DQBLK, "dqblk", NULL, (char *)dqblk_flds, SI(bitsz(xfs_dqblk_t)), @@ -246,6 +283,8 @@ fa_ino, NULL }, { FLDT_INOBT, "inobt", NULL, (char *)inobt_flds, btblock_size, FTARG_SIZE, NULL, inobt_flds }, + { FLDT_INOBT_CRC, "inobt", NULL, (char *)inobt_crc_flds, btblock_size, + FTARG_SIZE, NULL, inobt_crc_flds }, { FLDT_INOBTKEY, "inobtkey", fp_sarray, (char *)inobt_key_flds, SI(bitsz(xfs_inobt_key_t)), 0, NULL, inobt_key_flds }, { FLDT_INOBTPTR, "inobtptr", fp_num, "%u", SI(bitsz(xfs_inobt_ptr_t)), @@ -254,6 +293,8 @@ SI(bitsz(xfs_inobt_rec_t)), 0, NULL, inobt_rec_flds }, { FLDT_INODE, "inode", NULL, (char *)inode_flds, inode_size, FTARG_SIZE, NULL, inode_flds }, + { FLDT_INODE_CRC, "inode", NULL, (char *)inode_crc_flds, inode_size, + FTARG_SIZE, NULL, inode_crc_flds }, { FLDT_INOFREE, "inofree", fp_num, "%#llx", SI(bitsz(xfs_inofree_t)), 0, NULL, NULL }, { FLDT_INT16D, "int16d", fp_num, "%d", SI(bitsz(__int16_t)), @@ -272,6 +313,11 @@ NULL, NULL }, { FLDT_SB, "sb", NULL, (char *)sb_flds, sb_size, FTARG_SIZE, NULL, sb_flds }, + +/* CRC enabled symlink */ + { FLDT_SYMLINK_CRC, "symlink", NULL, (char *)symlink_crc_flds, + symlink_size, FTARG_SIZE, NULL, symlink_crc_flds }, + { FLDT_TIME, "time", fp_time, NULL, SI(bitsz(__int32_t)), FTARG_SIGNED, NULL, NULL }, { FLDT_TIMESTAMP, "timestamp", NULL, (char *)timestamp_flds, diff -Nru xfsprogs-3.1.9ubuntu2/db/field.h xfsprogs-3.2.1ubuntu1/db/field.h --- xfsprogs-3.1.9ubuntu2/db/field.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/field.h 2014-05-02 00:09:15.000000000 +0000 @@ -22,10 +22,13 @@ FLDT_AGBLOCKNZ, FLDT_AGF, FLDT_AGFL, + FLDT_AGFL_CRC, FLDT_AGI, FLDT_AGINO, FLDT_AGINONN, FLDT_AGNUMBER, + + /* attr fields */ FLDT_ATTR, FLDT_ATTR_BLKINFO, FLDT_ATTR_LEAF_ENTRY, @@ -38,11 +41,19 @@ FLDT_ATTR_SF_HDR, FLDT_ATTRBLOCK, FLDT_ATTRSHORT, + + /* attr 3 specific fields */ + FLDT_ATTR3, + FLDT_ATTR3_LEAF_HDR, + FLDT_ATTR3_NODE_HDR, + FLDT_BMAPBTA, + FLDT_BMAPBTA_CRC, FLDT_BMAPBTAKEY, FLDT_BMAPBTAPTR, FLDT_BMAPBTAREC, FLDT_BMAPBTD, + FLDT_BMAPBTD_CRC, FLDT_BMAPBTDKEY, FLDT_BMAPBTDPTR, FLDT_BMAPBTDREC, @@ -53,6 +64,7 @@ FLDT_BMROOTDKEY, FLDT_BMROOTDPTR, FLDT_BNOBT, + FLDT_BNOBT_CRC, FLDT_BNOBTKEY, FLDT_BNOBTPTR, FLDT_BNOBTREC, @@ -64,9 +76,14 @@ FLDT_CHARNS, FLDT_CHARS, FLDT_CNTBT, + FLDT_CNTBT_CRC, FLDT_CNTBTKEY, FLDT_CNTBTPTR, FLDT_CNTBTREC, + + /* CRC field type */ + FLDT_CRC, + FLDT_DEV, FLDT_DFILOFFA, FLDT_DFILOFFD, @@ -75,7 +92,9 @@ FLDT_DINODE_CORE, FLDT_DINODE_FMT, FLDT_DINODE_U, - FLDT_DIR, + FLDT_DINODE_V3, + + /* dir v2 fields */ FLDT_DIR2, FLDT_DIR2_BLOCK_TAIL, FLDT_DIR2_DATA_FREE, @@ -94,18 +113,25 @@ FLDT_DIR2_SF_HDR, FLDT_DIR2_SF_OFF, FLDT_DIR2SF, - FLDT_DIR_BLKINFO, - FLDT_DIR_INO, - FLDT_DIR_LEAF_ENTRY, - FLDT_DIR_LEAF_HDR, - FLDT_DIR_LEAF_MAP, - FLDT_DIR_LEAF_NAME, - FLDT_DIR_NODE_ENTRY, - FLDT_DIR_NODE_HDR, - FLDT_DIR_SF_ENTRY, - FLDT_DIR_SF_HDR, + + /* dir v3 fields */ + FLDT_DIR3, + FLDT_DIR3_BLKHDR, + FLDT_DIR3_DATA_HDR, + FLDT_DIR3_FREE_HDR, + FLDT_DIR3_LEAF_HDR, + FLDT_DIR3_DATA_UNION, + FLDT_DIR3_SF_ENTRY, + FLDT_DIR3SF, + + /* dir v2/3 node fields */ + FLDT_DA_BLKINFO, + FLDT_DA_NODE_ENTRY, + FLDT_DA_NODE_HDR, + FLDT_DA3_BLKINFO, + FLDT_DA3_NODE_HDR, + FLDT_DIRBLOCK, - FLDT_DIRSHORT, FLDT_DISK_DQUOT, FLDT_DQBLK, FLDT_DQID, @@ -116,10 +142,12 @@ FLDT_FSIZE, FLDT_INO, FLDT_INOBT, + FLDT_INOBT_CRC, FLDT_INOBTKEY, FLDT_INOBTPTR, FLDT_INOBTREC, FLDT_INODE, + FLDT_INODE_CRC, FLDT_INOFREE, FLDT_INT16D, FLDT_INT32D, @@ -129,6 +157,10 @@ FLDT_QCNT, FLDT_QWARNCNT, FLDT_SB, + + /* CRC enabled symlink */ + FLDT_SYMLINK_CRC, + FLDT_TIME, FLDT_TIMESTAMP, FLDT_UINT1, diff -Nru xfsprogs-3.1.9ubuntu2/db/fprint.c xfsprogs-3.2.1ubuntu1/db/fprint.c --- xfsprogs-3.1.9ubuntu2/db/fprint.c 2009-02-17 01:14:58.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/fprint.c 2014-05-02 00:09:15.000000000 +0000 @@ -30,6 +30,7 @@ #include "output.h" #include "sig.h" #include "malloc.h" +#include "io.h" int fp_charns( @@ -182,5 +183,56 @@ if (i < count - 1) dbprintf(" "); } + return 1; +} + +/* + * CRC is correct is the current buffer it is being pulled out + * of is not marked with a EFSCORRUPTED error. + */ +int +fp_crc( + void *obj, + int bit, + int count, + char *fmtstr, + int size, + int arg, + int base, + int array) +{ + int bitpos; + int i; + __int64_t val; + char *ok; + + switch (iocur_crc_valid()) { + case -1: + ok = "unchecked"; + break; + case 0: + ok = "bad"; + break; + case 1: + ok = "correct"; + break; + default: + ok = "unknown state"; + break; + } + + for (i = 0, bitpos = bit; + i < count && !seenint(); + i++, bitpos += size) { + if (array) + dbprintf("%d:", i + base); + val = getbitval(obj, bitpos, size, BVUNSIGNED); + if (size > 32) + dbprintf(fmtstr, val, ok); + else + dbprintf(fmtstr, (__int32_t)val, ok); + if (i < count - 1) + dbprintf(" "); + } return 1; } diff -Nru xfsprogs-3.1.9ubuntu2/db/fprint.h xfsprogs-3.2.1ubuntu1/db/fprint.h --- xfsprogs-3.1.9ubuntu2/db/fprint.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/fprint.h 2014-05-02 00:09:15.000000000 +0000 @@ -29,3 +29,5 @@ int arg, int base, int array); extern int fp_uuid(void *obj, int bit, int count, char *fmtstr, int size, int arg, int base, int array); +extern int fp_crc(void *obj, int bit, int count, char *fmtstr, int size, + int arg, int base, int array); diff -Nru xfsprogs-3.1.9ubuntu2/db/frag.c xfsprogs-3.2.1ubuntu1/db/frag.c --- xfsprogs-3.1.9ubuntu2/db/frag.c 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/frag.c 2013-10-10 21:07:17.000000000 +0000 @@ -326,7 +326,8 @@ skipd = 1; else if (!qflag && (ino == mp->m_sb.sb_uquotino || - ino == mp->m_sb.sb_gquotino)) + ino == mp->m_sb.sb_gquotino || + ino == mp->m_sb.sb_pquotino)) skipd = 1; else skipd = !fflag; diff -Nru xfsprogs-3.1.9ubuntu2/db/freesp.c xfsprogs-3.2.1ubuntu1/db/freesp.c --- xfsprogs-3.1.9ubuntu2/db/freesp.c 2010-08-18 03:32:44.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/freesp.c 2013-10-10 21:07:17.000000000 +0000 @@ -96,6 +96,10 @@ if (!init(argc, argv)) return 0; + + if (dumpflag) + dbprintf("%8s %8s %8s\n", "agno", "agbno", "len"); + for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { if (inaglist(agno)) scan_ag(agno); @@ -231,6 +235,7 @@ xfs_agfl_t *agfl; xfs_agblock_t bno; int i; + __be32 *agfl_bno; if (be32_to_cpu(agf->agf_flcount) == 0) return; @@ -239,8 +244,22 @@ XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); agfl = iocur_top->data; i = be32_to_cpu(agf->agf_flfirst); + + /* open coded XFS_BUF_TO_AGFL_BNO */ + agfl_bno = xfs_sb_version_hascrc(&mp->m_sb) ? &agfl->agfl_bno[0] + : (__be32 *)agfl; + + /* verify agf values before proceeding */ + if (be32_to_cpu(agf->agf_flfirst) >= XFS_AGFL_SIZE(mp) || + be32_to_cpu(agf->agf_fllast) >= XFS_AGFL_SIZE(mp)) { + dbprintf(_("agf %d freelist blocks bad, skipping " + "freelist scan\n"), i); + pop_cur(); + return; + } + for (;;) { - bno = be32_to_cpu(agfl->agfl_bno[i]); + bno = be32_to_cpu(agfl_bno[i]); addtohist(seqno, bno, 1); if (i == be32_to_cpu(agf->agf_fllast)) break; @@ -286,7 +305,8 @@ xfs_alloc_ptr_t *pp; xfs_alloc_rec_t *rp; - if (be32_to_cpu(block->bb_magic) != XFS_ABTB_MAGIC) + if (!(be32_to_cpu(block->bb_magic) == XFS_ABTB_MAGIC || + be32_to_cpu(block->bb_magic) == XFS_ABTB_CRC_MAGIC)) return; if (level == 0) { @@ -313,7 +333,8 @@ xfs_alloc_ptr_t *pp; xfs_alloc_rec_t *rp; - if (be32_to_cpu(block->bb_magic) != XFS_ABTC_MAGIC) + if (!(be32_to_cpu(block->bb_magic) == XFS_ABTC_MAGIC || + be32_to_cpu(block->bb_magic) == XFS_ABTC_CRC_MAGIC)) return; if (level == 0) { diff -Nru xfsprogs-3.1.9ubuntu2/db/init.c xfsprogs-3.2.1ubuntu1/db/init.c --- xfsprogs-3.1.9ubuntu2/db/init.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/init.c 2014-05-02 00:09:15.000000000 +0000 @@ -26,6 +26,7 @@ #include "sig.h" #include "output.h" #include "malloc.h" +#include "type.h" static char **cmdline; static int ncmdline; @@ -43,7 +44,7 @@ usage(void) { fprintf(stderr, _( - "Usage: %s [-fFrxV] [-p prog] [-l logdev] [-c cmd]... device\n" + "Usage: %s [-ifFrxV] [-p prog] [-l logdev] [-c cmd]... device\n" ), progname); exit(1); } @@ -53,8 +54,8 @@ int argc, char **argv) { - xfs_sb_t *sbp; - void *bufp = NULL; + struct xfs_sb *sbp; + struct xfs_buf *bp; int c; setlocale(LC_ALL, ""); @@ -108,43 +109,69 @@ else x.dname = fsdevice; + x.bcache_flags = CACHE_MISCOMPARE_PURGE; if (!libxfs_init(&x)) { fputs(_("\nfatal error -- couldn't initialize XFS library\n"), stderr); exit(1); } - if (read_bbs(XFS_SB_DADDR, 1, &bufp, NULL)) { + /* + * Read the superblock, but don't validate it - we are a diagnostic + * tool and so need to be able to mount busted filesystems. + */ + memset(&xmount, 0, sizeof(struct xfs_mount)); + libxfs_buftarg_init(&xmount, x.ddev, x.logdev, x.rtdev); + bp = libxfs_readbuf(xmount.m_ddev_targp, XFS_SB_DADDR, + 1 << (XFS_MAX_SECTORSIZE_LOG - BBSHIFT), 0, NULL); + + if (!bp || bp->b_error) { fprintf(stderr, _("%s: %s is invalid (cannot read first 512 " "bytes)\n"), progname, fsdevice); exit(1); } /* copy SB from buffer to in-core, converting architecture as we go */ - libxfs_sb_from_disk(&xmount.m_sb, bufp); - xfree(bufp); + libxfs_sb_from_disk(&xmount.m_sb, XFS_BUF_TO_SBP(bp)); + libxfs_putbuf(bp); + libxfs_purgebuf(bp); sbp = &xmount.m_sb; if (sbp->sb_magicnum != XFS_SB_MAGIC) { fprintf(stderr, _("%s: %s is not a valid XFS filesystem (unexpected SB magic number 0x%08x)\n"), progname, fsdevice, sbp->sb_magicnum); - if (!force) + if (!force) { + fprintf(stderr, _("Use -F to force a read attempt.\n")); exit(EXIT_FAILURE); + } } mp = libxfs_mount(&xmount, sbp, x.ddev, x.logdev, x.rtdev, - LIBXFS_MOUNT_ROOTINOS | LIBXFS_MOUNT_DEBUGGER); + LIBXFS_MOUNT_DEBUGGER); if (!mp) { - mp = libxfs_mount(&xmount, sbp, x.ddev, x.logdev, x.rtdev, - LIBXFS_MOUNT_DEBUGGER); - if (!mp) { - fprintf(stderr, _("%s: device %s unusable (not an XFS " - "filesystem?)\n"), progname, fsdevice); - exit(1); - } + fprintf(stderr, + _("%s: device %s unusable (not an XFS filesystem?)\n"), + progname, fsdevice); + exit(1); } blkbb = 1 << mp->m_blkbb_log; + /* + * xfs_check needs corrected incore superblock values + */ + if (sbp->sb_rootino != NULLFSINO && + xfs_sb_version_haslazysbcount(&mp->m_sb)) { + int error = xfs_initialize_perag_data(mp, sbp->sb_agcount); + if (error) { + fprintf(stderr, + _("%s: cannot init perag data (%d). Continuing anyway.\n"), + progname, error); + } + } + + if (xfs_sb_version_hascrc(&mp->m_sb)) + type_set_tab_crc(); + push_cur(); init_commands(); init_sig(); @@ -158,9 +185,11 @@ int c, i, done = 0; char *input; char **v; + int start_iocur_sp; pushfile(stdin); init(argc, argv); + start_iocur_sp = iocur_sp; for (i = 0; !done && i < ncmdline; i++) { v = breakline(cmdline[i], &c); @@ -183,6 +212,13 @@ } close_devices: + /* + * Make sure that we pop the all the buffer contexts we hold so that + * they are released before we purge the caches during unmount. + */ + while (iocur_sp > start_iocur_sp) + pop_cur(); + libxfs_umount(mp); if (x.ddev) libxfs_device_close(x.ddev); if (x.logdev && x.logdev != x.ddev) diff -Nru xfsprogs-3.1.9ubuntu2/db/inode.c xfsprogs-3.2.1ubuntu1/db/inode.c --- xfsprogs-3.1.9ubuntu2/db/inode.c 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/inode.c 2014-05-02 00:09:15.000000000 +0000 @@ -46,8 +46,8 @@ static int inode_u_c_count(void *obj, int startoff); static int inode_u_dev_count(void *obj, int startoff); static int inode_u_muuid_count(void *obj, int startoff); -static int inode_u_sfdir_count(void *obj, int startoff); static int inode_u_sfdir2_count(void *obj, int startoff); +static int inode_u_sfdir3_count(void *obj, int startoff); static int inode_u_symlink_count(void *obj, int startoff); static const cmdinfo_t inode_cmd = @@ -58,6 +58,10 @@ { "", FLDT_INODE, OI(0), C1, 0, TYP_NONE }, { NULL } }; +const field_t inode_crc_hfld[] = { + { "", FLDT_INODE_CRC, OI(0), C1, 0, TYP_NONE }, + { NULL } +}; /* XXX: fix this up! */ #define OFF(f) bitize(offsetof(xfs_dinode_t, di_ ## f)) @@ -70,6 +74,17 @@ FLD_COUNT|FLD_OFFSET, TYP_NONE }, { NULL } }; +const field_t inode_crc_flds[] = { + { "core", FLDT_DINODE_CORE, OI(OFF(magic)), C1, 0, TYP_NONE }, + { "next_unlinked", FLDT_AGINO, OI(OFF(next_unlinked)), C1, 0, + TYP_INODE }, + { "v3", FLDT_DINODE_V3, OI(OFF(magic)), C1, 0, TYP_NONE }, + { "u3", FLDT_DINODE_U, inode_u_offset, C1, FLD_OFFSET, TYP_NONE }, + { "a", FLDT_DINODE_A, inode_a_offset, inode_a_count, + FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { NULL } +}; + #define COFF(f) bitize(offsetof(xfs_dinode_t, di_ ## f)) const field_t inode_core_flds[] = { @@ -152,6 +167,18 @@ { NULL } }; +const field_t inode_v3_flds[] = { + { "crc", FLDT_CRC, OI(COFF(crc)), C1, 0, TYP_NONE }, + { "change_count", FLDT_UINT64D, OI(COFF(changecount)), C1, 0, TYP_NONE }, + { "lsn", FLDT_UINT64X, OI(COFF(lsn)), C1, 0, TYP_NONE }, + { "flags2", FLDT_UINT64X, OI(COFF(flags2)), C1, 0, TYP_NONE }, + { "crtime", FLDT_TIMESTAMP, OI(COFF(crtime)), C1, 0, TYP_NONE }, + { "inumber", FLDT_INO, OI(COFF(ino)), C1, 0, TYP_NONE }, + { "uuid", FLDT_UUID, OI(COFF(uuid)), C1, 0, TYP_NONE }, + { NULL } +}; + + #define TOFF(f) bitize(offsetof(xfs_timestamp_t, t_ ## f)) const field_t timestamp_flds[] = { { "sec", FLDT_TIME, OI(TOFF(sec)), C1, 0, TYP_NONE }, @@ -166,8 +193,8 @@ { "c", FLDT_CHARNS, NULL, inode_u_c_count, FLD_COUNT, TYP_NONE }, { "dev", FLDT_DEV, NULL, inode_u_dev_count, FLD_COUNT, TYP_NONE }, { "muuid", FLDT_UUID, NULL, inode_u_muuid_count, FLD_COUNT, TYP_NONE }, - { "sfdir", FLDT_DIRSHORT, NULL, inode_u_sfdir_count, FLD_COUNT, TYP_NONE }, { "sfdir2", FLDT_DIR2SF, NULL, inode_u_sfdir2_count, FLD_COUNT, TYP_NONE }, + { "sfdir3", FLDT_DIR3SF, NULL, inode_u_sfdir3_count, FLD_COUNT, TYP_NONE }, { "symlink", FLDT_CHARNS, NULL, inode_u_symlink_count, FLD_COUNT, TYP_NONE }, { NULL } @@ -404,7 +431,7 @@ { switch (iocur_top->mode & S_IFMT) { case S_IFDIR: - return xfs_sb_version_hasdirv2(&mp->m_sb) ? TYP_DIR2 : TYP_DIR; + return TYP_DIR2; case S_IFLNK: return TYP_SYMLINK; case S_IFREG: @@ -413,7 +440,8 @@ else if (iocur_top->ino == mp->m_sb.sb_rsumino) return TYP_RTSUMMARY; else if (iocur_top->ino == mp->m_sb.sb_uquotino || - iocur_top->ino == mp->m_sb.sb_gquotino) + iocur_top->ino == mp->m_sb.sb_gquotino || + iocur_top->ino == mp->m_sb.sb_pquotino) return TYP_DQBLK; else return TYP_DATA; @@ -519,7 +547,7 @@ } static int -inode_u_sfdir_count( +inode_u_sfdir2_count( void *obj, int startoff) { @@ -530,12 +558,13 @@ dip = obj; ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff)); return dip->di_format == XFS_DINODE_FMT_LOCAL && - (be16_to_cpu(dip->di_mode) & S_IFMT) == S_IFDIR - && !xfs_sb_version_hasdirv2(&mp->m_sb); + (be16_to_cpu(dip->di_mode) & S_IFMT) == S_IFDIR && + xfs_sb_version_hasdirv2(&mp->m_sb) && + !xfs_sb_version_hasftype(&mp->m_sb); } static int -inode_u_sfdir2_count( +inode_u_sfdir3_count( void *obj, int startoff) { @@ -547,7 +576,7 @@ ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff)); return dip->di_format == XFS_DINODE_FMT_LOCAL && (be16_to_cpu(dip->di_mode) & S_IFMT) == S_IFDIR && - xfs_sb_version_hasdirv2(&mp->m_sb); + xfs_sb_version_hasftype(&mp->m_sb); } int @@ -594,6 +623,14 @@ (int)be64_to_cpu(dip->di_size) : 0; } +/* + * We are now using libxfs for our IO backend, so we should always try to use + * inode cluster buffers rather than filesystem block sized buffers for reading + * inodes. This means that we always use the same buffers as libxfs operations + * does, and that avoids buffer cache issues caused by overlapping buffers. This + * can be seen clearly when trying to read the root inode. Much of this logic is + * similar to libxfs_imap(). + */ void set_cur_inode( xfs_ino_t ino) @@ -603,6 +640,9 @@ xfs_agnumber_t agno; xfs_dinode_t *dip; int offset; + int numblks = blkbb; + xfs_agblock_t cluster_agbno; + agno = XFS_INO_TO_AGNO(mp, ino); agino = XFS_INO_TO_AGINO(mp, ino); @@ -615,6 +655,24 @@ return; } cur_agno = agno; + + if (mp->m_inode_cluster_size > mp->m_sb.sb_blocksize && + mp->m_inoalign_mask) { + xfs_agblock_t chunk_agbno; + xfs_agblock_t offset_agbno; + int blks_per_cluster; + + blks_per_cluster = mp->m_inode_cluster_size >> + mp->m_sb.sb_blocklog; + offset_agbno = agbno & mp->m_inoalign_mask; + chunk_agbno = agbno - offset_agbno; + cluster_agbno = chunk_agbno + + ((offset_agbno / blks_per_cluster) * blks_per_cluster); + offset += ((agbno - cluster_agbno) * mp->m_sb.sb_inopblock); + numblks = XFS_FSB_TO_BB(mp, blks_per_cluster); + } else + cluster_agbno = agbno; + /* * First set_cur to the block with the inode * then use off_cur to get the right part of the buffer. @@ -622,10 +680,12 @@ ASSERT(typtab[TYP_INODE].typnm == TYP_INODE); /* ingore ring update here, do it explicitly below */ - set_cur(&typtab[TYP_INODE], XFS_AGB_TO_DADDR(mp, agno, agbno), - blkbb, DB_RING_IGN, NULL); + set_cur(&typtab[TYP_INODE], XFS_AGB_TO_DADDR(mp, agno, cluster_agbno), + numblks, DB_RING_IGN, NULL); off_cur(offset << mp->m_sb.sb_inodelog, mp->m_sb.sb_inodesize); dip = iocur_top->data; + iocur_top->ino_crc_ok = libxfs_dinode_verify(mp, ino, dip); + iocur_top->ino_buf = 1; iocur_top->ino = ino; iocur_top->mode = be16_to_cpu(dip->di_mode); if ((iocur_top->mode & S_IFMT) == S_IFDIR) diff -Nru xfsprogs-3.1.9ubuntu2/db/inode.h xfsprogs-3.2.1ubuntu1/db/inode.h --- xfsprogs-3.1.9ubuntu2/db/inode.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/inode.h 2013-10-10 21:07:17.000000000 +0000 @@ -18,8 +18,11 @@ extern const struct field inode_a_flds[]; extern const struct field inode_core_flds[]; +extern const struct field inode_v3_flds[]; extern const struct field inode_flds[]; +extern const struct field inode_crc_flds[]; extern const struct field inode_hfld[]; +extern const struct field inode_crc_hfld[]; extern const struct field inode_u_flds[]; extern const struct field timestamp_flds[]; diff -Nru xfsprogs-3.1.9ubuntu2/db/io.c xfsprogs-3.2.1ubuntu1/db/io.c --- xfsprogs-3.1.9ubuntu2/db/io.c 2009-02-17 01:14:58.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/io.c 2014-05-02 00:09:15.000000000 +0000 @@ -104,8 +104,14 @@ dbprintf(_("can't pop anything from I/O stack\n")); return; } - if (iocur_top->buf) - xfree(iocur_top->buf); + if (iocur_top->bp) { + libxfs_putbuf(iocur_top->bp); + iocur_top->bp = NULL; + } + if (iocur_top->bbmap) { + free(iocur_top->bbmap); + iocur_top->bbmap = NULL; + } if (--iocur_sp >= 0) { iocur_top = iocur_base + iocur_sp; cur_typ = iocur_top->typ; @@ -147,10 +153,11 @@ dbprintf(_("\tbuffer block %lld (fsbno %lld), %d bb%s\n"), ioc->bb, (xfs_dfsbno_t)XFS_DADDR_TO_FSB(mp, ioc->bb), ioc->blen, ioc->blen == 1 ? "" : "s"); - if (ioc->use_bbmap) { + if (ioc->bbmap) { dbprintf(_("\tblock map")); - for (i = 0; i < ioc->blen; i++) - dbprintf(" %d:%lld", i, ioc->bbmap.b[i]); + for (i = 0; i < ioc->bbmap->nmaps; i++) + dbprintf(" %lld:%d", ioc->bbmap->b[i].bm_bn, + ioc->bbmap->b[i].bm_len); dbprintf("\n"); } dbprintf(_("\tinode %lld, dir inode %lld, type %s\n"), ioc->ino, @@ -238,7 +245,7 @@ else set_cur(iocur_top[-1].typ, iocur_top[-1].bb, iocur_top[-1].blen, DB_RING_IGN, - iocur_top[-1].use_bbmap ? &iocur_top[-1].bbmap : NULL); + iocur_top[-1].bbmap); /* run requested command */ if (argc>1) @@ -280,8 +287,7 @@ iocur_ring[ring_current].bb, iocur_ring[ring_current].blen, DB_RING_IGN, - iocur_ring[ring_current].use_bbmap ? - &iocur_ring[ring_current].bbmap : NULL); + iocur_ring[ring_current].bbmap); return 0; } @@ -321,8 +327,7 @@ iocur_ring[ring_current].bb, iocur_ring[ring_current].blen, DB_RING_IGN, - iocur_ring[ring_current].use_bbmap ? - &iocur_ring[ring_current].bbmap : NULL); + iocur_ring[ring_current].bbmap); return 0; } @@ -353,8 +358,10 @@ } index = (int)strtoul(argv[1], NULL, 0); - if (index < 0 || index >= RING_ENTRIES) + if (index < 0 || index >= RING_ENTRIES) { dbprintf(_("invalid entry: %d\n"), index); + return 0; + } ring_current = index; @@ -362,7 +369,7 @@ iocur_ring[index].bb, iocur_ring[index].blen, DB_RING_IGN, - iocur_ring[index].use_bbmap ? &iocur_ring[index].bbmap : NULL); + iocur_ring[index].bbmap); return 0; } @@ -417,119 +424,55 @@ } } - -int -write_bbs( - __int64_t bbno, - int count, - void *bufp, - bbmap_t *bbmap) +static void +write_cur_buf(void) { - int c; - int i; - int j; - int rval = EINVAL; /* initialize for zero `count' case */ - - for (j = 0; j < count; j += bbmap ? 1 : count) { - if (bbmap) - bbno = bbmap->b[j]; - if (lseek64(x.dfd, bbno << BBSHIFT, SEEK_SET) < 0) { - rval = errno; - dbprintf(_("can't seek in filesystem at bb %lld\n"), bbno); - return rval; - } - c = BBTOB(bbmap ? 1 : count); - i = (int)write(x.dfd, (char *)bufp + BBTOB(j), c); - if (i < 0) { - rval = errno; - } else if (i < c) { - rval = -1; - } else - rval = 0; - if (rval) - break; - } - return rval; + int ret; + + ret = libxfs_writebufr(iocur_top->bp); + if (ret != 0) + dbprintf(_("write error: %s\n"), strerror(ret)); + + /* re-read buffer from disk */ + ret = libxfs_readbufr(mp->m_ddev_targp, iocur_top->bb, iocur_top->bp, + iocur_top->blen, 0); + if (ret != 0) + dbprintf(_("read error: %s\n"), strerror(ret)); } -int -read_bbs( - __int64_t bbno, - int count, - void **bufp, - bbmap_t *bbmap) +static void +write_cur_bbs(void) { - void *buf; - int c; - int i; - int j; - int rval = EINVAL; - - if (count <= 0) - count = 1; - - c = BBTOB(count); - if (*bufp == NULL) - buf = xmalloc(c); - else - buf = *bufp; - for (j = 0; j < count; j += bbmap ? 1 : count) { - if (bbmap) - bbno = bbmap->b[j]; - if (lseek64(x.dfd, bbno << BBSHIFT, SEEK_SET) < 0) { - rval = errno; - dbprintf(_("can't seek in filesystem at bb %lld\n"), bbno); - if (*bufp == NULL) - xfree(buf); - buf = NULL; - } else { - c = BBTOB(bbmap ? 1 : count); - i = (int)read(x.dfd, (char *)buf + BBTOB(j), c); - if (i < 0) { - rval = errno; - if (*bufp == NULL) - xfree(buf); - buf = NULL; - } else if (i < c) { - rval = -1; - if (*bufp == NULL) - xfree(buf); - buf = NULL; - } else - rval = 0; - } - if (buf == NULL) - break; - } - if (*bufp == NULL) - *bufp = buf; - return rval; + int ret; + + ret = libxfs_writebufr(iocur_top->bp); + if (ret != 0) + dbprintf(_("write error: %s\n"), strerror(ret)); + + + /* re-read buffer from disk */ + ret = libxfs_readbufr_map(mp->m_ddev_targp, iocur_top->bp, 0); + if (ret != 0) + dbprintf(_("read error: %s\n"), strerror(ret)); } void write_cur(void) { - int ret; - if (iocur_sp < 0) { dbprintf(_("nothing to write\n")); return; } - ret = write_bbs(iocur_top->bb, iocur_top->blen, iocur_top->buf, - iocur_top->use_bbmap ? &iocur_top->bbmap : NULL); - if (ret == -1) - dbprintf(_("incomplete write, block: %lld\n"), - (iocur_base + iocur_sp)->bb); - else if (ret != 0) - dbprintf(_("write error: %s\n"), strerror(ret)); - /* re-read buffer from disk */ - ret = read_bbs(iocur_top->bb, iocur_top->blen, &iocur_top->buf, - iocur_top->use_bbmap ? &iocur_top->bbmap : NULL); - if (ret == -1) - dbprintf(_("incomplete read, block: %lld\n"), - (iocur_base + iocur_sp)->bb); - else if (ret != 0) - dbprintf(_("read error: %s\n"), strerror(ret)); + + if (iocur_top->ino_buf) + libxfs_dinode_calc_crc(mp, iocur_top->data); + if (iocur_top->dquot_buf) + xfs_update_cksum(iocur_top->data, sizeof(struct xfs_dqblk), + XFS_DQUOT_CRC_OFF); + if (iocur_top->bbmap) + write_cur_bbs(); + else + write_cur_buf(); } void @@ -540,26 +483,57 @@ int ring_flag, bbmap_t *bbmap) { + struct xfs_buf *bp; xfs_ino_t dirino; xfs_ino_t ino; __uint16_t mode; + const struct xfs_buf_ops *ops = t ? t->bops : NULL; if (iocur_sp < 0) { dbprintf(_("set_cur no stack element to set\n")); return; } -#ifdef DEBUG - if (bbmap) - printf(_("xfs_db got a bbmap for %lld\n"), (long long)d); -#endif + ino = iocur_top->ino; dirino = iocur_top->dirino; mode = iocur_top->mode; pop_cur(); push_cur(); - if (read_bbs(d, c, &iocur_top->buf, bbmap)) + + if (bbmap) { +#ifdef DEBUG_BBMAP + int i; + printf(_("xfs_db got a bbmap for %lld\n"), (long long)d); + printf(_("\tblock map")); + for (i = 0; i < bbmap->nmaps; i++) + printf(" %lld:%d", (long long)bbmap->b[i].bm_bn, + bbmap->b[i].bm_len); + printf("\n"); +#endif + iocur_top->bbmap = malloc(sizeof(struct bbmap)); + if (!iocur_top->bbmap) + return; + memcpy(iocur_top->bbmap, bbmap, sizeof(struct bbmap)); + bp = libxfs_readbuf_map(mp->m_ddev_targp, bbmap->b, + bbmap->nmaps, 0, ops); + } else { + bp = libxfs_readbuf(mp->m_ddev_targp, d, c, 0, ops); + iocur_top->bbmap = NULL; + } + + /* + * Keep the buffer even if the verifier says it is corrupted. + * We're a diagnostic tool, after all. + */ + if (!bp || (bp->b_error && bp->b_error != EFSCORRUPTED && + bp->b_error != EFSBADCRC)) return; + iocur_top->buf = bp->b_addr; + iocur_top->bp = bp; + if (!ops) + bp->b_flags |= LIBXFS_B_UNCHECKED; + iocur_top->bb = d; iocur_top->blen = c; iocur_top->boff = 0; @@ -570,14 +544,38 @@ iocur_top->ino = ino; iocur_top->dirino = dirino; iocur_top->mode = mode; - if ((iocur_top->use_bbmap = (bbmap != NULL))) - iocur_top->bbmap = *bbmap; + iocur_top->ino_buf = 0; + iocur_top->dquot_buf = 0; /* store location in ring */ if (ring_flag) ring_add(); } +void +set_iocur_type( + const typ_t *t) +{ + struct xfs_buf *bp = iocur_top->bp; + + iocur_top->typ = t; + + /* verify the buffer if the type has one. */ + if (!bp) + return; + if (!t->bops) { + bp->b_ops = NULL; + bp->b_flags |= LIBXFS_B_UNCHECKED; + return; + } + if (!(bp->b_flags & LIBXFS_B_UPTODATE)) + return; + bp->b_error = 0; + bp->b_ops = t->bops; + bp->b_ops->verify_read(bp); + bp->b_flags &= ~LIBXFS_B_UNCHECKED; +} + static void stack_help(void) { diff -Nru xfsprogs-3.1.9ubuntu2/db/io.h xfsprogs-3.2.1ubuntu1/db/io.h --- xfsprogs-3.1.9ubuntu2/db/io.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/io.h 2014-05-02 00:09:15.000000000 +0000 @@ -20,7 +20,8 @@ #define BBMAP_SIZE (XFS_MAX_BLOCKSIZE / BBSIZE) typedef struct bbmap { - __int64_t b[BBMAP_SIZE]; + int nmaps; + struct xfs_buf_map b[BBMAP_SIZE]; } bbmap_t; typedef struct iocur { @@ -35,8 +36,12 @@ __uint16_t mode; /* current inode's mode */ xfs_off_t off; /* fs offset of "data" in bytes */ const struct typ *typ; /* type of "data" */ - int use_bbmap; /* set if bbmap is valid */ - bbmap_t bbmap; /* map daddr if fragmented */ + bbmap_t *bbmap; /* map daddr if fragmented */ + struct xfs_buf *bp; /* underlying buffer */ + int ino_crc_ok:1; + int ino_buf:1; + int dquot_buf:1; + int need_crc:1; } iocur_t; #define DB_RING_ADD 1 /* add to ring on set_cur */ @@ -52,11 +57,23 @@ extern void pop_cur(void); extern void print_iocur(char *tag, iocur_t *ioc); extern void push_cur(void); -extern int read_bbs(__int64_t daddr, int count, void **bufp, - bbmap_t *bbmap); -extern int write_bbs(__int64_t daddr, int count, void *bufp, - bbmap_t *bbmap); +extern int read_buf(__int64_t daddr, int count, void *bufp); extern void write_cur(void); extern void set_cur(const struct typ *t, __int64_t d, int c, int ring_add, bbmap_t *bbmap); extern void ring_add(void); +extern void set_iocur_type(const struct typ *t); + +/* + * returns -1 for unchecked, 0 for bad and 1 for good + */ +static inline int +iocur_crc_valid() +{ + if (!iocur_top->bp) + return -1; + if (iocur_top->bp->b_flags & LIBXFS_B_UNCHECKED) + return -1; + return (iocur_top->bp->b_error != EFSBADCRC && + (!iocur_top->ino_buf || iocur_top->ino_crc_ok)); +} diff -Nru xfsprogs-3.1.9ubuntu2/db/Makefile xfsprogs-3.2.1ubuntu1/db/Makefile --- xfsprogs-3.1.9ubuntu2/db/Makefile 2010-01-28 09:49:03.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/Makefile 2014-06-19 22:42:17.000000000 +0000 @@ -9,12 +9,12 @@ HFILES = addr.h agf.h agfl.h agi.h attr.h attrshort.h bit.h block.h bmap.h \ btblock.h bmroot.h check.h command.h convert.h debug.h \ - dir.h dir2.h dir2sf.h dirshort.h dquot.h echo.h faddr.h field.h \ + dir2.h dir2sf.h dquot.h echo.h faddr.h field.h \ flist.h fprint.h frag.h freesp.h hash.h help.h init.h inode.h input.h \ io.h malloc.h metadump.h output.h print.h quit.h sb.h sig.h strvec.h \ - text.h type.h write.h attrset.h + text.h type.h write.h attrset.h symlink.h CFILES = $(HFILES:.h=.c) -LSRCFILES = xfs_admin.sh xfs_check.sh xfs_ncheck.sh xfs_metadump.sh +LSRCFILES = xfs_admin.sh xfs_ncheck.sh xfs_metadump.sh LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG) @@ -38,7 +38,6 @@ $(INSTALL) -m 755 -d $(PKG_SBIN_DIR) $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR) $(INSTALL) -m 755 xfs_admin.sh $(PKG_SBIN_DIR)/xfs_admin - $(INSTALL) -m 755 xfs_check.sh $(PKG_SBIN_DIR)/xfs_check $(INSTALL) -m 755 xfs_ncheck.sh $(PKG_SBIN_DIR)/xfs_ncheck $(INSTALL) -m 755 xfs_metadump.sh $(PKG_SBIN_DIR)/xfs_metadump install-dev: diff -Nru xfsprogs-3.1.9ubuntu2/db/metadump.c xfsprogs-3.2.1ubuntu1/db/metadump.c --- xfsprogs-3.1.9ubuntu2/db/metadump.c 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/metadump.c 2014-06-19 22:42:17.000000000 +0000 @@ -26,6 +26,10 @@ #include "init.h" #include "sig.h" #include "xfs_metadump.h" +#include "fprint.h" +#include "faddr.h" +#include "field.h" +#include "dir2.h" #define DEFAULT_MAX_EXT_SIZE 1000 @@ -141,6 +145,8 @@ * even if the dump is exactly aligned, the last index will be full of * zeros. If the last index entry is non-zero, the dump is incomplete. * Correspondingly, the last chunk will have a count < num_indicies. + * + * Return 0 for success, -1 for failure. */ static int @@ -152,33 +158,88 @@ metablock->mb_count = cpu_to_be16(cur_index); if (fwrite(metablock, (cur_index + 1) << BBSHIFT, 1, outf) != 1) { print_warning("error writing to file: %s", strerror(errno)); - return 0; + return -errno; } memset(block_index, 0, num_indicies * sizeof(__be64)); cur_index = 0; - return 1; + return 0; } +/* + * Return 0 for success, -errno for failure. + */ static int -write_buf( - iocur_t *buf) +write_buf_segment( + char *data, + __int64_t off, + int len) { - char *data; - __int64_t off; int i; + int ret; - for (i = 0, off = buf->bb, data = buf->data; - i < buf->blen; - i++, off++, data += BBSIZE) { + for (i = 0; i < len; i++, off++, data += BBSIZE) { block_index[cur_index] = cpu_to_be64(off); memcpy(&block_buffer[cur_index << BBSHIFT], data, BBSIZE); if (++cur_index == num_indicies) { - if (!write_index()) - return 0; + ret = write_index(); + if (ret) + return -EIO; } } - return !seenint(); + return 0; +} + +/* + * we want to preserve the state of the metadata in the dump - whether it is + * intact or corrupt, so even if the buffer has a verifier attached to it we + * don't want to run it prior to writing the buffer to the metadump image. + * + * The only reason for running the verifier is to recalculate the CRCs on a + * buffer that has been obfuscated. i.e. a buffer than metadump modified itself. + * In this case, we only run the verifier if the buffer was not corrupt to begin + * with so that we don't accidentally correct buffers with CRC or errors in them + * when we are obfuscating them. + */ +static int +write_buf( + iocur_t *buf) +{ + struct xfs_buf *bp = buf->bp; + int i; + int ret; + + /* + * Run the write verifier to recalculate the buffer CRCs and check + * metadump didn't introduce a new corruption. Warn if the verifier + * failed, but still continue to dump it into the output file. + */ + if (buf->need_crc && bp && bp->b_ops && !bp->b_error) { + bp->b_ops->verify_write(bp); + if (bp->b_error) { + print_warning( + "obfuscation corrupted block at bno 0x%llx/0x%x", + (long long)bp->b_bn, bp->b_bcount); + } + } + + /* handle discontiguous buffers */ + if (!buf->bbmap) { + ret = write_buf_segment(buf->data, buf->bb, buf->blen); + if (ret) + return ret; + } else { + int len = 0; + for (i = 0; i < buf->bbmap->nmaps; i++) { + ret = write_buf_segment(buf->data + BBTOB(len), + buf->bbmap->b[i].bm_bn, + buf->bbmap->b[i].bm_len); + if (ret) + return ret; + len += buf->bbmap->b[i].bm_len; + } + } + return seenint() ? -EINTR : 0; } @@ -207,7 +268,7 @@ rval = !stop_on_read_error; goto pop_out; } - if (!write_buf(iocur_top)) + if (write_buf(iocur_top)) goto pop_out; if (!(*func)(iocur_top->data, agno, agbno, level - 1, btype, arg)) @@ -902,12 +963,12 @@ obfuscate_sf_dir( xfs_dinode_t *dip) { - xfs_dir2_sf_t *sfp; + struct xfs_dir2_sf_hdr *sfp; xfs_dir2_sf_entry_t *sfep; __uint64_t ino_dir_size; int i; - sfp = (xfs_dir2_sf_t *)XFS_DFORK_DPTR(dip); + sfp = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip); ino_dir_size = be64_to_cpu(dip->di_size); if (ino_dir_size > XFS_DFORK_DSIZE(dip, mp)) { ino_dir_size = XFS_DFORK_DSIZE(dip, mp); @@ -917,7 +978,7 @@ } sfep = xfs_dir2_sf_firstentry(sfp); - for (i = 0; (i < sfp->hdr.count) && + for (i = 0; (i < sfp->count) && ((char *)sfep - (char *)sfp < ino_dir_size); i++) { /* @@ -930,28 +991,70 @@ if (show_warnings) print_warning("zero length entry in dir inode " "%llu", (long long)cur_ino); - if (i != sfp->hdr.count - 1) + if (i != sfp->count - 1) break; namelen = ino_dir_size - ((char *)&sfep->name[0] - (char *)sfp); } else if ((char *)sfep - (char *)sfp + - xfs_dir2_sf_entsize_byentry(sfp, sfep) > + xfs_dir3_sf_entsize(mp, sfp, sfep->namelen) > ino_dir_size) { if (show_warnings) print_warning("entry length in dir inode %llu " "overflows space", (long long)cur_ino); - if (i != sfp->hdr.count - 1) + if (i != sfp->count - 1) break; namelen = ino_dir_size - ((char *)&sfep->name[0] - (char *)sfp); } - generate_obfuscated_name(xfs_dir2_sf_get_inumber(sfp, - xfs_dir2_sf_inumberp(sfep)), namelen, - &sfep->name[0]); + generate_obfuscated_name(xfs_dir3_sfe_get_ino(mp, sfp, sfep), + namelen, &sfep->name[0]); sfep = (xfs_dir2_sf_entry_t *)((char *)sfep + - xfs_dir2_sf_entsize_byname(sfp, namelen)); + xfs_dir3_sf_entsize(mp, sfp, namelen)); + } +} + +/* + * The pathname may not be null terminated. It may be terminated by the end of + * a buffer or inode literal area, and the start of the next region contains + * unknown data. Therefore, when we get to the last component of the symlink, we + * cannot assume that strlen() will give us the right result. Hence we need to + * track the remaining pathname length and use that instead. + */ +static void +obfuscate_path_components( + char *buf, + __uint64_t len) +{ + uchar_t *comp = (uchar_t *)buf; + uchar_t *end = comp + len; + xfs_dahash_t hash; + + while (comp < end) { + char *slash; + int namelen; + + /* find slash at end of this component */ + slash = strchr((char *)comp, '/'); + if (!slash) { + /* last (or single) component */ + namelen = strnlen((char *)comp, len); + hash = libxfs_da_hashname(comp, namelen); + obfuscate_name(hash, namelen, comp); + break; + } + namelen = slash - (char *)comp; + /* handle leading or consecutive slashes */ + if (!namelen) { + comp++; + len--; + continue; + } + hash = libxfs_da_hashname(comp, namelen); + obfuscate_name(hash, namelen, comp); + comp += namelen + 1; + len -= namelen + 1; } } @@ -971,8 +1074,7 @@ } buf = (char *)XFS_DFORK_DPTR(dip); - while (len > 0) - buf[--len] = random() % 127 + 1; + obfuscate_path_components(buf, len); } static void @@ -1028,24 +1130,11 @@ } } -/* - * dir_data structure is used to track multi-fsblock dir2 blocks between extent - * processing calls. - */ - -static struct dir_data_s { - int end_of_data; - int block_index; - int offset_to_entry; - int bad_block; -} dir_data; - static void -obfuscate_dir_data_blocks( - char *block, - xfs_dfiloff_t offset, - xfs_dfilblks_t count, - int is_block_format) +obfuscate_dir_data_block( + char *block, + xfs_dfiloff_t offset, + int is_block_format) { /* * we have to rely on the fileoffset and signature of the block to @@ -1053,134 +1142,105 @@ * for multi-fsblock dir blocks, if a name crosses an extent boundary, * ignore it and continue. */ - int c; - int dir_offset; - char *ptr; - char *endptr; - - if (is_block_format && count != mp->m_dirblkfsbs) - return; /* too complex to handle this rare case */ - - for (c = 0, endptr = block; c < count; c++) { - - if (dir_data.block_index == 0) { - int wantmagic; - - if (offset % mp->m_dirblkfsbs != 0) - return; /* corrupted, leave it alone */ - - dir_data.bad_block = 0; - - if (is_block_format) { - xfs_dir2_leaf_entry_t *blp; - xfs_dir2_block_tail_t *btp; - - btp = xfs_dir2_block_tail_p(mp, - (xfs_dir2_block_t *)block); - blp = xfs_dir2_block_leaf_p(btp); - if ((char *)blp > (char *)btp) - blp = (xfs_dir2_leaf_entry_t *)btp; - - dir_data.end_of_data = (char *)blp - block; - wantmagic = XFS_DIR2_BLOCK_MAGIC; - } else { /* leaf/node format */ - dir_data.end_of_data = mp->m_dirblkfsbs << - mp->m_sb.sb_blocklog; - wantmagic = XFS_DIR2_DATA_MAGIC; - } - dir_data.offset_to_entry = offsetof(xfs_dir2_data_t, u); - - if (be32_to_cpu(((xfs_dir2_data_hdr_t*)block)->magic) != - wantmagic) { - if (show_warnings) - print_warning("invalid magic in dir " - "inode %llu block %ld", - (long long)cur_ino, - (long)offset); - dir_data.bad_block = 1; - } - } - dir_data.block_index++; - if (dir_data.block_index == mp->m_dirblkfsbs) - dir_data.block_index = 0; - - if (dir_data.bad_block) - continue; - - dir_offset = (dir_data.block_index << mp->m_sb.sb_blocklog) + - dir_data.offset_to_entry; - - ptr = endptr + dir_data.offset_to_entry; - endptr += mp->m_sb.sb_blocksize; - - while (ptr < endptr && dir_offset < dir_data.end_of_data) { - xfs_dir2_data_entry_t *dep; - xfs_dir2_data_unused_t *dup; - int length; - - dup = (xfs_dir2_data_unused_t *)ptr; - - if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { - int length = be16_to_cpu(dup->length); - if (dir_offset + length > dir_data.end_of_data || - length == 0 || (length & - (XFS_DIR2_DATA_ALIGN - 1))) { - if (show_warnings) - print_warning("invalid length " - "for dir free space in " - "inode %llu", - (long long)cur_ino); - dir_data.bad_block = 1; - break; - } - if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) != - dir_offset) { - dir_data.bad_block = 1; - break; - } - dir_offset += length; - ptr += length; - if (dir_offset >= dir_data.end_of_data || - ptr >= endptr) - break; - } + int dir_offset; + char *ptr; + char *endptr; + int end_of_data; + int wantmagic; + struct xfs_dir2_data_hdr *datahdr; + + datahdr = (struct xfs_dir2_data_hdr *)block; + + if (offset % mp->m_dirblkfsbs != 0) + return; /* corrupted, leave it alone */ + + if (is_block_format) { + xfs_dir2_leaf_entry_t *blp; + xfs_dir2_block_tail_t *btp; + + btp = xfs_dir2_block_tail_p(mp, datahdr); + blp = xfs_dir2_block_leaf_p(btp); + if ((char *)blp > (char *)btp) + blp = (xfs_dir2_leaf_entry_t *)btp; + + end_of_data = (char *)blp - block; + if (xfs_sb_version_hascrc(&mp->m_sb)) + wantmagic = XFS_DIR3_BLOCK_MAGIC; + else + wantmagic = XFS_DIR2_BLOCK_MAGIC; + } else { /* leaf/node format */ + end_of_data = mp->m_dirblkfsbs << mp->m_sb.sb_blocklog; + if (xfs_sb_version_hascrc(&mp->m_sb)) + wantmagic = XFS_DIR3_DATA_MAGIC; + else + wantmagic = XFS_DIR2_DATA_MAGIC; + } - dep = (xfs_dir2_data_entry_t *)ptr; - length = xfs_dir2_data_entsize(dep->namelen); + if (be32_to_cpu(datahdr->magic) != wantmagic) { + if (show_warnings) + print_warning( + "invalid magic in dir inode %llu block %ld", + (long long)cur_ino, (long)offset); + return; + } - if (dir_offset + length > dir_data.end_of_data || - ptr + length > endptr) { + dir_offset = xfs_dir3_data_entry_offset(datahdr); + ptr = block + dir_offset; + endptr = block + mp->m_sb.sb_blocksize; + + while (ptr < endptr && dir_offset < end_of_data) { + xfs_dir2_data_entry_t *dep; + xfs_dir2_data_unused_t *dup; + int length; + + dup = (xfs_dir2_data_unused_t *)ptr; + + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { + int length = be16_to_cpu(dup->length); + if (dir_offset + length > end_of_data || + !length || (length & (XFS_DIR2_DATA_ALIGN - 1))) { if (show_warnings) - print_warning("invalid length for " - "dir entry name in inode %llu", + print_warning( + "invalid length for dir free space in inode %llu", (long long)cur_ino); - break; + return; } - if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) != - dir_offset) { - dir_data.bad_block = 1; - break; - } - generate_obfuscated_name(be64_to_cpu(dep->inumber), - dep->namelen, &dep->name[0]); + if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) != + dir_offset) + return; dir_offset += length; ptr += length; + if (dir_offset >= end_of_data || ptr >= endptr) + return; + } + + dep = (xfs_dir2_data_entry_t *)ptr; + length = xfs_dir3_data_entsize(mp, dep->namelen); + + if (dir_offset + length > end_of_data || + ptr + length > endptr) { + if (show_warnings) + print_warning( + "invalid length for dir entry name in inode %llu", + (long long)cur_ino); + return; } - dir_data.offset_to_entry = dir_offset & - (mp->m_sb.sb_blocksize - 1); + if (be16_to_cpu(*xfs_dir3_data_entry_tag_p(mp, dep)) != + dir_offset) + return; + generate_obfuscated_name(be64_to_cpu(dep->inumber), + dep->namelen, &dep->name[0]); + dir_offset += length; + ptr += length; } } static void -obfuscate_symlink_blocks( - char *block, - xfs_dfilblks_t count) +obfuscate_symlink_block( + char *block) { - int i; - - count <<= mp->m_sb.sb_blocklog; - for (i = 0; i < count; i++) - block[i] = random() % 127 + 1; + /* XXX: need to handle CRC headers */ + obfuscate_path_components(block, mp->m_sb.sb_blocksize); } #define MAX_REMOTE_VALS 4095 @@ -1201,86 +1261,227 @@ blockidx++; length -= XFS_LBSIZE(mp); } + + if (attr_data.remote_val_count >= MAX_REMOTE_VALS) { + print_warning( +"Overflowed attr obfuscation array. No longer obfuscating remote attrs."); + } } static void -obfuscate_attr_blocks( +obfuscate_attr_block( char *block, - xfs_dfiloff_t offset, - xfs_dfilblks_t count) + xfs_dfiloff_t offset) { xfs_attr_leafblock_t *leaf; - int c; int i; int nentries; xfs_attr_leaf_entry_t *entry; xfs_attr_leaf_name_local_t *local; xfs_attr_leaf_name_remote_t *remote; - for (c = 0; c < count; c++, offset++, block += XFS_LBSIZE(mp)) { - - leaf = (xfs_attr_leafblock_t *)block; + leaf = (xfs_attr_leafblock_t *)block; - if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) { - for (i = 0; i < attr_data.remote_val_count; i++) { - if (attr_data.remote_vals[i] == offset) - memset(block, 0, XFS_LBSIZE(mp)); - } - continue; + if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) { + for (i = 0; i < attr_data.remote_val_count; i++) { + /* XXX: need to handle CRC headers */ + if (attr_data.remote_vals[i] == offset) + memset(block, 0, XFS_LBSIZE(mp)); } + return; + } - nentries = be16_to_cpu(leaf->hdr.count); - if (nentries * sizeof(xfs_attr_leaf_entry_t) + - sizeof(xfs_attr_leaf_hdr_t) > XFS_LBSIZE(mp)) { + nentries = be16_to_cpu(leaf->hdr.count); + if (nentries * sizeof(xfs_attr_leaf_entry_t) + + sizeof(xfs_attr_leaf_hdr_t) > XFS_LBSIZE(mp)) { + if (show_warnings) + print_warning("invalid attr count in inode %llu", + (long long)cur_ino); + return; + } + + for (i = 0, entry = &leaf->entries[0]; i < nentries; i++, entry++) { + if (be16_to_cpu(entry->nameidx) > XFS_LBSIZE(mp)) { if (show_warnings) - print_warning("invalid attr count in inode %llu", + print_warning( + "invalid attr nameidx in inode %llu", (long long)cur_ino); - continue; + break; } - - for (i = 0, entry = &leaf->entries[0]; i < nentries; - i++, entry++) { - if (be16_to_cpu(entry->nameidx) > XFS_LBSIZE(mp)) { + if (entry->flags & XFS_ATTR_LOCAL) { + local = xfs_attr3_leaf_name_local(leaf, i); + if (local->namelen == 0) { + if (show_warnings) + print_warning( + "zero length for attr name in inode %llu", + (long long)cur_ino); + break; + } + generate_obfuscated_name(0, local->namelen, + &local->nameval[0]); + memset(&local->nameval[local->namelen], 0, + be16_to_cpu(local->valuelen)); + } else { + remote = xfs_attr3_leaf_name_remote(leaf, i); + if (remote->namelen == 0 || remote->valueblk == 0) { if (show_warnings) - print_warning("invalid attr nameidx " - "in inode %llu", - (long long)cur_ino); + print_warning( + "invalid attr entry in inode %llu", + (long long)cur_ino); break; } - if (entry->flags & XFS_ATTR_LOCAL) { - local = xfs_attr_leaf_name_local(leaf, i); - if (local->namelen == 0) { - if (show_warnings) - print_warning("zero length for " - "attr name in inode %llu", - (long long)cur_ino); - break; - } - generate_obfuscated_name(0, local->namelen, - &local->nameval[0]); - memset(&local->nameval[local->namelen], 0, - be16_to_cpu(local->valuelen)); - } else { - remote = xfs_attr_leaf_name_remote(leaf, i); - if (remote->namelen == 0 || - remote->valueblk == 0) { - if (show_warnings) - print_warning("invalid attr " - "entry in inode %llu", - (long long)cur_ino); - break; - } - generate_obfuscated_name(0, remote->namelen, - &remote->name[0]); - add_remote_vals(be32_to_cpu(remote->valueblk), + generate_obfuscated_name(0, remote->namelen, + &remote->name[0]); + add_remote_vals(be32_to_cpu(remote->valueblk), be32_to_cpu(remote->valuelen)); + } + } +} + +static int +process_single_fsb_objects( + xfs_dfiloff_t o, + xfs_dfsbno_t s, + xfs_dfilblks_t c, + typnm_t btype, + xfs_dfiloff_t last) +{ + char *dp; + int ret = 0; + int i; + + for (i = 0; i < c; i++) { + push_cur(); + set_cur(&typtab[btype], XFS_FSB_TO_DADDR(mp, s), blkbb, + DB_RING_IGN, NULL); + + if (!iocur_top->data) { + xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, s); + xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, s); + + print_warning("cannot read %s block %u/%u (%llu)", + typtab[btype].name, agno, agbno, s); + if (stop_on_read_error) + ret = -EIO; + goto out_pop; + + } + + if (dont_obfuscate) + goto write; + + dp = iocur_top->data; + switch (btype) { + case TYP_DIR2: + if (o >= mp->m_dirleafblk) + break; + + obfuscate_dir_data_block(dp, o, + last == mp->m_dirblkfsbs); + iocur_top->need_crc = 1; + break; + case TYP_SYMLINK: + obfuscate_symlink_block(dp); + iocur_top->need_crc = 1; + break; + case TYP_ATTR: + obfuscate_attr_block(dp, o); + iocur_top->need_crc = 1; + break; + default: + break; + } + +write: + ret = write_buf(iocur_top); +out_pop: + pop_cur(); + if (ret) + break; + o++; + s++; + } + + return ret; +} + +/* + * Static map to aggregate multiple extents into a single directory block. + */ +static struct bbmap mfsb_map; +static int mfsb_length; + +static int +process_multi_fsb_objects( + xfs_dfiloff_t o, + xfs_dfsbno_t s, + xfs_dfilblks_t c, + typnm_t btype, + xfs_dfiloff_t last) +{ + int ret = 0; + + switch (btype) { + case TYP_DIR2: + break; + default: + print_warning("bad type for multi-fsb object %d", btype); + return -EINVAL; + } + + while (c > 0) { + unsigned int bm_len; + + if (mfsb_length + c >= mp->m_dirblkfsbs) { + bm_len = mp->m_dirblkfsbs - mfsb_length; + mfsb_length = 0; + } else { + mfsb_length += c; + bm_len = c; + } + + mfsb_map.b[mfsb_map.nmaps].bm_bn = XFS_FSB_TO_DADDR(mp, s); + mfsb_map.b[mfsb_map.nmaps].bm_len = XFS_FSB_TO_BB(mp, bm_len); + mfsb_map.nmaps++; + + if (mfsb_length == 0) { + push_cur(); + set_cur(&typtab[btype], 0, 0, DB_RING_IGN, &mfsb_map); + if (!iocur_top->data) { + xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, s); + xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, s); + + print_warning("cannot read %s block %u/%u (%llu)", + typtab[btype].name, agno, agbno, s); + if (stop_on_read_error) + ret = -1; + goto out_pop; + + } + + if (dont_obfuscate || o >= mp->m_dirleafblk) { + ret = write_buf(iocur_top); + goto out_pop; } + + obfuscate_dir_data_block(iocur_top->data, o, + last == mp->m_dirblkfsbs); + iocur_top->need_crc = 1; + ret = write_buf(iocur_top); +out_pop: + pop_cur(); + mfsb_map.nmaps = 0; + if (ret) + break; } + c -= bm_len; + s += bm_len; } + + return ret; } /* inode copy routines */ - static int process_bmbt_reclist( xfs_bmbt_rec_t *rp, @@ -1295,6 +1496,7 @@ xfs_dfiloff_t last; xfs_agnumber_t agno; xfs_agblock_t agbno; + int error; if (btype == TYP_DATA) return 1; @@ -1356,44 +1558,14 @@ break; } - push_cur(); - set_cur(&typtab[btype], XFS_FSB_TO_DADDR(mp, s), c * blkbb, - DB_RING_IGN, NULL); - if (iocur_top->data == NULL) { - print_warning("cannot read %s block %u/%u (%llu)", - typtab[btype].name, agno, agbno, s); - if (stop_on_read_error) { - pop_cur(); - return 0; - } + /* multi-extent blocks require special handling */ + if (btype != TYP_DIR2 || mp->m_dirblkfsbs == 1) { + error = process_single_fsb_objects(o, s, c, btype, last); } else { - if (!dont_obfuscate) - switch (btype) { - case TYP_DIR2: - if (o < mp->m_dirleafblk) - obfuscate_dir_data_blocks( - iocur_top->data, o, c, - last == mp->m_dirblkfsbs); - break; - - case TYP_SYMLINK: - obfuscate_symlink_blocks( - iocur_top->data, c); - break; - - case TYP_ATTR: - obfuscate_attr_blocks(iocur_top->data, - o, c); - break; - - default: ; - } - if (!write_buf(iocur_top)) { - pop_cur(); - return 0; - } + error = process_multi_fsb_objects(o, s, c, btype, last); } - pop_cur(); + if (error) + return 0; } return 1; @@ -1575,6 +1747,13 @@ return 1; } +/* + * when we process the inode, we may change the data in the data and/or + * attribute fork if they are in short form and we are obfuscating names. + * In this case we need to recalculate the CRC of the inode, but we should + * only do that if the CRC in the inode is good to begin with. If the crc + * is not ok, we just leave it alone. + */ static int process_inode( xfs_agnumber_t agno, @@ -1582,18 +1761,30 @@ xfs_dinode_t *dip) { int success; + bool crc_was_ok = false; /* no recalc by default */ + bool need_new_crc = false; success = 1; cur_ino = XFS_AGINO_TO_INO(mp, agno, agino); + /* we only care about crc recalculation if we are obfuscating names. */ + if (!dont_obfuscate) { + crc_was_ok = xfs_verify_cksum((char *)dip, + mp->m_sb.sb_inodesize, + offsetof(struct xfs_dinode, di_crc)); + } + /* copy appropriate data fork metadata */ switch (be16_to_cpu(dip->di_mode) & S_IFMT) { case S_IFDIR: - memset(&dir_data, 0, sizeof(dir_data)); success = process_inode_data(dip, TYP_DIR2); + if (dip->di_format == XFS_DINODE_FMT_LOCAL) + need_new_crc = 1; break; case S_IFLNK: success = process_inode_data(dip, TYP_SYMLINK); + if (dip->di_format == XFS_DINODE_FMT_LOCAL) + need_new_crc = 1; break; case S_IFREG: success = process_inode_data(dip, TYP_DATA); @@ -1603,10 +1794,12 @@ nametable_clear(); /* copy extended attributes if they exist and forkoff is valid */ - if (success && XFS_DFORK_DSIZE(dip, mp) < XFS_LITINO(mp)) { + if (success && + XFS_DFORK_DSIZE(dip, mp) < XFS_LITINO(mp, dip->di_version)) { attr_data.remote_val_count = 0; switch (dip->di_aformat) { case XFS_DINODE_FMT_LOCAL: + need_new_crc = 1; if (!dont_obfuscate) obfuscate_sf_attr(dip); break; @@ -1621,6 +1814,9 @@ } nametable_clear(); } + + if (crc_was_ok && need_new_crc) + xfs_dinode_calc_crc(mp, dip); return success; } @@ -1693,7 +1889,7 @@ goto pop_out; } skip_processing: - if (!write_buf(iocur_top)) + if (write_buf(iocur_top)) goto pop_out; inodes_copied += XFS_INODES_PER_CHUNK; @@ -1721,6 +1917,7 @@ xfs_inobt_ptr_t *pp; int i; int numrecs; + int finobt = *(int *) arg; numrecs = be16_to_cpu(block->bb_numrecs); @@ -1732,6 +1929,14 @@ typtab[btype].name, agno, agbno); numrecs = mp->m_inobt_mxr[0]; } + + /* + * Only copy the btree blocks for the finobt. The inobt scan + * copies the inode chunks. + */ + if (finobt) + return 1; + rp = XFS_INOBT_REC_ADDR(mp, block, 1); for (i = 0; i < numrecs; i++, rp++) { if (!copy_inode_chunk(agno, rp)) @@ -1771,6 +1976,7 @@ { xfs_agblock_t root; int levels; + int finobt = 0; root = be32_to_cpu(agi->agi_root); levels = be32_to_cpu(agi->agi_level); @@ -1789,7 +1995,20 @@ return 1; } - return scan_btree(agno, root, levels, TYP_INOBT, agi, scanfunc_ino); + if (!scan_btree(agno, root, levels, TYP_INOBT, &finobt, scanfunc_ino)) + return 0; + + if (xfs_sb_version_hasfinobt(&mp->m_sb)) { + root = be32_to_cpu(agi->agi_free_root); + levels = be32_to_cpu(agi->agi_free_level); + + finobt = 1; + if (!scan_btree(agno, root, levels, TYP_INOBT, &finobt, + scanfunc_ino)) + return 0; + } + + return 1; } static int @@ -1811,7 +2030,7 @@ if (stop_on_read_error) goto pop_out; } else { - if (!write_buf(iocur_top)) + if (write_buf(iocur_top)) goto pop_out; } @@ -1826,7 +2045,7 @@ if (stop_on_read_error) goto pop_out; } else { - if (!write_buf(iocur_top)) + if (write_buf(iocur_top)) goto pop_out; } @@ -1841,7 +2060,7 @@ if (stop_on_read_error) goto pop_out; } else { - if (!write_buf(iocur_top)) + if (write_buf(iocur_top)) goto pop_out; } @@ -1855,7 +2074,7 @@ if (stop_on_read_error) goto pop_out; } else { - if (!write_buf(iocur_top)) + if (write_buf(iocur_top)) goto pop_out; } @@ -1940,7 +2159,10 @@ if (!copy_ino(mp->m_sb.sb_uquotino, TYP_DQBLK)) return 0; - return copy_ino(mp->m_sb.sb_gquotino, TYP_DQBLK); + if (!copy_ino(mp->m_sb.sb_gquotino, TYP_DQBLK)) + return 0; + + return copy_ino(mp->m_sb.sb_pquotino, TYP_DQBLK); } static int @@ -1957,7 +2179,7 @@ print_warning("cannot read log"); return !stop_on_read_error; } - return write_buf(iocur_top); + return !write_buf(iocur_top); } static int @@ -2063,7 +2285,7 @@ /* write the remaining index */ if (!exitcode) - exitcode = !write_index(); + exitcode = write_index() < 0; if (progress_since_warning) fputc('\n', (outf == stdout) ? stderr : stdout); diff -Nru xfsprogs-3.1.9ubuntu2/db/sb.c xfsprogs-3.2.1ubuntu1/db/sb.c --- xfsprogs-3.1.9ubuntu2/db/sb.c 2010-11-09 11:17:04.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/sb.c 2014-05-02 00:09:15.000000000 +0000 @@ -108,7 +108,19 @@ { "logsectsize", FLDT_UINT16D, OI(OFF(logsectsize)), C1, 0, TYP_NONE }, { "logsunit", FLDT_UINT32D, OI(OFF(logsunit)), C1, 0, TYP_NONE }, { "features2", FLDT_UINT32X, OI(OFF(features2)), C1, 0, TYP_NONE }, - { "bad_features2", FLDT_UINT32X, OI(OFF(bad_features2)), C1, 0, TYP_NONE }, + { "bad_features2", FLDT_UINT32X, OI(OFF(bad_features2)), + C1, 0, TYP_NONE }, + { "features_compat", FLDT_UINT32X, OI(OFF(features_compat)), + C1, 0, TYP_NONE }, + { "features_ro_compat", FLDT_UINT32X, OI(OFF(features_ro_compat)), + C1, 0, TYP_NONE }, + { "features_incompat", FLDT_UINT32X, OI(OFF(features_incompat)), + C1, 0, TYP_NONE }, + { "features_log_incompat", FLDT_UINT32X, OI(OFF(features_log_incompat)), + C1, 0, TYP_NONE }, + { "crc", FLDT_CRC, OI(OFF(crc)), C1, 0, TYP_NONE }, + { "pquotino", FLDT_INO, OI(OFF(pquotino)), C1, 0, TYP_INODE }, + { "lsn", FLDT_UINT64X, OI(OFF(lsn)), C1, 0, TYP_NONE }, { NULL } }; @@ -205,12 +217,15 @@ } /* workaround craziness in the xlog routines */ -int xlog_recover_do_trans(xlog_t *log, xlog_recover_t *t, int p) { return 0; } +int xlog_recover_do_trans(struct xlog *log, xlog_recover_t *t, int p) +{ + return 0; +} int sb_logcheck(void) { - xlog_t log; + struct xlog log; xfs_daddr_t head_blk, tail_blk; if (mp->m_sb.sb_logstart) { @@ -228,14 +243,18 @@ } memset(&log, 0, sizeof(log)); - if (!x.logdev) - x.logdev = x.ddev; + libxfs_buftarg_init(mp, x.ddev, x.logdev, x.rtdev); x.logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); x.logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart); - log.l_dev = (mp->m_sb.sb_logstart == 0) ? x.logdev : x.ddev; + x.lbsize = BBSIZE; + if (xfs_sb_version_hassector(&mp->m_sb)) + x.lbsize <<= (mp->m_sb.sb_logsectlog - BBSHIFT); + + log.l_dev = mp->m_logdev_targp; log.l_logsize = BBTOB(log.l_logBBsize); log.l_logBBsize = x.logBBsize; log.l_logBBstart = x.logBBstart; + log.l_sectBBsize = BTOBB(x.lbsize); log.l_mp = mp; if (xlog_find_tail(&log, &head_blk, &tail_blk)) { @@ -263,8 +282,7 @@ dbprintf(_("Clearing log and setting UUID\n")); - if (libxfs_log_clear( - (mp->m_sb.sb_logstart == 0) ? x.logdev : x.ddev, + if (libxfs_log_clear(mp->m_logdev_targp, XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), uuidp, @@ -591,6 +609,8 @@ strcpy(s, "V3"); else if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) strcpy(s, "V4"); + else if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) + strcpy(s, "V5"); if (xfs_sb_version_hasattr(sbp)) strcat(s, ",ATTR"); @@ -622,9 +642,19 @@ strcat(s, ",LAZYSBCOUNT"); if (xfs_sb_version_hasprojid32bit(sbp)) strcat(s, ",PROJID32BIT"); + if (xfs_sb_version_hascrc(sbp)) + strcat(s, ",CRC"); + if (xfs_sb_version_hasftype(sbp)) + strcat(s, ",FTYPE"); return s; } +/* + * XXX: this only supports reading and writing to version 4 superblock fields. + * V5 superblocks always define certain V4 feature bits - they are blocked from + * being changed if a V5 sb is detected, but otherwise v5 superblock features + * are not handled here. + */ static int version_f( int argc, @@ -656,12 +686,16 @@ break; case XFS_SB_VERSION_4: if (xfs_sb_version_hasextflgbit(&mp->m_sb)) - dbprintf(_("unwritten extents flag" - " is already enabled\n")); + dbprintf( + _("unwritten extents flag is already enabled\n")); else version = mp->m_sb.sb_versionnum | XFS_SB_VERSION_EXTFLGBIT; break; + case XFS_SB_VERSION_5: + dbprintf( + _("unwritten extents always enabled for v5 superblocks.\n")); + break; } } else if (!strcasecmp(argv[1], "log2")) { switch (XFS_SB_VERSION_NUM(&mp->m_sb)) { @@ -676,14 +710,24 @@ break; case XFS_SB_VERSION_4: if (xfs_sb_version_haslogv2(&mp->m_sb)) - dbprintf(_("version 2 log format" - " is already in use\n")); + dbprintf( + _("version 2 log format is already in use\n")); else version = mp->m_sb.sb_versionnum | XFS_SB_VERSION_LOGV2BIT; break; + case XFS_SB_VERSION_5: + dbprintf( + _("Version 2 logs always enabled for v5 superblocks.\n")); + break; } + } else if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5) { + dbprintf( + _("%s: Cannot change %s on v5 superblocks.\n"), + progname, argv[1]); + return 0; } else if (!strcasecmp(argv[1], "attr1")) { + if (xfs_sb_version_hasattr2(&mp->m_sb)) { if (!(mp->m_sb.sb_features2 &= ~XFS_SB_VERSION2_ATTR2BIT)) diff -Nru xfsprogs-3.1.9ubuntu2/db/symlink.c xfsprogs-3.2.1ubuntu1/db/symlink.c --- xfsprogs-3.1.9ubuntu2/db/symlink.c 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/symlink.c 2014-05-02 00:09:15.000000000 +0000 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "type.h" +#include "faddr.h" +#include "fprint.h" +#include "field.h" +#include "bit.h" +#include "init.h" + + +/* + * XXX: no idea how to handle multiple contiguous block symlinks here. + */ +static int +symlink_count( + void *obj, + int startoff) +{ + struct xfs_dsymlink_hdr *hdr = obj; + + ASSERT(startoff == 0); + + if (hdr->sl_magic != cpu_to_be32(XFS_SYMLINK_MAGIC)) + return 0; + if (be32_to_cpu(hdr->sl_bytes) + sizeof(*hdr) > mp->m_sb.sb_blocksize) + return mp->m_sb.sb_blocksize - sizeof(*hdr); + return be32_to_cpu(hdr->sl_bytes); +} + +int +symlink_size( + void *obj, + int startoff, + int idx) +{ + struct xfs_dsymlink_hdr *hdr = obj; + + ASSERT(startoff == 0); + if (hdr->sl_magic != cpu_to_be32(XFS_SYMLINK_MAGIC)) + return 0; + return be32_to_cpu(hdr->sl_bytes) + sizeof(*hdr); +} + +const struct field symlink_crc_hfld[] = { + { "", FLDT_SYMLINK_CRC, OI(0), C1, 0, TYP_NONE }, + { NULL } +}; + +#define OFF(f) bitize(offsetof(struct xfs_dsymlink_hdr, sl_ ## f)) +#define SZOF(f) bitize(sizeof(struct xfs_dsymlink_hdr)) +const struct field symlink_crc_flds[] = { + { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, + { "offset", FLDT_UINT32D, OI(OFF(offset)), C1, 0, TYP_NONE }, + { "bytes", FLDT_UINT32D, OI(OFF(bytes)), C1, 0, TYP_NONE }, + { "crc", FLDT_CRC, OI(OFF(crc)), C1, 0, TYP_NONE }, + { "uuid", FLDT_UUID, OI(OFF(uuid)), C1, 0, TYP_NONE }, + { "owner", FLDT_INO, OI(OFF(owner)), C1, 0, TYP_NONE }, + { "bno", FLDT_DFSBNO, OI(OFF(blkno)), C1, 0, TYP_BMAPBTD }, + { "lsn", FLDT_UINT64X, OI(OFF(lsn)), C1, 0, TYP_NONE }, + { "data", FLDT_CHARNS, OI(bitize(sizeof(struct xfs_dsymlink_hdr))), + symlink_count, FLD_COUNT, TYP_NONE }, + { NULL } +}; + diff -Nru xfsprogs-3.1.9ubuntu2/db/symlink.h xfsprogs-3.2.1ubuntu1/db/symlink.h --- xfsprogs-3.1.9ubuntu2/db/symlink.h 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/symlink.h 2013-10-10 21:07:17.000000000 +0000 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2013 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_DB_SYMLINK_H +#define __XFS_DB_SYMLINK_H + +extern const struct field symlink_crc_hfld[]; +extern const struct field symlink_crc_flds[]; + +extern int symlink_size(void *obj, int startoff, int idx); + +#endif /* __XFS_DB_SYMLINK_H */ diff -Nru xfsprogs-3.1.9ubuntu2/db/type.c xfsprogs-3.2.1ubuntu1/db/type.c --- xfsprogs-3.1.9ubuntu2/db/type.c 2009-02-17 01:14:58.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/type.c 2014-05-02 00:09:15.000000000 +0000 @@ -31,8 +31,6 @@ #include "agf.h" #include "agfl.h" #include "agi.h" -#include "dir.h" -#include "dirshort.h" #include "io.h" #include "output.h" #include "write.h" @@ -40,6 +38,7 @@ #include "dquot.h" #include "dir2.h" #include "text.h" +#include "symlink.h" static const typ_t *findtyp(char *name); static int type_f(int argc, char **argv); @@ -50,40 +49,81 @@ { "type", NULL, type_f, 0, 1, 1, N_("[newtype]"), N_("set/show current data type"), NULL }; -const typ_t typtab[] = { - { TYP_AGF, "agf", handle_struct, agf_hfld }, - { TYP_AGFL, "agfl", handle_struct, agfl_hfld }, - { TYP_AGI, "agi", handle_struct, agi_hfld }, - { TYP_ATTR, "attr", handle_struct, attr_hfld }, - { TYP_BMAPBTA, "bmapbta", handle_struct, bmapbta_hfld }, - { TYP_BMAPBTD, "bmapbtd", handle_struct, bmapbtd_hfld }, - { TYP_BNOBT, "bnobt", handle_struct, bnobt_hfld }, - { TYP_CNTBT, "cntbt", handle_struct, cntbt_hfld }, - { TYP_DATA, "data", handle_block, NULL }, - { TYP_DIR, "dir", handle_struct, dir_hfld }, - { TYP_DIR2, "dir2", handle_struct, dir2_hfld }, - { TYP_DQBLK, "dqblk", handle_struct, dqblk_hfld }, - { TYP_INOBT, "inobt", handle_struct, inobt_hfld }, - { TYP_INODATA, "inodata", NULL, NULL }, - { TYP_INODE, "inode", handle_struct, inode_hfld }, - { TYP_LOG, "log", NULL, NULL }, - { TYP_RTBITMAP, "rtbitmap", NULL, NULL }, - { TYP_RTSUMMARY, "rtsummary", NULL, NULL }, - { TYP_SB, "sb", handle_struct, sb_hfld }, - { TYP_SYMLINK, "symlink", handle_string, NULL }, - { TYP_TEXT, "text", handle_text, NULL }, +static const typ_t __typtab[] = { + { TYP_AGF, "agf", handle_struct, agf_hfld, NULL }, + { TYP_AGFL, "agfl", handle_struct, agfl_hfld, NULL }, + { TYP_AGI, "agi", handle_struct, agi_hfld, NULL }, + { TYP_ATTR, "attr", handle_struct, attr_hfld, NULL }, + { TYP_BMAPBTA, "bmapbta", handle_struct, bmapbta_hfld, NULL }, + { TYP_BMAPBTD, "bmapbtd", handle_struct, bmapbtd_hfld, NULL }, + { TYP_BNOBT, "bnobt", handle_struct, bnobt_hfld, NULL }, + { TYP_CNTBT, "cntbt", handle_struct, cntbt_hfld, NULL }, + { TYP_DATA, "data", handle_block, NULL, NULL }, + { TYP_DIR2, "dir2", handle_struct, dir2_hfld, NULL }, + { TYP_DQBLK, "dqblk", handle_struct, dqblk_hfld, NULL }, + { TYP_INOBT, "inobt", handle_struct, inobt_hfld, NULL }, + { TYP_INODATA, "inodata", NULL, NULL, NULL }, + { TYP_INODE, "inode", handle_struct, inode_hfld, NULL }, + { TYP_LOG, "log", NULL, NULL, NULL }, + { TYP_RTBITMAP, "rtbitmap", NULL, NULL, NULL }, + { TYP_RTSUMMARY, "rtsummary", NULL, NULL, NULL }, + { TYP_SB, "sb", handle_struct, sb_hfld, NULL }, + { TYP_SYMLINK, "symlink", handle_string, NULL, NULL }, + { TYP_TEXT, "text", handle_text, NULL, NULL }, { TYP_NONE, NULL } }; +static const typ_t __typtab_crc[] = { + { TYP_AGF, "agf", handle_struct, agf_hfld, &xfs_agf_buf_ops }, + { TYP_AGFL, "agfl", handle_struct, agfl_crc_hfld, &xfs_agfl_buf_ops }, + { TYP_AGI, "agi", handle_struct, agi_hfld, &xfs_agfl_buf_ops }, + { TYP_ATTR, "attr3", handle_struct, attr3_hfld, + &xfs_attr3_db_buf_ops }, + { TYP_BMAPBTA, "bmapbta", handle_struct, bmapbta_crc_hfld, + &xfs_bmbt_buf_ops }, + { TYP_BMAPBTD, "bmapbtd", handle_struct, bmapbtd_crc_hfld, + &xfs_bmbt_buf_ops }, + { TYP_BNOBT, "bnobt", handle_struct, bnobt_crc_hfld, + &xfs_allocbt_buf_ops }, + { TYP_CNTBT, "cntbt", handle_struct, cntbt_crc_hfld, + &xfs_allocbt_buf_ops }, + { TYP_DATA, "data", handle_block, NULL, NULL }, + { TYP_DIR2, "dir3", handle_struct, dir3_hfld, + &xfs_dir3_db_buf_ops }, + { TYP_DQBLK, "dqblk", handle_struct, dqblk_hfld, + &xfs_dquot_buf_ops }, + { TYP_INOBT, "inobt", handle_struct, inobt_crc_hfld, + &xfs_inobt_buf_ops }, + { TYP_INODATA, "inodata", NULL, NULL, NULL }, + { TYP_INODE, "inode", handle_struct, inode_crc_hfld, + &xfs_inode_buf_ops }, + { TYP_LOG, "log", NULL, NULL, NULL }, + { TYP_RTBITMAP, "rtbitmap", NULL, NULL, NULL }, + { TYP_RTSUMMARY, "rtsummary", NULL, NULL, NULL }, + { TYP_SB, "sb", handle_struct, sb_hfld, &xfs_sb_buf_ops }, + { TYP_SYMLINK, "symlink", handle_struct, symlink_crc_hfld, + &xfs_symlink_buf_ops }, + { TYP_TEXT, "text", handle_text, NULL, NULL }, + { TYP_NONE, NULL } +}; + +const typ_t *typtab = __typtab; + +void +type_set_tab_crc(void) +{ + typtab = __typtab_crc; +} + static const typ_t * findtyp( char *name) { const typ_t *tt; - for (tt = typtab; tt->name != NULL; tt++) { + for (tt = typtab; tt->typnm != TYP_NONE; tt++) { ASSERT(tt->typnm == (typnm_t)(tt - typtab)); - if (strcmp(tt->name, name) == 0) + if (tt->name && strcmp(tt->name, name) == 0) return tt; } return NULL; @@ -104,12 +144,14 @@ dbprintf(_("current type is \"%s\"\n"), cur_typ->name); dbprintf(_("\n supported types are:\n ")); - for (tt = typtab, count = 0; tt->name != NULL; tt++) { + for (tt = typtab, count = 0; tt->typnm != TYP_NONE; tt++) { + if (tt->name == NULL) + continue; if ((tt+1)->name != NULL) { dbprintf("%s, ", tt->name); if ((++count % 8) == 0) dbprintf("\n "); - } else { + } else if ((tt+1)->typnm == TYP_NONE) { dbprintf("%s\n", tt->name); } } @@ -120,10 +162,11 @@ if (tt == NULL) { dbprintf(_("no such type %s\n"), argv[1]); } else { - if (iocur_top->typ == NULL) { - dbprintf(_("no current object\n")); - } else { - iocur_top->typ = cur_typ = tt; + if (iocur_top->typ == NULL) + dbprintf(_("no current object\n")); + else { + cur_typ = tt; + set_iocur_type(tt); } } } diff -Nru xfsprogs-3.1.9ubuntu2/db/type.h xfsprogs-3.2.1ubuntu1/db/type.h --- xfsprogs-3.1.9ubuntu2/db/type.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/type.h 2014-05-02 00:09:15.000000000 +0000 @@ -24,7 +24,7 @@ typedef enum typnm { TYP_AGF, TYP_AGFL, TYP_AGI, TYP_ATTR, TYP_BMAPBTA, - TYP_BMAPBTD, TYP_BNOBT, TYP_CNTBT, TYP_DATA, TYP_DIR, + TYP_BMAPBTD, TYP_BNOBT, TYP_CNTBT, TYP_DATA, TYP_DIR2, TYP_DQBLK, TYP_INOBT, TYP_INODATA, TYP_INODE, TYP_LOG, TYP_RTBITMAP, TYP_RTSUMMARY, TYP_SB, TYP_SYMLINK, TYP_TEXT, TYP_NONE @@ -42,10 +42,12 @@ char *name; pfunc_t pfunc; const struct field *fields; + const struct xfs_buf_ops *bops; } typ_t; -extern const typ_t typtab[], *cur_typ; +extern const typ_t *typtab, *cur_typ; extern void type_init(void); +extern void type_set_tab_crc(void); extern void handle_block(int action, const struct field *fields, int argc, char **argv); extern void handle_string(int action, const struct field *fields, int argc, diff -Nru xfsprogs-3.1.9ubuntu2/db/write.c xfsprogs-3.2.1ubuntu1/db/write.c --- xfsprogs-3.1.9ubuntu2/db/write.c 2009-02-17 01:14:58.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/write.c 2014-07-21 09:13:53.000000000 +0000 @@ -233,6 +233,7 @@ memcpy(hold_region, base, shift); memcpy(base, base+shift, len-shift); memcpy(base+(len-shift), hold_region, shift); + free(hold_region); } /* ARGSUSED */ @@ -265,6 +266,7 @@ memcpy(hold_region, base+(len-shift), shift); memmove(base+shift, base, len-shift); memcpy(base, hold_region, shift); + free(hold_region); } /* ARGSUSED */ @@ -439,55 +441,78 @@ #define NYBBLE(x) (isdigit(x)?(x-'0'):(tolower(x)-'a'+0xa)) +/* + * convert_arg allows input in the following forms: + * + * - A string ("ABTB") whose ASCII value is placed in an array in the order + * matching the input. + * + * - An even number of hex numbers. If the length is greater than 64 bits, + * then the output is an array of bytes whose top nibble is the first hex + * digit in the input, the lower nibble is the second hex digit in the + * input. UUID entries are entered in this manner. + * + * - A decimal or hexadecimal integer to be used with setbitval(). + * + * Numbers that are passed to setbitval() need to be in big endian format and + * are adjusted in the buffer so that the first input bit is to be be written to + * the first bit in the output. + */ static char * convert_arg( - char *arg, - int bit_length) + char *arg, + int bit_length) { - int i; - static char *buf = NULL; - char *rbuf; - long long *value; - int alloc_size; - char *ostr; - int octval, ret; + int i; + int alloc_size; + int octval; + int offset; + int ret; + static char *buf = NULL; + char *endp; + char *rbuf; + char *ostr; + __u64 *value; + __u64 val = 0; if (bit_length <= 64) alloc_size = 8; else - alloc_size = (bit_length+7)/8; + alloc_size = (bit_length + 7) / 8; buf = xrealloc(buf, alloc_size); memset(buf, 0, alloc_size); - value = (long long *)buf; + value = (__u64 *)buf; rbuf = buf; if (*arg == '\"') { - /* handle strings */ + /* input a string and output ASCII array of characters */ /* zap closing quote if there is one */ - if ((ostr = strrchr(arg+1, '\"')) != NULL) + ostr = strrchr(arg + 1, '\"'); + if (ostr) *ostr = '\0'; - ostr = arg+1; + ostr = arg + 1; for (i = 0; i < alloc_size; i++) { if (!*ostr) break; - /* do octal */ + /* do octal conversion */ if (*ostr == '\\') { - if (*(ostr+1) >= '0' || *(ostr+1) <= '7') { - ret = convert_oct(ostr+1, &octval); + if (*(ostr + 1) >= '0' || *(ostr + 1) <= '7') { + ret = convert_oct(ostr + 1, &octval); *rbuf++ = octval; - ostr += ret+1; + ostr += ret + 1; continue; } } *rbuf++ = *ostr++; } - return buf; - } else if (arg[0] == '#' || ((arg[0] != '-') && strchr(arg,'-'))) { + } + + if (arg[0] == '#' || ((arg[0] != '-') && strchr(arg,'-'))) { /* * handle hex blocks ie * #00112233445566778899aabbccddeeff @@ -496,48 +521,79 @@ * * (but if it starts with "-" assume it's just an integer) */ - int bytes=bit_length/8; + int bytes = bit_length / NBBY; + + /* is this an array of hec numbers? */ + if (bit_length % NBBY) + return NULL; /* skip leading hash */ - if (*arg=='#') arg++; + if (*arg == '#') + arg++; while (*arg && bytes--) { - /* skip hypens */ - while (*arg=='-') arg++; - - /* get first nybble */ - if (!isxdigit((int)*arg)) return NULL; - *rbuf=NYBBLE((int)*arg)<<4; - arg++; - - /* skip more hyphens */ - while (*arg=='-') arg++; - - /* get second nybble */ - if (!isxdigit((int)*arg)) return NULL; - *rbuf++|=NYBBLE((int)*arg); - arg++; + /* skip hypens */ + while (*arg == '-') + arg++; + + /* get first nybble */ + if (!isxdigit((int)*arg)) + return NULL; + *rbuf = NYBBLE((int)*arg) << 4; + arg++; + + /* skip more hyphens */ + while (*arg == '-') + arg++; + + /* get second nybble */ + if (!isxdigit((int)*arg)) + return NULL; + *rbuf++ |= NYBBLE((int)*arg); + arg++; } - if (bytes<0&&*arg) return NULL; - return buf; - } else { - /* - * handle integers - */ - *value = strtoll(arg, NULL, 0); + if (bytes < 0 && *arg) + return NULL; -#if __BYTE_ORDER == BIG_ENDIAN - /* hackery for big endian */ - if (bit_length <= 8) { - rbuf += 7; - } else if (bit_length <= 16) { - rbuf += 6; - } else if (bit_length <= 32) { - rbuf += 4; - } -#endif - return rbuf; + return buf; } + + /* handle decimal / hexadecimal integers */ + val = strtoll(arg, &endp, 0); + /* return if not a clean number */ + if (*endp != '\0') + return NULL; + + /* Does the value fit into the range of the destination bitfield? */ + if (bit_length < 64 && (val >> bit_length) > 0) + return NULL; + /* + * If the length of the field is not a multiple of a byte, push + * the bits up in the field, so the most signicant field bit is + * the most significant bit in the byte: + * + * before: + * val |----|----|----|----|----|--MM|mmmm|llll| + * after + * val |----|----|----|----|----|MMmm|mmll|ll00| + */ + offset = bit_length % NBBY; + if (offset) + val <<= (NBBY - offset); + + /* + * convert to big endian and copy into the array + * rbuf |----|----|----|----|----|MMmm|mmll|ll00| + */ + *value = cpu_to_be64(val); + + /* + * Align the array to point to the field in the array. + * rbuf = |MMmm|mmll|ll00| + */ + offset = sizeof(__be64) - 1 - ((bit_length - 1) / sizeof(__be64)); + rbuf += offset; + return rbuf; } @@ -550,9 +606,9 @@ { const ftattr_t *fa; flist_t *fl; - flist_t *sfl; - int bit_length; - char *buf; + flist_t *sfl; + int bit_length; + char *buf; int parentoffset; if (argc != 2) { diff -Nru xfsprogs-3.1.9ubuntu2/db/xfs_check.sh xfsprogs-3.2.1ubuntu1/db/xfs_check.sh --- xfsprogs-3.1.9ubuntu2/db/xfs_check.sh 2009-09-23 01:42:38.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/xfs_check.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -#!/bin/sh -f -# -# Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. -# - -OPTS=" " -DBOPTS=" " -USAGE="Usage: xfs_check [-fsvV] [-l logdev] [-i ino]... [-b bno]... special" - -while getopts "b:fi:l:stvV" c -do - case $c in - s) OPTS=$OPTS"-s ";; - t) OPTS=$OPTS"-t ";; - v) OPTS=$OPTS"-v ";; - i) OPTS=$OPTS"-i "$OPTARG" ";; - b) OPTS=$OPTS"-b "$OPTARG" ";; - f) DBOPTS=$DBOPTS" -f";; - l) DBOPTS=$DBOPTS" -l "$OPTARG" ";; - V) xfs_db -p xfs_check -V - status=$? - exit $status - ;; - \?) echo $USAGE 1>&2 - exit 2 - ;; - esac -done -set -- extra $@ -shift $OPTIND -case $# in - 1) xfs_db$DBOPTS -F -i -p xfs_check -c "check$OPTS" $1 - status=$? - ;; - *) echo $USAGE 1>&2 - exit 2 - ;; -esac -exit $status diff -Nru xfsprogs-3.1.9ubuntu2/db/xfs_metadump.sh xfsprogs-3.2.1ubuntu1/db/xfs_metadump.sh --- xfsprogs-3.1.9ubuntu2/db/xfs_metadump.sh 2009-02-01 19:04:59.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/db/xfs_metadump.sh 2014-05-02 00:09:15.000000000 +0000 @@ -5,9 +5,9 @@ OPTS=" " DBOPTS=" " -USAGE="Usage: xfs_metadump [-efogwV] [-m max_extents] [-l logdev] source target" +USAGE="Usage: xfs_metadump [-efFogwV] [-m max_extents] [-l logdev] source target" -while getopts "efgl:m:owV" c +while getopts "efgl:m:owFV" c do case $c in e) OPTS=$OPTS"-e ";; @@ -17,6 +17,7 @@ w) OPTS=$OPTS"-w ";; f) DBOPTS=$DBOPTS" -f";; l) DBOPTS=$DBOPTS" -l "$OPTARG" ";; + F) DBOPTS=$DBOPTS" -F";; V) xfs_db -p xfs_metadump -V status=$? exit $status @@ -29,7 +30,7 @@ set -- extra $@ shift $OPTIND case $# in - 2) xfs_db$DBOPTS -F -i -p xfs_metadump -c "metadump$OPTS $2" $1 + 2) xfs_db$DBOPTS -i -p xfs_metadump -c "metadump$OPTS $2" $1 status=$? ;; *) echo $USAGE 1>&2 diff -Nru xfsprogs-3.1.9ubuntu2/debian/changelog xfsprogs-3.2.1ubuntu1/debian/changelog --- xfsprogs-3.1.9ubuntu2/debian/changelog 2013-12-18 17:15:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/debian/changelog 2014-08-08 11:51:17.000000000 +0000 @@ -1,3 +1,29 @@ +xfsprogs (3.2.1ubuntu1) utopic; urgency=medium + + * Patch m4/libtool.m4 for powerpc64le and regenerate configure. + + -- Matthias Klose Fri, 08 Aug 2014 13:49:19 +0200 + +xfsprogs (3.2.1) unstable; urgency=low + + * New upstream release (closes: #747080) + * Add a watch file (closes: #748483) + + -- Nathan Scott Wed, 16 Jul 2014 13:47:49 +1000 + +xfsprogs (3.2.0) unstable; urgency=low + + * New upstream release + * Add dh-autoreconf invocation (closes: #725971) + + -- Nathan Scott Sat, 03 May 2014 15:59:55 +1000 + +xfsprogs (3.1.11) unstable; urgency=low + + * New upstream release + + -- Nathan Scott Wed, 08 May 2013 12:59:56 -0500 + xfsprogs (3.1.9ubuntu2) trusty; urgency=medium * Patch m4/libtool.m4 for powerpc64le and regenerate configure. diff -Nru xfsprogs-3.1.9ubuntu2/debian/Makefile xfsprogs-3.2.1ubuntu1/debian/Makefile --- xfsprogs-3.1.9ubuntu2/debian/Makefile 2009-12-07 21:21:49.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/debian/Makefile 2014-07-21 09:13:53.000000000 +0000 @@ -5,7 +5,7 @@ TOPDIR = .. include $(TOPDIR)/include/builddefs -LSRCFILES = changelog compat control copyright rules +LSRCFILES = changelog compat control copyright rules watch DEV_DOC_DIR = $(PKG_DOC_DIR)/../xfslibs-dev BOOT_MKFS_BIN = $(TOPDIR)/mkfs/mkfs.xfs-xfsprogs-udeb LDIRDIRT = xfslibs-dev xfsprogs xfsprogs-udeb diff -Nru xfsprogs-3.1.9ubuntu2/debian/watch xfsprogs-3.2.1ubuntu1/debian/watch --- xfsprogs-3.1.9ubuntu2/debian/watch 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/debian/watch 2014-07-21 09:13:53.000000000 +0000 @@ -0,0 +1,3 @@ +version=3 +opts=uversionmangle=s/(\d)[_\.\-\+]?((RC|rc|pre|dev|beta|alpha)\d*)$/$1~$2/ \ +ftp://oss.sgi.com/projects/xfs/cmd_tars/xfsprogs-(.+)\.tar\.gz diff -Nru xfsprogs-3.1.9ubuntu2/doc/CHANGES xfsprogs-3.2.1ubuntu1/doc/CHANGES --- xfsprogs-3.1.9ubuntu2/doc/CHANGES 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/doc/CHANGES 2014-07-21 09:13:53.000000000 +0000 @@ -1,3 +1,145 @@ +xfsprogs-3.2.1 (15 July 2014) + - Added support for new on-disk free inode btree (Brian Foster) + - libxfs inode use-after free fixes (Mark Tinguely) + - xfs_copy threading cleanups (Junxiao Bi) + - xfs_check has been removed + - C++ header compiler fixes (Roger Willcocks) + - xfs_repair prefetch fixes (Eric Sandeen) + - xfs_repair directory block CRC detection fixes (Jan Kara) + - xfs_repair directory rebuild fixes + - libxfs buffer error handling fixes + - xfs_repair quota inode handling fixes + - removed incorrect asserts from phase 2 of xfs_repair + - updated Polish translations (Jakub Bogusz) + - xfs_mkfs 4k sector device fixes (Eric Sandeen) + - xfs_fsr cleanups nd fixes (Eric Sandeen) + - mount options described in xfs(5) man page (Eric Sandeen) + +xfsprogs-3.2.0 (16 May 2014) + - First release with full support of CRC enabled filesystems + - No code changes from 3.2.0-rc3 + +xfsprogs-3.2.0-rc3 (9 May 2014) + - Third release candidate for full support of CRC enabled filesystems + - Updated Debian change logs in preparation for release (Nathan Scott) + - Build warning fixes (Nathan Scott) + - xfs_repair prefetch fix (Eric Sandeen) + - xfs_repair block tracking scalability fix + +xfsprogs-3.2.0-rc2 (2 May 2014) + - Second release candidate for full support of CRC enabled filesystems + - xfs_repair has full CRC validation and repair + - Coverity related cleanups and fixes + +xfsprogs-3.2.0-rc1 (14 April 2014) + - First release candidate for full support of CRC enabled filesystems + - Large number of Coverity related fixes and cleanups + - disambiguous of CRC validation errors from IO errors. + - Improved dangerous mode handling in repair + - repair handles garbage in zeroed areas of superblocks better + - repair validates dirent ftype field fully + - metadump fully supports discontiguous directory blocks + - metadump only recalculates CRCs on metadata it obfuscates so as to + preserve errors in the metadata where possible. + - default log size that mkfs creates is now reverted to the same size + as 3.1.x releases create. + - mkfs sets the ftype on directory entries correctly during protofile + population + - xfs_io support O_TMPFILE, flink, FALLOC_FL_ZERO_RANGE and + FALLOC_FL_COLLAPSE_RANGE, + - logprint handles split entries better + +xfsprogs-3.2.0-alpha2 (25 November 2013) + - Alpha release for the purpose of testing the CRC feature in + kernels 3.10 and newer. + - Enable xfs_db write support and xfs_metadump support for CRC + enabled filesystems. + - Add directory entry filetype support for non-CRC filesystems. + - Remove experimental warnings for CRC filesystems. + - Ensure all inodes created by xfs_repair have a proper d_type set. + - Fix build on big endian machines. + - Properly handle symlinks to devices on various tool commandlines. + - Fix xfs_repair's dirty log detection for 4k sector logs, broken + in Alpha1. + - Fix a potential segfault in xfs_repair when issuing progress + reports. + - Fix potential xfs_fsr failures when running w/ selinux. + - Update config.guess/config.sub for arm64, thanks to Colin Watson. + - Stop wasting memory by caching inode structures in xfs_repair - + they are never re-used. Thanks to Christoph Hellwig. + - Fix several Coverity-found defects, thanks to Li Zhong. + - Fix platform_test_xfs_fd to return false on special files which + cannot take an xfs ioctl. + - Sync up libxfs with kernel code. + - Improved xfs_repair performance on large filesystems + (always use prefetch and strided AG scanning functionality) + + +xfsprogs-3.2.0-alpha1 (26 September 2013) + - Alpha release for the purpose of testing the CRC feature in + kernels 3.10 and newer. + - Remove all vestiges of old, unsupported version 1 directory code. + - Add a "readdir" command to xfs_io, thanks to Brian Foster. + - Fix potential segfault in xfs_repair when creating lost+found. + - Zero out unused parts of on-disk superblocks during repair, to + avoid metadata verifier failures at runtime. + - Add directory entry type support to mkfs.xfs and xfs_db. + - Add the icreate transaction to xfs_logprint, and fix continuation + transactions. + - Add the lseek SEEK_DATA/SEEK_HOLE support into xfs_io. + - Print all AGI unlinked buckets in xfs_logprint. + - Fix mkfs.xfs ENOSPC with protofile which creates a very large + directory. + - Fix several Coverity-found defects, thanks to Li Zhong. + - Do all file reads in xfs_fsr using O_DIRECT. + - Sync up libxfs with kernel code. + - Add support for concurrent group and project quota usage on CRC + enabled filesystems. + - Ensure mkfs creates log sizes that are always large enough for + the configured fileystem geometry. + +xfsprogs-3.1.11 (8 May 2013) + - Support for relative paths in xfs_quota thanks to Satoru Takeuchi. + - mkfs.xfs will always go into multidisk mode when filesystem + geometry is specified on the command line. + - Document all commands in xfs_io. + - Remove setfl command from xfs_io. + - xfs_metadump will obfuscate symlinks by path component. + - mkfs.xfs no longer accepts geometry settings smaller than the + physical sector size. + - xfs_logprint now supports multiply-logged inode fields and + handles continued inode transactions correctly. + - kill XLOG_SET + - Update release scripts to use git archive to address a + missing source file reported by Arkadiusz Mi?kiewicz + - Fix a build error with -Werror=format-security, reported + by Arkadiusz Mi?kiewicz + - mkfs.xfs no longer attempts to discard when -N option is used. + - Update 'make deb' to use tarball + - Sync up with log reservation changes in the kernel. + - Fix possible unallocated memory access in fiemap. + - Guard against string overflow in path_to_fspath. + - Fix setup_cursor array allocation. + - Fix free of unintialized pointer in xfs_acl_valid error path. + - Guard against path string overflows. + - Check strdup results properly in initallfs(). + - Fix attribute no_change_count logic. + - Remove extraneous close() in fsrallfs(). + - xfs_repair now skips the freelist scan of a corrupt agf + when in no-modify mode. + - xfs_db now skips freelist scans of corrupt agfs. + - Remove unconditional ASSERT(0) in xfs_repair. + - Reduce bb_numrecs in bno/cnt btrees when log consumes all agf space. + - Add depraction message for xfs_check. + - xfs_quota allow user or group names beginning with digits reported + by James Carter. + - Fix manpages and usage() spelling, errors and omissions. + - Validate the extent count is at least within the positive + range of a signed 32 bit integer before using it. + +xfsprogs-3.1.10 (13 December 2012) + - Update release script to make a source tarball. + xfsprogs-3.1.9 (31 October 2012) - Print nice details if agsize is out of bounds in mkfs.xfs. - Various fixes for fragmented multi-block dir2 handling in diff -Nru xfsprogs-3.1.9ubuntu2/estimate/xfs_estimate.c xfsprogs-3.2.1ubuntu1/estimate/xfs_estimate.c --- xfsprogs-3.1.9ubuntu2/estimate/xfs_estimate.c 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/estimate/xfs_estimate.c 2013-06-06 22:52:59.000000000 +0000 @@ -18,6 +18,8 @@ /* * Estimate space of an XFS filesystem + * + * XXX: assumes dirv1 format. */ #include #include @@ -48,7 +50,7 @@ #define BLOCKSIZE 4096 #define INODESIZE 256 #define PERDIRENTRY \ - (sizeof(xfs_dir_leaf_entry_t) + sizeof(xfs_dir_leaf_name_t)) + (sizeof(xfs_dir2_leaf_entry_t) + sizeof(xfs_dir2_data_entry_t)) #define LOGSIZE 1000 #define FBLOCKS(n) ((n)/blocksize) @@ -78,6 +80,7 @@ "\t-i logsize (internal log size)\n" "\t-e logsize (external log size)\n" "\t-v prints more verbose messages\n" + "\t-V prints version and exits\n" "\t-h prints this usage message\n\n" "Note:\tblocksize may have 'k' appended to indicate x1024\n" "\tlogsize may also have 'm' appended to indicate (1024 x 1024)\n"), diff -Nru xfsprogs-3.1.9ubuntu2/fsck/xfs_fsck.sh xfsprogs-3.2.1ubuntu1/fsck/xfs_fsck.sh --- xfsprogs-3.1.9ubuntu2/fsck/xfs_fsck.sh 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/fsck/xfs_fsck.sh 2014-05-02 00:09:15.000000000 +0000 @@ -19,6 +19,6 @@ echo "$0: XFS file system." else echo "If you wish to check the consistency of an XFS filesystem or" - echo "repair a damaged filesystem, see xfs_check(8) and xfs_repair(8)." + echo "repair a damaged filesystem, see xfs_repair(8)." fi exit 0 diff -Nru xfsprogs-3.1.9ubuntu2/fsr/xfs_fsr.c xfsprogs-3.2.1ubuntu1/fsr/xfs_fsr.c --- xfsprogs-3.1.9ubuntu2/fsr/xfs_fsr.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/fsr/xfs_fsr.c 2014-06-19 22:42:17.000000000 +0000 @@ -16,11 +16,10 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include #include +#include #include #include -#include #include #include #include @@ -77,7 +76,6 @@ #define V_ALL 2 #define BUFFER_SIZE (1<<16) #define BUFFER_MAX (1<<24) -#define min(x, y) ((x) < (y) ? (x) : (y)) static time_t howlong = 7200; /* default seconds of reorganizing */ static char *leftofffile = _PATH_FSRLAST; /* where we left off last */ @@ -386,20 +384,19 @@ usage(int ret) { fprintf(stderr, _( -"Usage: %s [-d] [-v] [-n] [-s] [-g] [-t time] [-p passes] [-f leftf] [-m mtab]\n" -" %s [-d] [-v] [-n] [-s] [-g] xfsdev | dir | file ...\n\n" +"Usage: %s [-d] [-v] [-g] [-t time] [-p passes] [-f leftf] [-m mtab]\n" +" %s [-d] [-v] [-g] xfsdev | dir | file ...\n" +" %s -V\n\n" "Options:\n" -" -n Do nothing, only interesting with -v. Not\n" -" effective with in mtab mode.\n" -" -s Print statistics only.\n" " -g Print to syslog (default if stdout not a tty).\n" " -t time How long to run in seconds.\n" -" -p passes Number of passes before terminating global re-org.\n" +" -p passes Number of passes before terminating global re-org.\n" " -f leftoff Use this instead of %s.\n" " -m mtab Use something other than /etc/mtab.\n" " -d Debug, print even more.\n" -" -v Verbose, more -v's more verbose.\n" - ), progname, progname, _PATH_FSRLAST); +" -v Verbose, more -v's more verbose.\n" +" -V Print version number and exit.\n" + ), progname, progname, progname, _PATH_FSRLAST); exit(ret); } @@ -470,10 +467,14 @@ fs->dev = strdup(mp->mnt_fsname); fs->mnt = strdup(mp->mnt_dir); - if (fs->mnt == NULL || fs->mnt == NULL) { + if (fs->dev == NULL) { fsrprintf(_("strdup(%s) failed\n"), mp->mnt_fsname); exit(1); } + if (fs->mnt == NULL) { + fsrprintf(_("strdup(%s) failed\n"), mp->mnt_dir); + exit(1); + } mi++; fs++; } @@ -553,6 +554,8 @@ fsrprintf(_("could not read %s, starting with %s\n"), leftofffile, *fs->dev); } else { + /* Ensure the buffer we read is null terminated */ + buf[SMBUFSZ-1] = '\0'; for (fs = fsbase; fs < fsend; fs++) { fsname = fs->dev; if ((strncmp(buf,fsname,strlen(fsname)) == 0) @@ -623,7 +626,6 @@ break; default: wait(&error); - close(fd); if (WIFEXITED(error) && WEXITSTATUS(error) == 1) { /* child timed out & did fsrall_cleanup */ exit(0); @@ -647,14 +649,19 @@ int ret; char buf[SMBUFSZ]; - /* record where we left off */ unlink(leftofffile); - fd = open(leftofffile, O_WRONLY|O_CREAT|O_EXCL, 0644); - if (fd == -1) - fsrprintf(_("open(%s) failed: %s\n"), - leftofffile, strerror(errno)); - else { - if (timeout) { + + if (timeout) { + fsrprintf(_("%s startpass %d, endpass %d, time %d seconds\n"), + progname, startpass, fs->npass, + time(0) - endtime + howlong); + + /* record where we left off */ + fd = open(leftofffile, O_WRONLY|O_CREAT|O_EXCL, 0644); + if (fd == -1) { + fsrprintf(_("open(%s) failed: %s\n"), + leftofffile, strerror(errno)); + } else { ret = sprintf(buf, "%s %d %llu\n", fs->dev, fs->npass, (unsigned long long)leftoffino); if (write(fd, buf, ret) < strlen(buf)) @@ -663,11 +670,6 @@ close(fd); } } - - if (timeout) - fsrprintf(_("%s startpass %d, endpass %d, time %d seconds\n"), - progname, startpass, fs->npass, - time(0) - endtime + howlong); } /* @@ -706,6 +708,7 @@ if (xfs_getgeom(fsfd, &fsgeom) < 0 ) { fsrprintf(_("Skipping %s: could not get XFS geometry\n"), mntdir); + close(fsfd); return -1; } @@ -730,7 +733,8 @@ (p->bs_extents < 2)) continue; - if ((fd = jdm_open(fshandlep, p, O_RDWR)) < 0) { + fd = jdm_open(fshandlep, p, O_RDWR|O_DIRECT); + if (fd < 0) { /* This probably means the file was * removed while in progress of handling * it. Just quietly ignore this file. @@ -834,7 +838,7 @@ return -1; } - fd = jdm_open( fshandlep, &statbuf, O_RDWR); + fd = jdm_open(fshandlep, &statbuf, O_RDWR|O_DIRECT); if (fd < 0) { fsrprintf(_("unable to open handle %s: %s\n"), fname, strerror(errno)); @@ -1021,6 +1025,7 @@ { struct stat64 tstatbuf; int i; + int diff = 0; int last_forkoff = 0; int no_change_cnt = 0; int ret; @@ -1056,10 +1061,9 @@ xfs_bstat_t tbstat; xfs_ino_t ino; char name[64]; - int diff; /* - * bulkstat the temp inode to see what the forkoff is. Use + * bulkstat the temp inode to see what the forkoff is. Use * this to compare against the target and determine what we * need to do. */ @@ -1072,6 +1076,11 @@ if (dflag) fsrprintf(_("orig forkoff %d, temp forkoff %d\n"), bstatp->bs_forkoff, tbstat.bs_forkoff); + diff = tbstat.bs_forkoff - bstatp->bs_forkoff; + + /* if they are equal, we are done */ + if (!diff) + goto out; snprintf(name, sizeof(name), "user.%d", i); @@ -1080,12 +1089,62 @@ * an attribute fork at the default location. */ if (!tbstat.bs_forkoff) { + ASSERT(i == 0); ret = fsetxattr(tfd, name, "XX", 2, XATTR_CREATE); if (ret) { fsrprintf(_("could not set ATTR\n")); return -1; } continue; + } else if (i == 0) { + struct fsxattr fsx; + /* + * First pass, and temp file already has an inline + * xattr, probably due to selinux. + * + * It's *possible* that the temp file attr area + * is larger than the target file's, if the + * target file's attrs are not inline: + * + * Target Temp + * +-------+ 0 +-------+ 0 + * | | | | + * | | | Data | + * | Data | | | + * | | v-------v forkoff + * | | | | + * v-------v forkoff | Attr | local + * | Attr | ext/btree | | + * +-------+ +-------+ + * + * FSGETXATTRA will tell us nr of attr extents in + * target, if any. If none, it's local: + */ + + memset(&fsx, 0, sizeof(fsx)); + if (ioctl(fd, XFS_IOC_FSGETXATTRA, &fsx)) { + fsrprintf(_("FSGETXATTRA failed on target\n")); + return -1; + } + + /* + * If target attr area is less than the temp's (diff < 0) + * and the target is not local, write a big attr to + * the temp file to knock the attr out of local format, + * to match the target. (This should actually *increase* + * the temp file's forkoffset when the attr moves out + * of the inode) + */ + if (diff < 0 && fsx.fsx_nextents > 0) { + char val[2048]; + memset(val, 'X', 2048); + if (fsetxattr(tfd, name, val, 2048, 0)) { + fsrprintf(_("big ATTR set failed\n")); + return -1; + } + /* Go back & see where we're at now */ + continue; + } } /* @@ -1095,24 +1154,19 @@ if (last_forkoff == tbstat.bs_forkoff) { if (no_change_cnt++ > 10) break; - } - no_change_cnt = 0; + } else /* progress! */ + no_change_cnt = 0; last_forkoff = tbstat.bs_forkoff; /* work out which way to grow the fork */ - diff = tbstat.bs_forkoff - bstatp->bs_forkoff; if (abs(diff) > fsgeom.inodesize - sizeof(struct xfs_dinode)) { fsrprintf(_("forkoff diff %d too large!\n"), diff); return -1; } - /* if they are equal, we are done */ - if (!diff) - goto out; - /* - * if the temp inode fork offset is smaller then we have to - * grow the data fork + * if the temp inode fork offset is still smaller then we have + * to grow the data fork */ if (diff < 0) { /* @@ -1122,6 +1176,8 @@ * non-contiguous offsets. */ /* XXX: unimplemented! */ + if (dflag) + printf(_("data fork growth unimplemented\n")); goto out; } @@ -1137,6 +1193,10 @@ out: if (dflag) fsrprintf(_("set temp attr\n")); + /* We failed to resolve the fork difference */ + if (dflag && diff) + fsrprintf(_("failed to match fork offset\n"));; + return 0; } @@ -1145,14 +1205,20 @@ * We already are pretty sure we can and want to * defragment the file. Create the tmp file, copy * the data (maintaining holes) and call the kernel - * extent swap routinte. + * extent swap routine. + * + * Return values: + * -1: Some error was encountered + * 0: Successfully defragmented the file + * 1: No change / No Error */ static int packfile(char *fname, char *tname, int fd, xfs_bstat_t *statp, struct fsxattr *fsxp) { - int tfd; + int tfd = -1; int srval; + int retval = -1; /* Failure is the default */ int nextents, extent, cur_nextents, new_nextents; unsigned blksz_dio; unsigned dio_min; @@ -1160,7 +1226,7 @@ static xfs_swapext_t sx; struct xfs_flock64 space; off64_t cnt, pos; - void *fbuf; + void *fbuf = NULL; int ct, wc, wc_b4; char ffname[SMBUFSZ]; int ffd = -1; @@ -1176,7 +1242,8 @@ if (cur_nextents == 1 || cur_nextents <= nextents) { if (vflag) fsrprintf(_("%s already fully defragmented.\n"), fname); - return 1; /* indicates no change/no error */ + retval = 1; /* indicates no change/no error */ + goto out; } if (dflag) @@ -1188,15 +1255,14 @@ if (vflag) fsrprintf(_("could not open tmp file: %s: %s\n"), tname, strerror(errno)); - return -1; + goto out; } unlink(tname); /* Setup extended attributes */ if (fsr_setup_attr_fork(fd, tfd, statp) != 0) { fsrprintf(_("failed to set ATTR fork on tmp: %s:\n"), tname); - close(tfd); - return -1; + goto out; } /* Setup extended inode flags, project identifier, etc */ @@ -1204,15 +1270,13 @@ if (ioctl(tfd, XFS_IOC_FSSETXATTR, fsxp) < 0) { fsrprintf(_("could not set inode attrs on tmp: %s\n"), tname); - close(tfd); - return -1; + goto out; } } if ((ioctl(tfd, XFS_IOC_DIOINFO, &dio)) < 0 ) { fsrprintf(_("could not get DirectIO info on tmp: %s\n"), tname); - close(tfd); - return -1; + goto out; } dio_min = dio.d_miniosz; @@ -1234,8 +1298,7 @@ if (!(fbuf = (char *)memalign(dio.d_mem, blksz_dio))) { fsrprintf(_("could not allocate buf: %s\n"), tname); - close(tfd); - return -1; + goto out; } if (nfrags) { @@ -1246,9 +1309,7 @@ if ((ffd = open(ffname, openopts, 0666)) < 0) { fsrprintf(_("could not open fragfile: %s : %s\n"), ffname, strerror(errno)); - close(tfd); - free(fbuf); - return -1; + goto out; } unlink(ffname); } @@ -1264,7 +1325,11 @@ fsrprintf(_("could not trunc tmp %s\n"), tname); } - lseek64(tfd, outmap[extent].bmv_length, SEEK_CUR); + if (lseek64(tfd, outmap[extent].bmv_length, SEEK_CUR) < 0) { + fsrprintf(_("could not lseek in tmpfile: %s : %s\n"), + tname, strerror(errno)); + goto out; + } continue; } else if (outmap[extent].bmv_length == 0) { /* to catch holes at the beginning of the file */ @@ -1278,19 +1343,19 @@ if (ioctl(tfd, XFS_IOC_RESVSP64, &space) < 0) { fsrprintf(_("could not pre-allocate tmp space:" " %s\n"), tname); - close(tfd); - free(fbuf); - return -1; + goto out; + } + if (lseek64(tfd, outmap[extent].bmv_length, SEEK_CUR) < 0) { + fsrprintf(_("could not lseek in tmpfile: %s : %s\n"), + tname, strerror(errno)); + goto out; } - lseek64(tfd, outmap[extent].bmv_length, SEEK_CUR); } } /* end of space allocation loop */ if (lseek64(tfd, 0, SEEK_SET)) { fsrprintf(_("Couldn't rewind on temporary file\n")); - close(tfd); - free(fbuf); - return -1; + goto out; } /* Check if the temporary file has fewer extents */ @@ -1300,17 +1365,24 @@ if (cur_nextents <= new_nextents) { if (vflag) fsrprintf(_("No improvement will be made (skipping): %s\n"), fname); - free(fbuf); - close(tfd); - return 1; /* no change/no error */ + retval = 1; /* no change/no error */ + goto out; } /* Loop through block map copying the file. */ for (extent = 0; extent < nextents; extent++) { pos = outmap[extent].bmv_offset; if (outmap[extent].bmv_block == -1) { - lseek64(tfd, outmap[extent].bmv_length, SEEK_CUR); - lseek64(fd, outmap[extent].bmv_length, SEEK_CUR); + if (lseek64(tfd, outmap[extent].bmv_length, SEEK_CUR) < 0) { + fsrprintf(_("could not lseek in tmpfile: %s : %s\n"), + tname, strerror(errno)); + goto out; + } + if (lseek64(fd, outmap[extent].bmv_length, SEEK_CUR) < 0) { + fsrprintf(_("could not lseek in file: %s : %s\n"), + fname, strerror(errno)); + goto out; + } continue; } else if (outmap[extent].bmv_length == 0) { /* to catch holes at the beginning of the file */ @@ -1373,9 +1445,7 @@ tname); } } - free(fbuf); - close(tfd); - return -1; + goto out; } if (nfrags) { /* Do a matching write to the tmp file */ @@ -1388,11 +1458,16 @@ } } } - ftruncate64(tfd, statp->bs_size); - if (ffd > 0) close(ffd); - fsync(tfd); - - free(fbuf); + if (ftruncate64(tfd, statp->bs_size) < 0) { + fsrprintf(_("could not truncate tmpfile: %s : %s\n"), + fname, strerror(errno)); + goto out; + } + if (fsync(tfd) < 0) { + fsrprintf(_("could not fsync tmpfile: %s : %s\n"), + fname, strerror(errno)); + goto out; + } sx.sx_stat = *statp; /* struct copy */ sx.sx_version = XFS_SX_VERSION; @@ -1406,8 +1481,7 @@ if (vflag) fsrprintf(_("failed to fchown tmpfile %s: %s\n"), tname, strerror(errno)); - close(tfd); - return -1; + goto out; } /* Swap the extents */ @@ -1429,8 +1503,7 @@ fsrprintf(_("XFS_IOC_SWAPEXT failed: %s: %s\n"), fname, strerror(errno)); } - close(tfd); - return -1; + goto out; } /* Report progress */ @@ -1439,8 +1512,15 @@ cur_nextents, new_nextents, (new_nextents <= nextents ? "DONE" : " " ), fname); - close(tfd); - return 0; + retval = 0; + +out: + free(fbuf); + if (tfd != -1) + close(tfd); + if (ffd != -1) + close(ffd); + return retval; } char * @@ -1452,7 +1532,8 @@ sprintf(sbuf, "/.fsr%d", getpid()); - strcpy(buf, fname); + strncpy(buf, fname, PATH_MAX); + buf[PATH_MAX] = '\0'; ptr = strrchr(buf, '/'); if (ptr) { *ptr = '\0'; @@ -1476,7 +1557,8 @@ static char buf[PATH_MAX+1]; char *ptr; - strcpy(buf, fname); + strncpy(buf, fname, PATH_MAX); + buf[PATH_MAX] = '\0'; ptr = strrchr(buf, '/'); if (ptr) { if (ptr == &buf[0]) diff -Nru xfsprogs-3.1.9ubuntu2/.gitcensus xfsprogs-3.2.1ubuntu1/.gitcensus --- xfsprogs-3.1.9ubuntu2/.gitcensus 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/.gitcensus 2014-07-21 09:17:37.000000000 +0000 @@ -0,0 +1,423 @@ +.gitignore +Makefile +README +VERSION +configure.ac +copy/Makefile +copy/xfs_copy.c +copy/xfs_copy.h +db/Makefile +db/addr.c +db/addr.h +db/agf.c +db/agf.h +db/agfl.c +db/agfl.h +db/agi.c +db/agi.h +db/attr.c +db/attr.h +db/attrset.c +db/attrset.h +db/attrshort.c +db/attrshort.h +db/bit.c +db/bit.h +db/block.c +db/block.h +db/bmap.c +db/bmap.h +db/bmroot.c +db/bmroot.h +db/btblock.c +db/btblock.h +db/check.c +db/check.h +db/command.c +db/command.h +db/convert.c +db/convert.h +db/debug.c +db/debug.h +db/dir2.c +db/dir2.h +db/dir2sf.c +db/dir2sf.h +db/dquot.c +db/dquot.h +db/echo.c +db/echo.h +db/faddr.c +db/faddr.h +db/field.c +db/field.h +db/flist.c +db/flist.h +db/fprint.c +db/fprint.h +db/frag.c +db/frag.h +db/freesp.c +db/freesp.h +db/hash.c +db/hash.h +db/help.c +db/help.h +db/init.c +db/init.h +db/inode.c +db/inode.h +db/input.c +db/input.h +db/io.c +db/io.h +db/malloc.c +db/malloc.h +db/metadump.c +db/metadump.h +db/output.c +db/output.h +db/print.c +db/print.h +db/quit.c +db/quit.h +db/sb.c +db/sb.h +db/sig.c +db/sig.h +db/strvec.c +db/strvec.h +db/symlink.c +db/symlink.h +db/text.c +db/text.h +db/type.c +db/type.h +db/write.c +db/write.h +db/xfs_admin.sh +db/xfs_metadump.sh +db/xfs_ncheck.sh +debian/Makefile +debian/changelog +debian/compat +debian/control +debian/copyright +debian/rules +debian/watch +doc/CHANGES +doc/COPYING +doc/CREDITS +doc/INSTALL +doc/Makefile +doc/sparse.txt +estimate/Makefile +estimate/xfs_estimate.c +fsck/Makefile +fsck/xfs_fsck.sh +fsr/Makefile +fsr/xfs_fsr.c +growfs/Makefile +growfs/xfs_growfs.c +growfs/xfs_info.sh +include/Makefile +include/atomic.h +include/bitops.h +include/builddefs.in +include/buildmacros +include/buildrules +include/cache.h +include/command.h +include/darwin.h +include/dvh.h +include/freebsd.h +include/fstyp.h +include/gnukfreebsd.h +include/handle.h +include/hlist.h +include/input.h +include/install-sh +include/irix.h +include/jdm.h +include/kmem.h +include/libxfs.h +include/libxlog.h +include/linux.h +include/list.h +include/parent.h +include/path.h +include/platform_defs.h.in +include/project.h +include/radix-tree.h +include/swab.h +include/volume.h +include/xfs.h +include/xfs_ag.h +include/xfs_alloc.h +include/xfs_alloc_btree.h +include/xfs_arch.h +include/xfs_attr_leaf.h +include/xfs_attr_remote.h +include/xfs_attr_sf.h +include/xfs_bit.h +include/xfs_bmap.h +include/xfs_bmap_btree.h +include/xfs_btree.h +include/xfs_btree_trace.h +include/xfs_cksum.h +include/xfs_da_btree.h +include/xfs_da_format.h +include/xfs_dinode.h +include/xfs_dir2.h +include/xfs_format.h +include/xfs_fs.h +include/xfs_ialloc.h +include/xfs_ialloc_btree.h +include/xfs_inode_buf.h +include/xfs_inode_fork.h +include/xfs_inum.h +include/xfs_log_format.h +include/xfs_log_recover.h +include/xfs_metadump.h +include/xfs_quota_defs.h +include/xfs_sb.h +include/xfs_shared.h +include/xfs_trace.h +include/xfs_trans_resv.h +include/xfs_trans_space.h +include/xfs_types.h +include/xqm.h +io/Makefile +io/attr.c +io/bmap.c +io/fadvise.c +io/fiemap.c +io/file.c +io/freeze.c +io/fsync.c +io/getrusage.c +io/imap.c +io/init.c +io/init.h +io/inject.c +io/io.h +io/link.c +io/madvise.c +io/mincore.c +io/mmap.c +io/open.c +io/parent.c +io/pread.c +io/prealloc.c +io/pwrite.c +io/readdir.c +io/resblks.c +io/seek.c +io/sendfile.c +io/shutdown.c +io/sync_file_range.c +io/truncate.c +io/xfs_bmap.sh +io/xfs_freeze.sh +io/xfs_mkfile.sh +libdisk/Makefile +libdisk/dm.c +libdisk/drivers.c +libdisk/drivers.h +libdisk/evms.c +libdisk/evms.h +libdisk/fstype.c +libdisk/fstype.h +libdisk/lvm.c +libdisk/md.c +libdisk/md.h +libdisk/pttype.c +libdisk/pttype.h +libdisk/xvm.c +libdisk/xvm.h +libhandle/Makefile +libhandle/handle.c +libhandle/jdm.c +libhandle/libhandle.sym +libxcmd/Makefile +libxcmd/command.c +libxcmd/help.c +libxcmd/input.c +libxcmd/paths.c +libxcmd/projects.c +libxcmd/quit.c +libxfs/Makefile +libxfs/cache.c +libxfs/crc32.c +libxfs/crc32defs.h +libxfs/darwin.c +libxfs/freebsd.c +libxfs/gen_crc32table.c +libxfs/init.c +libxfs/init.h +libxfs/irix.c +libxfs/kmem.c +libxfs/linux.c +libxfs/logitem.c +libxfs/radix-tree.c +libxfs/rdwr.c +libxfs/trans.c +libxfs/util.c +libxfs/xfs.h +libxfs/xfs_alloc.c +libxfs/xfs_alloc_btree.c +libxfs/xfs_attr.c +libxfs/xfs_attr_leaf.c +libxfs/xfs_attr_remote.c +libxfs/xfs_bmap.c +libxfs/xfs_bmap_btree.c +libxfs/xfs_btree.c +libxfs/xfs_da_btree.c +libxfs/xfs_dir2.c +libxfs/xfs_dir2_block.c +libxfs/xfs_dir2_data.c +libxfs/xfs_dir2_leaf.c +libxfs/xfs_dir2_node.c +libxfs/xfs_dir2_priv.h +libxfs/xfs_dir2_sf.c +libxfs/xfs_dquot_buf.c +libxfs/xfs_ialloc.c +libxfs/xfs_ialloc_btree.c +libxfs/xfs_inode_buf.c +libxfs/xfs_inode_fork.c +libxfs/xfs_log_rlimit.c +libxfs/xfs_rtbitmap.c +libxfs/xfs_sb.c +libxfs/xfs_symlink_remote.c +libxfs/xfs_trans_resv.c +libxlog/Makefile +libxlog/util.c +libxlog/xfs_log_recover.c +logprint/Makefile +logprint/log_copy.c +logprint/log_dump.c +logprint/log_misc.c +logprint/log_print_all.c +logprint/log_print_trans.c +logprint/logprint.c +logprint/logprint.h +m4/Makefile +m4/manual_format.m4 +m4/multilib.m4 +m4/package_aiodev.m4 +m4/package_blkid.m4 +m4/package_globals.m4 +m4/package_libcdev.m4 +m4/package_pthread.m4 +m4/package_types.m4 +m4/package_utilies.m4 +m4/package_uuiddev.m4 +man/Makefile +man/man3/Makefile +man/man3/handle.3 +man/man3/xfsctl.3 +man/man5/Makefile +man/man5/projects.5 +man/man5/projid.5 +man/man5/xfs.5 +man/man8/Makefile +man/man8/fsck.xfs.8 +man/man8/mkfs.xfs.8 +man/man8/xfs_admin.8 +man/man8/xfs_bmap.8 +man/man8/xfs_copy.8 +man/man8/xfs_db.8 +man/man8/xfs_estimate.8 +man/man8/xfs_freeze.8 +man/man8/xfs_fsr.8 +man/man8/xfs_growfs.8 +man/man8/xfs_io.8 +man/man8/xfs_logprint.8 +man/man8/xfs_mdrestore.8 +man/man8/xfs_metadump.8 +man/man8/xfs_mkfile.8 +man/man8/xfs_ncheck.8 +man/man8/xfs_quota.8 +man/man8/xfs_repair.8 +man/man8/xfs_rtcp.8 +mdrestore/Makefile +mdrestore/xfs_mdrestore.c +mkfs/Makefile +mkfs/fstyp.c +mkfs/maxtrres.c +mkfs/proto.c +mkfs/xfs_mkfs.c +mkfs/xfs_mkfs.h +po/Makefile +po/de.po +po/pl.po +quota/Makefile +quota/darwin.c +quota/edit.c +quota/free.c +quota/freebsd.c +quota/init.c +quota/init.h +quota/irix.c +quota/linux.c +quota/path.c +quota/project.c +quota/quot.c +quota/quota.c +quota/quota.h +quota/report.c +quota/state.c +quota/util.c +release.sh +repair/Makefile +repair/README +repair/agheader.c +repair/agheader.h +repair/attr_repair.c +repair/attr_repair.h +repair/avl.c +repair/avl.h +repair/avl64.c +repair/avl64.h +repair/bmap.c +repair/bmap.h +repair/btree.c +repair/btree.h +repair/dino_chunks.c +repair/dinode.c +repair/dinode.h +repair/dir2.c +repair/dir2.h +repair/err_protos.h +repair/globals.c +repair/globals.h +repair/incore.c +repair/incore.h +repair/incore_bmc.c +repair/incore_ext.c +repair/incore_ino.c +repair/init.c +repair/phase1.c +repair/phase2.c +repair/phase3.c +repair/phase4.c +repair/phase5.c +repair/phase6.c +repair/phase7.c +repair/prefetch.c +repair/prefetch.h +repair/progress.c +repair/progress.h +repair/protos.h +repair/rt.c +repair/rt.h +repair/sb.c +repair/scan.c +repair/scan.h +repair/threads.c +repair/threads.h +repair/versions.c +repair/versions.h +repair/xfs_repair.c +rtcp/Makefile +rtcp/xfs_rtcp.c diff -Nru xfsprogs-3.1.9ubuntu2/.gitignore xfsprogs-3.2.1ubuntu1/.gitignore --- xfsprogs-3.1.9ubuntu2/.gitignore 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/.gitignore 2014-05-02 00:09:15.000000000 +0000 @@ -0,0 +1,74 @@ +# object files +*.o +.dep +.ltdep + +# build system +.census +.gitcensus +/include/platform_defs.h +/include/builddefs +/install-sh + +# magic directory symlinks +/include/disk +/include/xfs + +# packaging +/doc/CHANGES.gz +/xfsprogs-* +/xfsprogs_* +/xfslibs-dev_* + +# autoconf generated files +/aclocal.m4 +/m4/libtool.m4 +/m4/ltoptions.m4 +/m4/ltsugar.m4 +/m4/ltversion.m4 +/m4/lt~obsolete.m4 +/autom4te.cache/ +/config.guess +/config.log +/config.status +/config.sub +/configure + +# libtool +/libtool +/ltmain.sh +*.lo +*.la +.libs + +# gettext +/po/de.mo +/po/pl.mo +/po/xfsprogs.pot + +# cscope stuff +cscope.* + +# quilt stuff +/.pc/ +/patches/ + +# binaries +/copy/xfs_copy +/db/xfs_db +/estimate/xfs_estimate +/fsr/xfs_fsr +/growfs/xfs_growfs +/io/xfs_io +/logprint/xfs_logprint +/mdrestore/xfs_mdrestore +/mkfs/fstyp +/mkfs/mkfs.xfs +/quota/xfs_quota +/repair/xfs_repair +/rtcp/xfs_rtcp + +# generated crc files +/libxfs/crc32selftest +/libxfs/crc32table.h +/libxfs/gen_crc32table diff -Nru xfsprogs-3.1.9ubuntu2/growfs/xfs_growfs.c xfsprogs-3.2.1ubuntu1/growfs/xfs_growfs.c --- xfsprogs-3.1.9ubuntu2/growfs/xfs_growfs.c 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/growfs/xfs_growfs.c 2014-06-19 22:42:17.000000000 +0000 @@ -19,14 +19,6 @@ #include #include -/* - * When growing a filesystem, this is the most significant - * bits we'll accept in the resulting inode numbers - * without warning the user. - */ - -#define XFS_MAX_INODE_SIG_BITS 32 - static void usage(void) { @@ -37,7 +29,6 @@ -l grow log section\n\ -r grow realtime section\n\ -n don't change anything, just show geometry\n\ - -I allow inode numbers to exceed %d significant bits\n\ -i convert log from external to internal format\n\ -t alternate location for mount table (/etc/mtab)\n\ -x convert log from internal to external format\n\ @@ -47,7 +38,7 @@ -e size set realtime extent size to size blks\n\ -m imaxpct set inode max percent to imaxpct\n\ -V print version information\n"), - progname, XFS_MAX_INODE_SIG_BITS); + progname); exit(2); } @@ -62,24 +53,30 @@ int dirversion, int logversion, int attrversion, - int cimode) + int projid32bit, + int crcs_enabled, + int cimode, + int ftype_enabled, + int finobt_enabled) { printf(_( "meta-data=%-22s isize=%-6u agcount=%u, agsize=%u blks\n" - " =%-22s sectsz=%-5u attr=%u\n" + " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" + " =%-22s crc=%-8u finobt=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" - "naming =version %-14u bsize=%-6u ascii-ci=%d\n" + "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n" "log =%-22s bsize=%-6u blocks=%u, version=%u\n" " =%-22s sectsz=%-5u sunit=%u blks, lazy-count=%u\n" "realtime =%-22s extsz=%-6u blocks=%llu, rtextents=%llu\n"), mntpoint, geo.inodesize, geo.agcount, geo.agblocks, - "", geo.sectsize, attrversion, + "", geo.sectsize, attrversion, projid32bit, + "", crcs_enabled, finobt_enabled, "", geo.blocksize, (unsigned long long)geo.datablocks, geo.imaxpct, "", geo.sunit, geo.swidth, - dirversion, geo.dirblocksize, cimode, + dirversion, geo.dirblocksize, cimode, ftype_enabled, isint ? _("internal") : logname ? logname : _("external"), geo.blocksize, geo.logblocks, logversion, "", geo.logsectsize, geo.logsunit / geo.blocksize, lazycount, @@ -124,6 +121,10 @@ char *rtdev; /* RT device name */ fs_path_t *fs; /* mount point information */ libxfs_init_t xi; /* libxfs structure */ + int projid32bit; + int crcs_enabled; + int ftype_enabled = 0; + int finobt_enabled; /* free inode btree */ progname = basename(argv[0]); setlocale(LC_ALL, ""); @@ -133,7 +134,6 @@ maxpct = esize = 0; dsize = lsize = rsize = 0LL; aflag = dflag = iflag = lflag = mflag = nflag = rflag = xflag = 0; - ci = 0; while ((c = getopt(argc, argv, "dD:e:ilL:m:np:rR:t:xV")) != EOF) { switch (c) { @@ -190,7 +190,7 @@ usage(); if (iflag && xflag) usage(); - if (dflag + lflag + rflag == 0) + if (dflag + lflag + rflag + mflag == 0) aflag = 1; fs_table_initialise(0, NULL, 0, NULL); @@ -243,10 +243,15 @@ attrversion = geo.flags & XFS_FSOP_GEOM_FLAGS_ATTR2 ? 2 : \ (geo.flags & XFS_FSOP_GEOM_FLAGS_ATTR ? 1 : 0); ci = geo.flags & XFS_FSOP_GEOM_FLAGS_DIRV2CI ? 1 : 0; + projid32bit = geo.flags & XFS_FSOP_GEOM_FLAGS_PROJID32 ? 1 : 0; + crcs_enabled = geo.flags & XFS_FSOP_GEOM_FLAGS_V5SB ? 1 : 0; + ftype_enabled = geo.flags & XFS_FSOP_GEOM_FLAGS_FTYPE ? 1 : 0; + finobt_enabled = geo.flags & XFS_FSOP_GEOM_FLAGS_FINOBT ? 1 : 0; if (nflag) { report_info(geo, datadev, isint, logdev, rtdev, lazycount, dirversion, logversion, - attrversion, ci); + attrversion, projid32bit, crcs_enabled, ci, + ftype_enabled, finobt_enabled); exit(0); } @@ -283,7 +288,8 @@ report_info(geo, datadev, isint, logdev, rtdev, lazycount, dirversion, logversion, - attrversion, ci); + attrversion, projid32bit, crcs_enabled, ci, ftype_enabled, + finobt_enabled); ddsize = xi.dsize; dlsize = ( xi.logBBsize? xi.logBBsize : @@ -302,12 +308,15 @@ drsize -= (drsize % 2); error = 0; - if (dflag | aflag) { + + if (dflag | mflag | aflag) { xfs_growfs_data_t in; if (!mflag) maxpct = geo.imaxpct; - if (!dsize) + if (!dflag && !aflag) /* Only mflag, no data size change */ + dsize = geo.datablocks; + else if (!dsize) dsize = ddsize / (geo.blocksize / BBSIZE); else if (dsize > ddsize / (geo.blocksize / BBSIZE)) { fprintf(stderr, _( diff -Nru xfsprogs-3.1.9ubuntu2/include/bitops.h xfsprogs-3.2.1ubuntu1/include/bitops.h --- xfsprogs-3.1.9ubuntu2/include/bitops.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/bitops.h 2014-05-02 00:09:15.000000000 +0000 @@ -28,7 +28,6 @@ r -= 2; } if (!(x & 0x80000000u)) { - x <<= 1; r -= 1; } return r; diff -Nru xfsprogs-3.1.9ubuntu2/include/builddefs.in xfsprogs-3.2.1ubuntu1/include/builddefs.in --- xfsprogs-3.1.9ubuntu2/include/builddefs.in 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/builddefs.in 2013-10-10 21:07:17.000000000 +0000 @@ -103,12 +103,16 @@ HAVE_FIEMAP = @have_fiemap@ HAVE_PREADV = @have_preadv@ HAVE_SYNC_FILE_RANGE = @have_sync_file_range@ +HAVE_READDIR = @have_readdir@ GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall # -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-decl ifeq ($(PKG_PLATFORM),linux) PCFLAGS = -D_GNU_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=500 -D_FILE_OFFSET_BITS=64 $(GCCFLAGS) +ifeq ($(HAVE_UMODE_T),yes) +PCFLAGS += -DHAVE_UMODE_T +endif DEPENDFLAGS = -D__linux__ endif ifeq ($(PKG_PLATFORM),gnukfreebsd) diff -Nru xfsprogs-3.1.9ubuntu2/include/buildrules xfsprogs-3.2.1ubuntu1/include/buildrules --- xfsprogs-3.1.9ubuntu2/include/buildrules 2010-08-18 03:32:44.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/buildrules 2014-05-02 00:09:15.000000000 +0000 @@ -23,17 +23,6 @@ $(Q)$(MAKE) $(MAKEOPTS) -q -C $@ || $(MAKE) $(MAKEOPTS) -C $@ endif -source-link: - @test -z "$$DIR" && DIR="."; \ - for f in `echo $(SRCFILES) $(SUBDIRS) $(POTHEAD)`; do \ - if test -d $$f ; then \ - mkdir $(TOPDIR)/$(PKG_NAME)-$(PKG_VERSION)/$$DIR/$$f || exit $$?; \ - $(MAKEF) DIR=$$DIR/$$f -C $$f $@ || exit $$?; \ - else \ - ln $$f $(TOPDIR)/$(PKG_NAME)-$(PKG_VERSION)/$$DIR/$$f || exit $$?; \ - fi; \ - done - # # Standard targets # @@ -90,18 +79,30 @@ $(_FORCE): # dependency build is automatic, relies on gcc -MM to generate. +# +# This is a bit messy. It regenerates the dependencies on each build so +# that we catch files being added and removed. There are other ways of doing +# this (e.g. per-file dependency files) but that requires more in-depth changes +# to the build system. Compile time is not an issue for us, so the +# rebuild on every make invocation isn't a problem we need to care about. Just +# do it silently so it doesn't make the build unnecessarily noisy. + .PHONY : depend ltdepend install-qa MAKEDEP := $(MAKEDEPEND) $(CFLAGS) -ltdepend: .ltdep +ltdepend: rmltdep .ltdep + +rmltdep: + @rm -f .ltdep .ltdep: $(CFILES) $(HFILES) - @echo " [LTDEP]" $(Q)$(MAKEDEP) $(CFILES) | $(SED) -e 's,^\([^:]*\)\.o,\1.lo,' > .ltdep -depend: .dep +depend: rmdep .dep + +rmdep: + @rm -f .dep .dep: $(CFILES) $(HFILES) - @echo " [DEP]" $(Q)$(MAKEDEP) $(CFILES) > .dep diff -Nru xfsprogs-3.1.9ubuntu2/include/cache.h xfsprogs-3.2.1ubuntu1/include/cache.h --- xfsprogs-3.1.9ubuntu2/include/cache.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/cache.h 2014-05-02 00:09:15.000000000 +0000 @@ -18,6 +18,25 @@ #ifndef __CACHE_H__ #define __CACHE_H__ +/* + * initialisation flags + */ +/* + * xfs_db always writes changes immediately, and so we need to purge buffers + * when we get a buffer lookup mismatch due to reading the same block with a + * different buffer configuration. + */ +#define CACHE_MISCOMPARE_PURGE (1 << 0) + +/* + * cache object campare return values + */ +enum { + CACHE_HIT, + CACHE_MISS, + CACHE_PURGE, +}; + #define HASH_CACHE_RATIO 8 /* @@ -47,7 +66,8 @@ typedef struct cache_node * (*cache_node_alloc_t)(cache_key_t); typedef void (*cache_node_flush_t)(struct cache_node *); typedef void (*cache_node_relse_t)(struct cache_node *); -typedef unsigned int (*cache_node_hash_t)(cache_key_t, unsigned int); +typedef unsigned int (*cache_node_hash_t)(cache_key_t, unsigned int, + unsigned int); typedef int (*cache_node_compare_t)(struct cache_node *, cache_key_t); typedef unsigned int (*cache_bulk_relse_t)(struct cache *, struct list_head *); @@ -82,6 +102,7 @@ }; struct cache { + int c_flags; /* behavioural flags */ unsigned int c_maxcount; /* max cache nodes */ unsigned int c_count; /* count of nodes */ pthread_mutex_t c_mutex; /* node count mutex */ @@ -92,6 +113,7 @@ cache_node_compare_t compare; /* comparison routine */ cache_bulk_relse_t bulkrelse; /* bulk release routine */ unsigned int c_hashsize; /* hash bucket count */ + unsigned int c_hashshift; /* hash key shift */ struct cache_hash *c_hash; /* hash table buckets */ struct cache_mru c_mrus[CACHE_MAX_PRIORITY + 1]; unsigned long long c_misses; /* cache misses */ @@ -99,7 +121,7 @@ unsigned int c_max; /* max nodes ever used */ }; -struct cache *cache_init(unsigned int, struct cache_operations *); +struct cache *cache_init(int, unsigned int, struct cache_operations *); void cache_destroy(struct cache *); void cache_walk(struct cache *, cache_walk_t); void cache_purge(struct cache *); diff -Nru xfsprogs-3.1.9ubuntu2/include/darwin.h xfsprogs-3.2.1ubuntu1/include/darwin.h --- xfsprogs-3.1.9ubuntu2/include/darwin.h 2009-12-06 20:58:01.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/darwin.h 2014-05-02 00:09:15.000000000 +0000 @@ -150,6 +150,7 @@ #define ENOATTR 989 /* Attribute not found */ #define EFSCORRUPTED 990 /* Filesystem is corrupted */ +#define EFSBADCRC 991 /* Bad CRC detected */ #define constpp char * const * #define HAVE_FID 1 diff -Nru xfsprogs-3.1.9ubuntu2/include/freebsd.h xfsprogs-3.2.1ubuntu1/include/freebsd.h --- xfsprogs-3.1.9ubuntu2/include/freebsd.h 2009-12-06 20:58:01.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/freebsd.h 2014-05-02 00:09:15.000000000 +0000 @@ -45,6 +45,7 @@ #define constpp char * const * #define EFSCORRUPTED 990 /* Filesystem is corrupted */ +#define EFSBADCRC 991 /* Bad CRC detected */ typedef off_t xfs_off_t; typedef off_t off64_t; diff -Nru xfsprogs-3.1.9ubuntu2/include/gnukfreebsd.h xfsprogs-3.2.1ubuntu1/include/gnukfreebsd.h --- xfsprogs-3.1.9ubuntu2/include/gnukfreebsd.h 2010-05-10 01:17:21.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/gnukfreebsd.h 2014-05-02 00:09:15.000000000 +0000 @@ -36,6 +36,7 @@ #define constpp char * const * #define EFSCORRUPTED 990 /* Filesystem is corrupted */ +#define EFSBADCRC 991 /* Bad CRC detected */ typedef off_t xfs_off_t; typedef __uint64_t xfs_ino_t; diff -Nru xfsprogs-3.1.9ubuntu2/include/input.h xfsprogs-3.2.1ubuntu1/include/input.h --- xfsprogs-3.1.9ubuntu2/include/input.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/input.h 2013-06-06 22:52:59.000000000 +0000 @@ -22,6 +22,7 @@ #include #include #include +#include extern char **breakline(char *input, int *count); extern void doneline(char *input, char **vec); @@ -46,6 +47,7 @@ extern uid_t uid_from_string(char *user); extern gid_t gid_from_string(char *group); extern prid_t prid_from_string(char *project); +extern bool isdigits_only(const char *str); #define HAVE_FTW_H 1 /* TODO: configure me */ diff -Nru xfsprogs-3.1.9ubuntu2/include/irix.h xfsprogs-3.2.1ubuntu1/include/irix.h --- xfsprogs-3.1.9ubuntu2/include/irix.h 2009-12-06 20:58:01.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/irix.h 2014-05-02 00:09:15.000000000 +0000 @@ -52,6 +52,8 @@ #define xfs_flock64 flock64 #define xfs_flock64_t struct flock64 +#define EFSBADCRC 991 /* Bad CRC detected */ + typedef struct xfs_error_injection { __int32_t fd; __int32_t errtag; diff -Nru xfsprogs-3.1.9ubuntu2/include/libxfs.h xfsprogs-3.2.1ubuntu1/include/libxfs.h --- xfsprogs-3.1.9ubuntu2/include/libxfs.h 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/libxfs.h 2014-07-21 09:13:53.000000000 +0000 @@ -33,32 +33,34 @@ #include #include -#include #include +#include #include + +#include +#include +#include +#include +#include + #include #include #include #include -#include -#include -#include #include #include #include -#include -#include #include #include -#include -#include -#include +#include +#include #include #include #include #include #include + #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #endif @@ -108,6 +110,8 @@ int dfd; /* data subvolume file descriptor */ int logfd; /* log subvolume file descriptor */ int rtfd; /* realtime subvolume file descriptor */ + int icache_flags; /* cache init flags */ + int bcache_flags; /* cache init flags */ } libxfs_init_t; #define LIBXFS_EXIT_ON_FAILURE 0x0001 /* exit the program if a call fails */ @@ -117,22 +121,36 @@ #define LIBXFS_EXCLUSIVELY 0x0010 /* disallow other accesses (O_EXCL) */ #define LIBXFS_DIRECT 0x0020 /* can use direct I/O, not buffered */ +/* + * IO verifier callbacks need the xfs_mount pointer, so we have to behave + * somewhat like the kernel now for userspace IO in terms of having buftarg + * based devices... + */ +struct xfs_buftarg { + struct xfs_mount *bt_mount; + dev_t dev; +}; + +extern void libxfs_buftarg_init(struct xfs_mount *mp, dev_t ddev, + dev_t logdev, dev_t rtdev); + extern char *progname; extern int libxfs_init (libxfs_init_t *); extern void libxfs_destroy (void); extern int libxfs_device_to_fd (dev_t); extern dev_t libxfs_device_open (char *, int, int, int); -extern void libxfs_device_zero (dev_t, xfs_daddr_t, uint); +extern void libxfs_device_zero(struct xfs_buftarg *, xfs_daddr_t, uint); extern void libxfs_device_close (dev_t); extern int libxfs_device_alignment (void); extern void libxfs_report(FILE *); extern void platform_findsizes(char *path, int fd, long long *sz, int *bsz); +extern int platform_nproc(void); /* check or write log footer: specify device, log size in blocks & uuid */ typedef xfs_caddr_t (libxfs_get_block_t)(xfs_caddr_t, int, void *); -extern int libxfs_log_clear (dev_t, xfs_daddr_t, uint, uuid_t *, - int, int, int); +extern int libxfs_log_clear (struct xfs_buftarg *, xfs_daddr_t, uint, + uuid_t *, int, int, int); extern int libxfs_log_header (xfs_caddr_t, uuid_t *, int, int, int, libxfs_get_block_t *, void *); @@ -152,17 +170,19 @@ uint m_rsumsize; /* size of rt summary, bytes */ struct xfs_inode *m_rbmip; /* pointer to bitmap inode */ struct xfs_inode *m_rsumip; /* pointer to summary inode */ - struct xfs_inode *m_rootip; /* pointer to root directory */ - dev_t m_dev; - dev_t m_logdev; - dev_t m_rtdev; + struct xfs_buftarg *m_ddev_targp; + struct xfs_buftarg *m_logdev_targp; + struct xfs_buftarg *m_rtdev_targp; +#define m_dev m_ddev_targp +#define m_logdev m_logdev_targp +#define m_rtdev m_rtdev_targp __uint8_t m_dircook_elog; /* log d-cookie entry bits */ __uint8_t m_blkbit_log; /* blocklog + NBBY */ __uint8_t m_blkbb_log; /* blocklog - BBSHIFT */ __uint8_t m_sectbb_log; /* sectorlog - BBSHIFT */ __uint8_t m_agno_log; /* log #ag's */ __uint8_t m_agino_log; /* #bits for agino in inum */ - __uint16_t m_inode_cluster_size;/* min inode buf size */ + uint m_inode_cluster_size;/* min inode buf size */ uint m_blockmask; /* sb_blocksize-1 */ uint m_blockwsize; /* sb_blocksize in words */ uint m_blockwmask; /* blockwsize-1 */ @@ -185,7 +205,7 @@ int m_ialloc_blks; /* blocks in inode allocation */ int m_litino; /* size of inode union area */ int m_inoalign_mask;/* mask sb_inoalignmt if used */ - xfs_trans_reservations_t m_reservations;/* precomputed res values */ + struct xfs_trans_resv m_resv; /* precomputed res values */ __uint64_t m_maxicount; /* maximum inode count */ int m_dalign; /* stripe unit */ int m_swidth; /* stripe width */ @@ -198,16 +218,55 @@ xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ xfs_dablk_t m_dirleafblk; /* blockno of dir non-data v2 */ xfs_dablk_t m_dirfreeblk; /* blockno of dirfreeindex v2 */ + + /* + * anonymous struct to allow xfs_dquot_buf.c to compile. + * Pointer is always null in userspace, so code does not use it at all + */ + struct { + int qi_dqperchunk; + } *m_quotainfo; + } xfs_mount_t; -#define LIBXFS_MOUNT_ROOTINOS 0x0001 -#define LIBXFS_MOUNT_DEBUGGER 0x0002 -#define LIBXFS_MOUNT_32BITINODES 0x0004 -#define LIBXFS_MOUNT_32BITINOOPT 0x0008 -#define LIBXFS_MOUNT_COMPAT_ATTR 0x0010 -#define LIBXFS_MOUNT_ATTR2 0x0020 +/* + * Per-ag incore structure, copies of information in agf and agi, + * to improve the performance of allocation group selection. + */ +typedef struct xfs_perag { + struct xfs_mount *pag_mount; /* owner filesystem */ + xfs_agnumber_t pag_agno; /* AG this structure belongs to */ + atomic_t pag_ref; /* perag reference count */ + char pagf_init; /* this agf's entry is initialized */ + char pagi_init; /* this agi's entry is initialized */ + char pagf_metadata; /* the agf is preferred to be metadata */ + char pagi_inodeok; /* The agi is ok for inodes */ + __uint8_t pagf_levels[XFS_BTNUM_AGF]; + /* # of levels in bno & cnt btree */ + __uint32_t pagf_flcount; /* count of blocks in freelist */ + xfs_extlen_t pagf_freeblks; /* total free blocks */ + xfs_extlen_t pagf_longest; /* longest free space */ + __uint32_t pagf_btreeblks; /* # of blocks held in AGF btrees */ + xfs_agino_t pagi_freecount; /* number of free inodes */ + xfs_agino_t pagi_count; /* number of allocated inodes */ + + /* + * Inode allocation search lookup optimisation. + * If the pagino matches, the search for new inodes + * doesn't need to search the near ones again straight away + */ + xfs_agino_t pagl_pagino; + xfs_agino_t pagl_leftrec; + xfs_agino_t pagl_rightrec; + int pagb_count; /* pagb slots in use */ +} xfs_perag_t; + +#define LIBXFS_MOUNT_DEBUGGER 0x0001 +#define LIBXFS_MOUNT_32BITINODES 0x0002 +#define LIBXFS_MOUNT_32BITINOOPT 0x0004 +#define LIBXFS_MOUNT_COMPAT_ATTR 0x0008 +#define LIBXFS_MOUNT_ATTR2 0x0010 -#define LIBXFS_IHASHSIZE(sbp) (1<<10) #define LIBXFS_BHASHSIZE(sbp) (1<<10) extern xfs_mount_t *libxfs_mount (xfs_mount_t *, xfs_sb_t *, @@ -215,24 +274,51 @@ extern void libxfs_umount (xfs_mount_t *); extern void libxfs_rtmount_destroy (xfs_mount_t *); +/* + * xfs/xfs_da_format.h needs struct xfs_mount to be defined + */ +#include +#include +#include /* * Simple I/O interface */ +#define XB_PAGES 2 + +struct xfs_buf_map { + xfs_daddr_t bm_bn; /* block number for I/O */ + int bm_len; /* size of I/O */ +}; + +#define DEFINE_SINGLE_BUF_MAP(map, blkno, numblk) \ + struct xfs_buf_map (map) = { .bm_bn = (blkno), .bm_len = (numblk) }; + +struct xfs_buf_ops { + void (*verify_read)(struct xfs_buf *); + void (*verify_write)(struct xfs_buf *); +}; + typedef struct xfs_buf { struct cache_node b_node; unsigned int b_flags; - xfs_daddr_t b_blkno; + xfs_daddr_t b_bn; unsigned b_bcount; - dev_t b_dev; + unsigned int b_length; + struct xfs_buftarg *b_target; +#define b_dev b_target->dev pthread_mutex_t b_lock; pthread_t b_holder; unsigned int b_recur; - void *b_fsprivate; + void *b_fspriv; void *b_fsprivate2; void *b_fsprivate3; - char *b_addr; + void *b_addr; int b_error; + const struct xfs_buf_ops *b_ops; + struct xfs_perag *b_pag; + struct xfs_buf_map *b_map; + int b_nmaps; #ifdef XFS_BUF_TRACING struct list_head b_lock_list; const char *b_func; @@ -245,12 +331,16 @@ LIBXFS_B_EXIT = 0x0001, /* ==LIBXFS_EXIT_ON_FAILURE */ LIBXFS_B_DIRTY = 0x0002, /* buffer has been modified */ LIBXFS_B_STALE = 0x0004, /* buffer marked as invalid */ - LIBXFS_B_UPTODATE = 0x0008 /* buffer is sync'd to disk */ + LIBXFS_B_UPTODATE = 0x0008, /* buffer is sync'd to disk */ + LIBXFS_B_DISCONTIG = 0x0010, /* discontiguous buffer */ + LIBXFS_B_UNCHECKED = 0x0020, /* needs verification */ }; -#define XFS_BUF_PTR(bp) ((bp)->b_addr) +#define XFS_BUF_DADDR_NULL ((xfs_daddr_t) (-1LL)) + +#define XFS_BUF_PTR(bp) ((char *)(bp)->b_addr) #define xfs_buf_offset(bp, offset) (XFS_BUF_PTR(bp) + (offset)) -#define XFS_BUF_ADDR(bp) ((bp)->b_blkno) +#define XFS_BUF_ADDR(bp) ((bp)->b_bn) #define XFS_BUF_SIZE(bp) ((bp)->b_bcount) #define XFS_BUF_COUNT(bp) ((bp)->b_bcount) #define XFS_BUF_TARGET(bp) ((bp)->b_dev) @@ -259,11 +349,11 @@ XFS_BUF_SET_COUNT(bp,cnt); \ }) -#define XFS_BUF_SET_ADDR(bp,blk) ((bp)->b_blkno = (blk)) +#define XFS_BUF_SET_ADDR(bp,blk) ((bp)->b_bn = (blk)) #define XFS_BUF_SET_COUNT(bp,cnt) ((bp)->b_bcount = (cnt)) -#define XFS_BUF_FSPRIVATE(bp,type) ((type)(bp)->b_fsprivate) -#define XFS_BUF_SET_FSPRIVATE(bp,val) (bp)->b_fsprivate = (void *)(val) +#define XFS_BUF_FSPRIVATE(bp,type) ((type)(bp)->b_fspriv) +#define XFS_BUF_SET_FSPRIVATE(bp,val) (bp)->b_fspriv = (void *)(val) #define XFS_BUF_FSPRIVATE2(bp,type) ((type)(bp)->b_fsprivate2) #define XFS_BUF_SET_FSPRIVATE2(bp,val) (bp)->b_fsprivate2 = (void *)(val) #define XFS_BUF_FSPRIVATE3(bp,type) ((type)(bp)->b_fsprivate3) @@ -275,6 +365,13 @@ (pri)) #define XFS_BUF_PRIORITY(bp) (cache_node_get_priority( \ (struct cache_node *)(bp))) +#define xfs_buf_set_ref(bp,ref) ((void) 0) +#define xfs_buf_ioerror(bp,err) ((bp)->b_error = (err)) + +#define xfs_daddr_to_agno(mp,d) \ + ((xfs_agnumber_t)(XFS_BB_TO_FSBT(mp, d) / (mp)->m_sb.sb_agblocks)) +#define xfs_daddr_to_agbno(mp,d) \ + ((xfs_agblock_t)(XFS_BB_TO_FSBT(mp, d) % (mp)->m_sb.sb_agblocks)) /* Buffer Cache Interfaces */ @@ -285,41 +382,62 @@ #ifdef XFS_BUF_TRACING -#define libxfs_readbuf(dev, daddr, len, flags) \ +#define libxfs_readbuf(dev, daddr, len, flags, ops) \ libxfs_trace_readbuf(__FUNCTION__, __FILE__, __LINE__, \ - (dev), (daddr), (len), (flags)) + (dev), (daddr), (len), (flags), (ops)) +#define libxfs_readbuf_map(dev, map, nmaps, flags, ops) \ + libxfs_trace_readbuf_map(__FUNCTION__, __FILE__, __LINE__, \ + (dev), (map), (nmaps), (flags), (ops)) #define libxfs_writebuf(buf, flags) \ libxfs_trace_writebuf(__FUNCTION__, __FILE__, __LINE__, \ (buf), (flags)) #define libxfs_getbuf(dev, daddr, len) \ libxfs_trace_getbuf(__FUNCTION__, __FILE__, __LINE__, \ (dev), (daddr), (len)) +#define libxfs_getbuf_map(dev, map, nmaps, flags) \ + libxfs_trace_getbuf_map(__FUNCTION__, __FILE__, __LINE__, \ + (dev), (map), (nmaps), (flags)) #define libxfs_getbuf_flags(dev, daddr, len, flags) \ - libxfs_trace_getbuf(__FUNCTION__, __FILE__, __LINE__, \ + libxfs_trace_getbuf_flags(__FUNCTION__, __FILE__, __LINE__, \ (dev), (daddr), (len), (flags)) #define libxfs_putbuf(buf) \ libxfs_trace_putbuf(__FUNCTION__, __FILE__, __LINE__, (buf)) extern xfs_buf_t *libxfs_trace_readbuf(const char *, const char *, int, - dev_t, xfs_daddr_t, int, int); + struct xfs_buftarg *, xfs_daddr_t, int, int, + const struct xfs_buf_ops *); +extern xfs_buf_t *libxfs_trace_readbuf_map(const char *, const char *, int, + struct xfs_buftarg *, struct xfs_buf_map *, int, int, + const struct xfs_buf_ops *); extern int libxfs_trace_writebuf(const char *, const char *, int, xfs_buf_t *, int); -extern xfs_buf_t *libxfs_trace_getbuf(const char *, const char *, int, dev_t, xfs_daddr_t, int); +extern xfs_buf_t *libxfs_trace_getbuf(const char *, const char *, int, + struct xfs_buftarg *, xfs_daddr_t, int); +extern xfs_buf_t *libxfs_trace_getbuf_map(const char *, const char *, int, + struct xfs_buftarg *, struct xfs_buf_map *, int, int); extern xfs_buf_t *libxfs_trace_getbuf_flags(const char *, const char *, int, - dev_t, xfs_daddr_t, int, unsigned int); + struct xfs_buftarg *, xfs_daddr_t, int, unsigned int); extern void libxfs_trace_putbuf (const char *, const char *, int, xfs_buf_t *); #else -extern xfs_buf_t *libxfs_readbuf(dev_t, xfs_daddr_t, int, int); +extern xfs_buf_t *libxfs_readbuf(struct xfs_buftarg *, xfs_daddr_t, int, int, + const struct xfs_buf_ops *); +extern xfs_buf_t *libxfs_readbuf_map(struct xfs_buftarg *, struct xfs_buf_map *, + int, int, const struct xfs_buf_ops *); extern int libxfs_writebuf(xfs_buf_t *, int); -extern xfs_buf_t *libxfs_getbuf(dev_t, xfs_daddr_t, int); -extern xfs_buf_t *libxfs_getbuf_flags(dev_t, xfs_daddr_t, int, unsigned int); +extern xfs_buf_t *libxfs_getbuf(struct xfs_buftarg *, xfs_daddr_t, int); +extern xfs_buf_t *libxfs_getbuf_map(struct xfs_buftarg *, + struct xfs_buf_map *, int, int); +extern xfs_buf_t *libxfs_getbuf_flags(struct xfs_buftarg *, xfs_daddr_t, + int, unsigned int); extern void libxfs_putbuf (xfs_buf_t *); #endif +extern void libxfs_readbuf_verify(struct xfs_buf *bp, + const struct xfs_buf_ops *ops); extern xfs_buf_t *libxfs_getsb(xfs_mount_t *, int); extern void libxfs_bcache_purge(void); extern void libxfs_bcache_flush(void); @@ -328,14 +446,15 @@ extern int libxfs_bcache_usage(void); /* Buffer (Raw) Interfaces */ -extern xfs_buf_t *libxfs_getbufr(dev_t, xfs_daddr_t, int); +extern xfs_buf_t *libxfs_getbufr(struct xfs_buftarg *, xfs_daddr_t, int); extern void libxfs_putbufr(xfs_buf_t *); extern int libxfs_writebuf_int(xfs_buf_t *, int); -extern int libxfs_readbufr(dev_t, xfs_daddr_t, xfs_buf_t *, int, int); +extern int libxfs_writebufr(struct xfs_buf *); +extern int libxfs_readbufr(struct xfs_buftarg *, xfs_daddr_t, xfs_buf_t *, int, int); +extern int libxfs_readbufr_map(struct xfs_buftarg *, struct xfs_buf *, int); extern int libxfs_bhash_size; -extern int libxfs_ihash_size; #define LIBXFS_BREAD 0x1 #define LIBXFS_BWRITE 0x2 @@ -343,7 +462,6 @@ extern void libxfs_iomove (xfs_buf_t *, uint, int, void *, int); - /* * Transaction interface */ @@ -352,15 +470,16 @@ struct xfs_log_item_desc *li_desc; /* ptr to current desc*/ struct xfs_mount *li_mountp; /* ptr to fs mount */ uint li_type; /* item type */ + xfs_lsn_t li_lsn; } xfs_log_item_t; typedef struct xfs_inode_log_item { xfs_log_item_t ili_item; /* common portion */ struct xfs_inode *ili_inode; /* inode pointer */ unsigned short ili_flags; /* misc flags */ + unsigned int ili_fields; /* fields to be logged */ unsigned int ili_last_fields; /* fields when flushed*/ xfs_inode_log_format_t ili_format; /* logged structure */ - int ili_lock_flags; } xfs_inode_log_item_t; typedef struct xfs_buf_log_item { @@ -371,7 +490,23 @@ xfs_buf_log_format_t bli_format; /* in-log header */ } xfs_buf_log_item_t; -#include +#define XFS_BLI_DIRTY (1<<0) +#define XFS_BLI_HOLD (1<<1) +#define XFS_BLI_STALE (1<<2) +#define XFS_BLI_INODE_ALLOC_BUF (1<<3) + +typedef struct xfs_dq_logitem { + xfs_log_item_t qli_item; /* common portion */ + struct xfs_dquot *qli_dquot; /* dquot ptr */ + xfs_lsn_t qli_flush_lsn; /* lsn at last flush */ + xfs_dq_logformat_t qli_format; /* logged structure */ +} xfs_dq_logitem_t; + +typedef struct xfs_qoff_logitem { + xfs_log_item_t qql_item; /* common portion */ + struct xfs_qoff_logitem *qql_start_lip; /* qoff-start logitem, if any */ + xfs_qoff_logformat_t qql_format; /* logged structure */ +} xfs_qoff_logitem_t; typedef struct xfs_trans { unsigned int t_type; /* transaction type */ @@ -386,19 +521,20 @@ struct list_head t_items; /* first log item desc chunk */ } xfs_trans_t; +extern void xfs_trans_init(struct xfs_mount *); +extern int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *); + extern xfs_trans_t *libxfs_trans_alloc (xfs_mount_t *, int); extern xfs_trans_t *libxfs_trans_dup (xfs_trans_t *); -extern int libxfs_trans_reserve (xfs_trans_t *, uint,uint,uint,uint,uint); +extern int libxfs_trans_reserve(struct xfs_trans *, struct xfs_trans_res *, + uint, uint); extern int libxfs_trans_commit (xfs_trans_t *, uint); extern void libxfs_trans_cancel (xfs_trans_t *, int); -extern void libxfs_mod_sb (xfs_trans_t *, __int64_t); extern xfs_buf_t *libxfs_trans_getsb (xfs_trans_t *, xfs_mount_t *, int); extern int libxfs_trans_iget (xfs_mount_t *, xfs_trans_t *, xfs_ino_t, uint, uint, struct xfs_inode **); -extern void libxfs_trans_iput(xfs_trans_t *, struct xfs_inode *, uint); extern void libxfs_trans_ijoin (xfs_trans_t *, struct xfs_inode *, uint); -extern void libxfs_trans_ihold (xfs_trans_t *, struct xfs_inode *); extern void libxfs_trans_ijoin_ref(xfs_trans_t *, struct xfs_inode *, int); extern void libxfs_trans_log_inode (xfs_trans_t *, struct xfs_inode *, uint); @@ -409,11 +545,52 @@ extern void libxfs_trans_bhold (xfs_trans_t *, struct xfs_buf *); extern void libxfs_trans_log_buf (xfs_trans_t *, struct xfs_buf *, uint, uint); +/* extern xfs_buf_t *libxfs_trans_get_buf (xfs_trans_t *, dev_t, xfs_daddr_t, int, uint); extern int libxfs_trans_read_buf (xfs_mount_t *, xfs_trans_t *, dev_t, xfs_daddr_t, int, uint, struct xfs_buf **); +*/ +struct xfs_buf *libxfs_trans_get_buf_map(struct xfs_trans *tp, + struct xfs_buftarg *btp, + struct xfs_buf_map *map, int nmaps, + uint flags); + +static inline struct xfs_buf * +libxfs_trans_get_buf( + struct xfs_trans *tp, + struct xfs_buftarg *btp, + xfs_daddr_t blkno, + int numblks, + uint flags) +{ + DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); + return libxfs_trans_get_buf_map(tp, btp, &map, 1, flags); +} + +int libxfs_trans_read_buf_map(struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_buftarg *btp, + struct xfs_buf_map *map, int nmaps, + uint flags, struct xfs_buf **bpp, + const struct xfs_buf_ops *ops); + +static inline int +libxfs_trans_read_buf( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_buftarg *btp, + xfs_daddr_t blkno, + int numblks, + uint flags, + struct xfs_buf **bpp, + const struct xfs_buf_ops *ops) +{ + DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); + return libxfs_trans_read_buf_map(mp, tp, btp, &map, 1, + flags, bpp, ops); +} /* * Inode interface @@ -423,7 +600,7 @@ xfs_mount_t *i_mount; /* fs mount struct ptr */ xfs_ino_t i_ino; /* inode number (agno/agino) */ struct xfs_imap i_imap; /* location for xfs_imap() */ - dev_t i_dev; /* dev for this inode */ + struct xfs_buftarg i_dev; /* dev for this inode */ xfs_ifork_t *i_afp; /* attribute fork pointer */ xfs_ifork_t i_df; /* data fork */ xfs_trans_t *i_transp; /* ptr to owning transaction */ @@ -438,6 +615,27 @@ #define LIBXFS_ATTR_CREATE 0x0010 /* create, but fail if attr exists */ #define LIBXFS_ATTR_REPLACE 0x0020 /* set, but fail if attr not exists */ +/* + * Project quota id helpers (previously projid was 16bit only and using two + * 16bit values to hold new 32bit projid was chosen to retain compatibility with + * "old" filesystems). + * + * Copied here from xfs_inode.h because it has to be defined after the struct + * xfs_inode... + */ +static inline prid_t +xfs_get_projid(struct xfs_icdinode *id) +{ + return (prid_t)id->di_projid_hi << 16 | id->di_projid_lo; +} + +static inline void +xfs_set_projid(struct xfs_icdinode *id, prid_t projid) +{ + id->di_projid_hi = (__uint16_t) (projid >> 16); + id->di_projid_lo = (__uint16_t) (projid & 0xffff); +} + typedef struct cred { uid_t cr_uid; gid_t cr_gid; @@ -451,25 +649,13 @@ extern void libxfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int); extern int libxfs_iflush_int (xfs_inode_t *, xfs_buf_t *); -extern int libxfs_iread (xfs_mount_t *, xfs_trans_t *, xfs_ino_t, - xfs_inode_t *, xfs_daddr_t); /* Inode Cache Interfaces */ -extern struct cache *libxfs_icache; -extern struct cache_operations libxfs_icache_operations; -extern void libxfs_icache_purge (void); extern int libxfs_iget (xfs_mount_t *, xfs_trans_t *, xfs_ino_t, uint, xfs_inode_t **, xfs_daddr_t); -extern void libxfs_iput (xfs_inode_t *, uint); - -extern int xfs_imap_to_bp(xfs_mount_t *mp, xfs_trans_t *tp, struct xfs_imap *imap, - xfs_buf_t **bpp, uint buf_flags, uint iget_flags); +extern void libxfs_iput (xfs_inode_t *); -#include /* dirv1 support in db & repair */ -#include -#include -#include -#include +#define IRELE(ip) libxfs_iput(ip) /* Shared utility routines */ extern unsigned int libxfs_log2_roundup(unsigned int i); @@ -478,11 +664,6 @@ xfs_off_t, int, int); extern int libxfs_bmap_finish(xfs_trans_t **, xfs_bmap_free_t *, int *); -extern void libxfs_da_bjoin (xfs_trans_t *, xfs_dabuf_t *); -extern void libxfs_da_bhold (xfs_trans_t *, xfs_dabuf_t *); -extern int libxfs_da_read_bufr(xfs_trans_t *, xfs_inode_t *, xfs_dablk_t, - xfs_daddr_t, xfs_dabuf_t **, int); - extern void libxfs_fs_repair_cmn_err(int, struct xfs_mount *, char *, ...); extern void libxfs_fs_cmn_err(int, struct xfs_mount *, char *, ...); @@ -495,13 +676,10 @@ extern unsigned long libxfs_physmem(void); /* in kilobytes */ #include -#include #include -#include +#include #include -#include -#include #define XFS_INOBT_IS_FREE_DISK(rp,i) \ ((be64_to_cpu((rp)->ir_free) & XFS_INOBT_MASK(i)) != 0) @@ -523,7 +701,7 @@ /* xfs_bmap.c */ xfs_bmbt_rec_host_t *xfs_bmap_search_extents(xfs_inode_t *, xfs_fileoff_t, int, int *, xfs_extnum_t *, xfs_bmbt_irec_t *, - xfs_bmbt_irec_t *); + xfs_bmbt_irec_t *); void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); /* xfs_attr_leaf.h */ @@ -536,7 +714,8 @@ /* xfs_bmap.h */ #define libxfs_bmap_cancel xfs_bmap_cancel #define libxfs_bmap_last_offset xfs_bmap_last_offset -#define libxfs_bmapi xfs_bmapi +#define libxfs_bmapi_write xfs_bmapi_write +#define libxfs_bmapi_read xfs_bmapi_read #define libxfs_bunmapi xfs_bunmapi /* xfs_bmap_btree.h */ @@ -546,6 +725,7 @@ #define libxfs_da_brelse xfs_da_brelse #define libxfs_da_hashname xfs_da_hashname #define libxfs_da_shrink_inode xfs_da_shrink_inode +#define libxfs_da_read_buf xfs_da_read_buf /* xfs_dir2.h */ #define libxfs_dir_createname xfs_dir_createname @@ -566,15 +746,59 @@ /* xfs_inode.h */ #define libxfs_dinode_from_disk xfs_dinode_from_disk #define libxfs_dinode_to_disk xfs_dinode_to_disk +void xfs_dinode_from_disk(struct xfs_icdinode *, + struct xfs_dinode *); +#define libxfs_dinode_calc_crc xfs_dinode_calc_crc #define libxfs_idata_realloc xfs_idata_realloc #define libxfs_idestroy_fork xfs_idestroy_fork -/* xfs_mount.h */ +#define libxfs_dinode_verify xfs_dinode_verify +bool xfs_dinode_verify(struct xfs_mount *mp, xfs_ino_t ino, + struct xfs_dinode *dip); + +/* xfs_sb.h */ #define libxfs_mod_sb xfs_mod_sb #define libxfs_sb_from_disk xfs_sb_from_disk +#define libxfs_sb_quota_from_disk xfs_sb_quota_from_disk #define libxfs_sb_to_disk xfs_sb_to_disk +/* xfs_symlink.h */ +#define libxfs_symlink_blocks xfs_symlink_blocks +#define libxfs_symlink_hdr_ok xfs_symlink_hdr_ok + +/* xfs_trans_resv.h */ +#define libxfs_trans_resv_calc xfs_trans_resv_calc + /* xfs_rtalloc.c */ int libxfs_rtfree_extent(struct xfs_trans *, xfs_rtblock_t, xfs_extlen_t); +/* CRC wrappers */ + +extern uint32_t crc32_le(uint32_t crc, unsigned char const *p, size_t len); +extern uint32_t crc32c_le(uint32_t crc, unsigned char const *p, size_t len); + +#define crc32(c,p,l) crc32_le((c),(unsigned char const *)(p),(l)) +#define crc32c(c,p,l) crc32c_le((c),(unsigned char const *)(p),(l)) + +#include + +static inline int +xfs_buf_verify_cksum(struct xfs_buf *bp, unsigned long cksum_offset) +{ + return xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length), + cksum_offset); +} + +static inline void +xfs_buf_update_cksum(struct xfs_buf *bp, unsigned long cksum_offset) +{ + xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), + cksum_offset); +} + +#define xfs_notice(mp,fmt,args...) cmn_err(CE_NOTE,fmt, ## args) +#define xfs_warn(mp,fmt,args...) cmn_err(CE_WARN,fmt, ## args) +#define xfs_alert(mp,fmt,args...) cmn_err(CE_ALERT,fmt, ## args) +#define xfs_hex_dump(d,n) ((void) 0) + #endif /* __LIBXFS_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/libxlog.h xfsprogs-3.2.1ubuntu1/include/libxlog.h --- xfsprogs-3.1.9ubuntu2/include/libxlog.h 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/libxlog.h 2013-10-10 21:07:17.000000000 +0000 @@ -24,11 +24,11 @@ * xlog_t that we actually need to get our work done, avoiding * the need to define any exotic kernel types in userland. */ -typedef struct log { +struct xlog { xfs_lsn_t l_tail_lsn; /* lsn of 1st LR w/ unflush buffers */ xfs_lsn_t l_last_sync_lsn;/* lsn of last LR on disk */ xfs_mount_t *l_mp; /* mount point */ - dev_t l_dev; /* dev_t of log */ + struct xfs_buftarg *l_dev; /* dev_t of log */ xfs_daddr_t l_logBBstart; /* start block of log */ int l_logsize; /* size of log in bytes */ int l_logBBsize; /* size of log in 512 byte chunks */ @@ -45,18 +45,9 @@ uint l_sectbb_mask; /* sector size (in BBs) * alignment mask */ int l_sectBBsize; /* size of log sector in 512 byte chunks */ -} xlog_t; +}; #include -#include -#include -#include - -typedef union { - xlog_rec_header_t hic_header; - xlog_rec_ext_header_t hic_xheader; - char hic_sector[XLOG_HEADER_SIZE]; -} xlog_in_core_2_t; /* * macros mapping kernel code to user code @@ -74,7 +65,6 @@ #define XFS_CORRUPTION_ERROR(e,l,mp,m) ((void) 0) #define XFS_MOUNT_WAS_CLEAN 0x1 #define unlikely(x) (x) -#define min(a,b) ((a) < (b) ? (a) : (b)) extern void xlog_warn(char *fmt,...); extern void xlog_exit(char *fmt,...); @@ -88,34 +78,34 @@ /* libxfs parameters */ extern libxfs_init_t x; -extern struct xfs_buf *xlog_get_bp(xlog_t *, int); +extern struct xfs_buf *xlog_get_bp(struct xlog *, int); extern void xlog_put_bp(struct xfs_buf *); -extern int xlog_bread(xlog_t *log, xfs_daddr_t blk_no, int nbblks, +extern int xlog_bread(struct xlog *log, xfs_daddr_t blk_no, int nbblks, xfs_buf_t *bp, xfs_caddr_t *offset); -extern int xlog_bread_noalign(xlog_t *log, xfs_daddr_t blk_no, int nbblks, - xfs_buf_t *bp); +extern int xlog_bread_noalign(struct xlog *log, xfs_daddr_t blk_no, + int nbblks, xfs_buf_t *bp); -extern int xlog_find_zeroed(xlog_t *log, xfs_daddr_t *blk_no); -extern int xlog_find_cycle_start(xlog_t *log, xfs_buf_t *bp, +extern int xlog_find_zeroed(struct xlog *log, xfs_daddr_t *blk_no); +extern int xlog_find_cycle_start(struct xlog *log, xfs_buf_t *bp, xfs_daddr_t first_blk, xfs_daddr_t *last_blk, uint cycle); -extern int xlog_find_tail(xlog_t *log, xfs_daddr_t *head_blk, +extern int xlog_find_tail(struct xlog *log, xfs_daddr_t *head_blk, xfs_daddr_t *tail_blk); -extern int xlog_test_footer(xlog_t *log); -extern int xlog_recover(xlog_t *log, int readonly); +extern int xlog_test_footer(struct xlog *log); +extern int xlog_recover(struct xlog *log, int readonly); extern void xlog_recover_print_data(xfs_caddr_t p, int len); extern void xlog_recover_print_logitem(xlog_recover_item_t *item); extern void xlog_recover_print_trans_head(xlog_recover_t *tr); -extern int xlog_print_find_oldest(xlog_t *log, xfs_daddr_t *last_blk); +extern int xlog_print_find_oldest(struct xlog *log, xfs_daddr_t *last_blk); /* for transactional view */ extern void xlog_recover_print_trans_head(xlog_recover_t *tr); extern void xlog_recover_print_trans(xlog_recover_t *trans, struct list_head *itemq, int print); -extern int xlog_do_recovery_pass(xlog_t *log, xfs_daddr_t head_blk, +extern int xlog_do_recovery_pass(struct xlog *log, xfs_daddr_t head_blk, xfs_daddr_t tail_blk, int pass); -extern int xlog_recover_do_trans(xlog_t *log, xlog_recover_t *trans, +extern int xlog_recover_do_trans(struct xlog *log, xlog_recover_t *trans, int pass); extern int xlog_header_check_recover(xfs_mount_t *mp, xlog_rec_header_t *head); diff -Nru xfsprogs-3.1.9ubuntu2/include/linux.h xfsprogs-3.2.1ubuntu1/include/linux.h --- xfsprogs-3.1.9ubuntu2/include/linux.h 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/linux.h 2014-05-02 00:09:15.000000000 +0000 @@ -27,26 +27,45 @@ #include #include #include +#include static __inline__ int xfsctl(const char *path, int fd, int cmd, void *p) { return ioctl(fd, cmd, p); } +/* + * platform_test_xfs_*() implies that xfsctl will succeed on the file; + * on Linux, at least, special files don't get xfs file ops, + * so return 0 for those + */ + static __inline__ int platform_test_xfs_fd(int fd) { - struct statfs buf; - if (fstatfs(fd, &buf) < 0) + struct statfs statfsbuf; + struct stat statbuf; + + if (fstatfs(fd, &statfsbuf) < 0) + return 0; + if (fstat(fd, &statbuf) < 0) + return 0; + if (!S_ISREG(statbuf.st_mode) && !S_ISDIR(statbuf.st_mode)) return 0; - return (buf.f_type == 0x58465342); /* XFSB */ + return (statfsbuf.f_type == 0x58465342); /* XFSB */ } static __inline__ int platform_test_xfs_path(const char *path) { - struct statfs buf; - if (statfs(path, &buf) < 0) + struct statfs statfsbuf; + struct stat statbuf; + + if (statfs(path, &statfsbuf) < 0) + return 0; + if (stat(path, &statbuf) < 0) + return 0; + if (!S_ISREG(statbuf.st_mode) && !S_ISDIR(statbuf.st_mode)) return 0; - return (buf.f_type == 0x58465342); /* XFSB */ + return (statfsbuf.f_type == 0x58465342); /* XFSB */ } static __inline__ int platform_fstatfs(int fd, struct statfs *buf) @@ -117,6 +136,7 @@ #define ENOATTR ENODATA /* Attribute not found */ #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ +#define EFSBADCRC EBADMSG /* Bad CRC detected */ typedef loff_t xfs_off_t; typedef __uint64_t xfs_ino_t; diff -Nru xfsprogs-3.1.9ubuntu2/include/Makefile xfsprogs-3.2.1ubuntu1/include/Makefile --- xfsprogs-3.1.9ubuntu2/include/Makefile 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/Makefile 2014-05-02 00:09:15.000000000 +0000 @@ -23,16 +23,30 @@ swab.h \ xfs_ag.h xfs_alloc.h xfs_alloc_btree.h xfs_arch.h xfs_attr_leaf.h \ xfs_attr_sf.h xfs_bit.h xfs_bmap.h xfs_bmap_btree.h xfs_btree.h \ - xfs_btree_trace.h xfs_buf_item.h xfs_da_btree.h xfs_dinode.h \ - xfs_dir2.h xfs_dir2_block.h xfs_dir2_data.h xfs_dir2_leaf.h \ - xfs_dir2_node.h xfs_dir2_sf.h xfs_dir_leaf.h xfs_dir_sf.h \ - xfs_extfree_item.h xfs_ialloc.h xfs_ialloc_btree.h \ - xfs_inode.h xfs_inode_item.h xfs_inum.h \ - xfs_log.h xfs_log_priv.h xfs_log_recover.h xfs_metadump.h \ - xfs_mount.h xfs_quota.h xfs_rtalloc.h xfs_sb.h xfs_trace.h \ - xfs_trans.h xfs_trans_space.h xfs_types.h xfs_dfrag.h + xfs_attr_remote.h \ + xfs_btree_trace.h \ + xfs_cksum.h \ + xfs_da_btree.h \ + xfs_da_format.h \ + xfs_dinode.h \ + xfs_dir2.h \ + xfs_format.h \ + xfs_ialloc.h \ + xfs_ialloc_btree.h \ + xfs_inode_buf.h \ + xfs_inode_fork.h \ + xfs_inum.h \ + xfs_log_format.h \ + xfs_log_recover.h \ + xfs_metadump.h \ + xfs_quota_defs.h \ + xfs_sb.h \ + xfs_shared.h \ + xfs_trace.h \ + xfs_trans_resv.h \ + xfs_trans_space.h -HFILES = handle.h jdm.h xqm.h xfs.h xfs_fs.h +HFILES = handle.h jdm.h xqm.h xfs.h xfs_fs.h xfs_types.h HFILES += $(PKG_PLATFORM).h PHFILES = darwin.h freebsd.h irix.h linux.h gnukfreebsd.h DKHFILES = volume.h fstyp.h dvh.h diff -Nru xfsprogs-3.1.9ubuntu2/include/platform_defs.h.in xfsprogs-3.2.1ubuntu1/include/platform_defs.h.in --- xfsprogs-3.1.9ubuntu2/include/platform_defs.h.in 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/platform_defs.h.in 2013-10-10 21:07:17.000000000 +0000 @@ -34,6 +34,7 @@ #include #include #include +#include #undef HAVE___U32 #ifdef HAVE___U32 @@ -57,6 +58,10 @@ #define __force #endif +typedef __u16 __bitwise __le16; +typedef __u32 __bitwise __le32; +typedef __u64 __bitwise __le64; + typedef __u16 __bitwise __be16; typedef __u32 __bitwise __be32; typedef __u64 __bitwise __be64; @@ -118,6 +123,11 @@ # endif #endif +/* Check whether to define umode_t ourselves. */ +#ifndef HAVE_UMODE_T +typedef unsigned short umode_t; +#endif + /* Define if you want gettext (I18N) support */ #undef ENABLE_GETTEXT #ifdef ENABLE_GETTEXT @@ -163,4 +173,9 @@ #define __arch_pack #endif +#ifndef min +#define min(a,b) (((a)<(b))?(a):(b)) +#define max(a,b) (((a)>(b))?(a):(b)) +#endif + #endif /* __XFS_PLATFORM_DEFS_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/project.h xfsprogs-3.2.1ubuntu1/include/project.h --- xfsprogs-3.1.9ubuntu2/include/project.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/project.h 2013-06-06 22:52:59.000000000 +0000 @@ -20,10 +20,6 @@ #include -#if !defined(__sgi__) -typedef __uint32_t prid_t; -#endif - extern int setprojid(const char *__name, int __fd, prid_t __id); extern int getprojid(const char *__name, int __fd, prid_t *__id); diff -Nru xfsprogs-3.1.9ubuntu2/include/swab.h xfsprogs-3.2.1ubuntu1/include/swab.h --- xfsprogs-3.1.9ubuntu2/include/swab.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/swab.h 2013-10-10 21:07:17.000000000 +0000 @@ -96,15 +96,15 @@ */ # define __swab16(x) \ (__builtin_constant_p((__u16)(x)) ? \ - ___swab16((x)) : \ + ___constant_swab16((x)) : \ __fswab16((x))) # define __swab32(x) \ (__builtin_constant_p((__u32)(x)) ? \ - ___swab32((x)) : \ + ___constant_swab32((x)) : \ __fswab32((x))) # define __swab64(x) \ (__builtin_constant_p((__u64)(x)) ? \ - ___swab64((x)) : \ + ___constant_swab64((x)) : \ __fswab64((x))) @@ -153,4 +153,42 @@ (__extension__ ({__arch__swab64s(addr);})); } +static inline __uint16_t get_unaligned_be16(void *p) +{ + __uint8_t *__p = p; + return __p[0] << 8 | __p[1]; +} + +static inline __uint32_t get_unaligned_be32(void *p) +{ + __uint8_t *__p = p; + return __p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3]; +} + +static inline __uint64_t get_unaligned_be64(void *p) +{ + return (__uint64_t)get_unaligned_be32(p) << 32 | + get_unaligned_be32(p + 4); +} + +static inline void put_unaligned_be16(__uint16_t val, void *p) +{ + __uint8_t *__p = p; + *__p++ = val >> 8; + *__p++ = val; +} + +static inline void put_unaligned_be32(__uint32_t val, void *p) +{ + __uint8_t *__p = p; + put_unaligned_be16(val >> 16, __p); + put_unaligned_be16(val, __p + 2); +} + +static inline void put_unaligned_be64(__uint64_t val, void *p) +{ + put_unaligned_be32(val >> 32, p); + put_unaligned_be32(val, p + 4); +} + #endif /* SWAB_H */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_ag.h xfsprogs-3.2.1ubuntu1/include/xfs_ag.h --- xfsprogs-3.1.9ubuntu2/include/xfs_ag.h 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_ag.h 2014-06-19 22:42:17.000000000 +0000 @@ -30,6 +30,7 @@ #define XFS_AGF_MAGIC 0x58414746 /* 'XAGF' */ #define XFS_AGI_MAGIC 0x58414749 /* 'XAGI' */ +#define XFS_AGFL_MAGIC 0x5841464c /* 'XAFL' */ #define XFS_AGF_VERSION 1 #define XFS_AGI_VERSION 1 @@ -63,14 +64,33 @@ __be32 agf_spare0; /* spare field */ __be32 agf_levels[XFS_BTNUM_AGF]; /* btree levels */ __be32 agf_spare1; /* spare field */ + __be32 agf_flfirst; /* first freelist block's index */ __be32 agf_fllast; /* last freelist block's index */ __be32 agf_flcount; /* count of blocks in freelist */ __be32 agf_freeblks; /* total free blocks */ + __be32 agf_longest; /* longest free space */ __be32 agf_btreeblks; /* # of blocks held in AGF btrees */ + uuid_t agf_uuid; /* uuid of filesystem */ + + /* + * reserve some contiguous space for future logged fields before we add + * the unlogged fields. This makes the range logging via flags and + * structure offsets much simpler. + */ + __be64 agf_spare64[16]; + + /* unlogged fields, written during buffer writeback. */ + __be64 agf_lsn; /* last write sequence */ + __be32 agf_crc; /* crc of agf sector */ + __be32 agf_spare2; + + /* structure must be padded to 64 bit alignment */ } xfs_agf_t; +#define XFS_AGF_CRC_OFF offsetof(struct xfs_agf, agf_crc) + #define XFS_AGF_MAGICNUM 0x00000001 #define XFS_AGF_VERSIONNUM 0x00000002 #define XFS_AGF_SEQNO 0x00000004 @@ -83,7 +103,8 @@ #define XFS_AGF_FREEBLKS 0x00000200 #define XFS_AGF_LONGEST 0x00000400 #define XFS_AGF_BTREEBLKS 0x00000800 -#define XFS_AGF_NUM_BITS 12 +#define XFS_AGF_UUID 0x00001000 +#define XFS_AGF_NUM_BITS 13 #define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1) #define XFS_AGF_FLAGS \ @@ -98,12 +119,13 @@ { XFS_AGF_FLCOUNT, "FLCOUNT" }, \ { XFS_AGF_FREEBLKS, "FREEBLKS" }, \ { XFS_AGF_LONGEST, "LONGEST" }, \ - { XFS_AGF_BTREEBLKS, "BTREEBLKS" } + { XFS_AGF_BTREEBLKS, "BTREEBLKS" }, \ + { XFS_AGF_UUID, "UUID" } /* disk block (xfs_daddr_t) in the AG */ #define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log)) #define XFS_AGF_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp)) -#define XFS_BUF_TO_AGF(bp) ((xfs_agf_t *)XFS_BUF_PTR(bp)) +#define XFS_BUF_TO_AGF(bp) ((xfs_agf_t *)((bp)->b_addr)) extern int xfs_read_agf(struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, int flags, struct xfs_buf **bpp); @@ -130,6 +152,7 @@ __be32 agi_root; /* root of inode btree */ __be32 agi_level; /* levels in inode btree */ __be32 agi_freecount; /* number of free inodes */ + __be32 agi_newino; /* new inode just allocated */ __be32 agi_dirino; /* last directory inode chunk */ /* @@ -137,26 +160,41 @@ * still being referenced. */ __be32 agi_unlinked[XFS_AGI_UNLINKED_BUCKETS]; + + uuid_t agi_uuid; /* uuid of filesystem */ + __be32 agi_crc; /* crc of agi sector */ + __be32 agi_pad32; + __be64 agi_lsn; /* last write sequence */ + + __be32 agi_free_root; /* root of the free inode btree */ + __be32 agi_free_level;/* levels in free inode btree */ + + /* structure must be padded to 64 bit alignment */ } xfs_agi_t; -#define XFS_AGI_MAGICNUM 0x00000001 -#define XFS_AGI_VERSIONNUM 0x00000002 -#define XFS_AGI_SEQNO 0x00000004 -#define XFS_AGI_LENGTH 0x00000008 -#define XFS_AGI_COUNT 0x00000010 -#define XFS_AGI_ROOT 0x00000020 -#define XFS_AGI_LEVEL 0x00000040 -#define XFS_AGI_FREECOUNT 0x00000080 -#define XFS_AGI_NEWINO 0x00000100 -#define XFS_AGI_DIRINO 0x00000200 -#define XFS_AGI_UNLINKED 0x00000400 -#define XFS_AGI_NUM_BITS 11 -#define XFS_AGI_ALL_BITS ((1 << XFS_AGI_NUM_BITS) - 1) +#define XFS_AGI_CRC_OFF offsetof(struct xfs_agi, agi_crc) + +#define XFS_AGI_MAGICNUM (1 << 0) +#define XFS_AGI_VERSIONNUM (1 << 1) +#define XFS_AGI_SEQNO (1 << 2) +#define XFS_AGI_LENGTH (1 << 3) +#define XFS_AGI_COUNT (1 << 4) +#define XFS_AGI_ROOT (1 << 5) +#define XFS_AGI_LEVEL (1 << 6) +#define XFS_AGI_FREECOUNT (1 << 7) +#define XFS_AGI_NEWINO (1 << 8) +#define XFS_AGI_DIRINO (1 << 9) +#define XFS_AGI_UNLINKED (1 << 10) +#define XFS_AGI_NUM_BITS_R1 11 /* end of the 1st agi logging region */ +#define XFS_AGI_ALL_BITS_R1 ((1 << XFS_AGI_NUM_BITS_R1) - 1) +#define XFS_AGI_FREE_ROOT (1 << 11) +#define XFS_AGI_FREE_LEVEL (1 << 12) +#define XFS_AGI_NUM_BITS_R2 13 /* disk block (xfs_daddr_t) in the AG */ #define XFS_AGI_DADDR(mp) ((xfs_daddr_t)(2 << (mp)->m_sectbb_log)) #define XFS_AGI_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGI_DADDR(mp)) -#define XFS_BUF_TO_AGI(bp) ((xfs_agi_t *)XFS_BUF_PTR(bp)) +#define XFS_BUF_TO_AGI(bp) ((xfs_agi_t *)((bp)->b_addr)) extern int xfs_read_agi(struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, struct xfs_buf **bpp); @@ -167,83 +205,34 @@ */ #define XFS_AGFL_DADDR(mp) ((xfs_daddr_t)(3 << (mp)->m_sectbb_log)) #define XFS_AGFL_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGFL_DADDR(mp)) -#define XFS_AGFL_SIZE(mp) ((mp)->m_sb.sb_sectsize / sizeof(xfs_agblock_t)) -#define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)XFS_BUF_PTR(bp)) +#define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)((bp)->b_addr)) + +#define XFS_BUF_TO_AGFL_BNO(mp, bp) \ + (xfs_sb_version_hascrc(&((mp)->m_sb)) ? \ + &(XFS_BUF_TO_AGFL(bp)->agfl_bno[0]) : \ + (__be32 *)(bp)->b_addr) + +/* + * Size of the AGFL. For CRC-enabled filesystes we steal a couple of + * slots in the beginning of the block for a proper header with the + * location information and CRC. + */ +#define XFS_AGFL_SIZE(mp) \ + (((mp)->m_sb.sb_sectsize - \ + (xfs_sb_version_hascrc(&((mp)->m_sb)) ? \ + sizeof(struct xfs_agfl) : 0)) / \ + sizeof(xfs_agblock_t)) typedef struct xfs_agfl { - __be32 agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */ + __be32 agfl_magicnum; + __be32 agfl_seqno; + uuid_t agfl_uuid; + __be64 agfl_lsn; + __be32 agfl_crc; + __be32 agfl_bno[]; /* actually XFS_AGFL_SIZE(mp) */ } xfs_agfl_t; -/* - * Busy block/extent entry. Indexed by a rbtree in perag to mark blocks that - * have been freed but whose transactions aren't committed to disk yet. - * - * Note that we use the transaction ID to record the transaction, not the - * transaction structure itself. See xfs_alloc_busy_insert() for details. - */ -struct xfs_busy_extent { -#ifdef __KERNEL__ - struct rb_node rb_node; /* ag by-bno indexed search tree */ -#endif - struct list_head list; /* transaction busy extent list */ - xfs_agnumber_t agno; - xfs_agblock_t bno; - xfs_extlen_t length; - xlog_tid_t tid; /* transaction that created this */ -}; - -/* - * Per-ag incore structure, copies of information in agf and agi, - * to improve the performance of allocation group selection. - */ -#define XFS_PAGB_NUM_SLOTS 128 - -typedef struct xfs_perag { - struct xfs_mount *pag_mount; /* owner filesystem */ - xfs_agnumber_t pag_agno; /* AG this structure belongs to */ - atomic_t pag_ref; /* perag reference count */ - char pagf_init; /* this agf's entry is initialized */ - char pagi_init; /* this agi's entry is initialized */ - char pagf_metadata; /* the agf is preferred to be metadata */ - char pagi_inodeok; /* The agi is ok for inodes */ - __uint8_t pagf_levels[XFS_BTNUM_AGF]; - /* # of levels in bno & cnt btree */ - __uint32_t pagf_flcount; /* count of blocks in freelist */ - xfs_extlen_t pagf_freeblks; /* total free blocks */ - xfs_extlen_t pagf_longest; /* longest free space */ - __uint32_t pagf_btreeblks; /* # of blocks held in AGF btrees */ - xfs_agino_t pagi_freecount; /* number of free inodes */ - xfs_agino_t pagi_count; /* number of allocated inodes */ - - /* - * Inode allocation search lookup optimisation. - * If the pagino matches, the search for new inodes - * doesn't need to search the near ones again straight away - */ - xfs_agino_t pagl_pagino; - xfs_agino_t pagl_leftrec; - xfs_agino_t pagl_rightrec; -#ifdef __KERNEL__ - spinlock_t pagb_lock; /* lock for pagb_tree */ - struct rb_root pagb_tree; /* ordered tree of busy extents */ - - atomic_t pagf_fstrms; /* # of filestreams active in this AG */ - - spinlock_t pag_ici_lock; /* incore inode cache lock */ - struct radix_tree_root pag_ici_root; /* incore inode cache root */ - int pag_ici_reclaimable; /* reclaimable inodes */ - struct mutex pag_ici_reclaim_lock; /* serialisation point */ - unsigned long pag_ici_reclaim_cursor; /* reclaim restart point */ - - /* buffer cache index */ - spinlock_t pag_buf_lock; /* lock for pag_buf_tree */ - struct rb_root pag_buf_tree; /* ordered tree of active buffers */ - - /* for rcu-safe freeing */ - struct rcu_head rcu_head; -#endif - int pagb_count; /* pagb slots in use */ -} xfs_perag_t; +#define XFS_AGFL_CRC_OFF offsetof(struct xfs_agfl, agfl_crc) /* * tags for inode radix tree @@ -251,6 +240,7 @@ #define XFS_ICI_NO_TAG (-1) /* special flag for an untagged lookup in xfs_inode_ag_iterator */ #define XFS_ICI_RECLAIM_TAG 0 /* inode is to be reclaimed */ +#define XFS_ICI_EOFBLOCKS_TAG 1 /* inode has blocks beyond EOF */ #define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels) #define XFS_MIN_FREELIST_RAW(bl,cl,mp) \ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_alloc_btree.h xfsprogs-3.2.1ubuntu1/include/xfs_alloc_btree.h --- xfsprogs-3.1.9ubuntu2/include/xfs_alloc_btree.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_alloc_btree.h 2014-05-02 00:09:15.000000000 +0000 @@ -27,56 +27,11 @@ struct xfs_mount; /* - * There are two on-disk btrees, one sorted by blockno and one sorted - * by blockcount and blockno. All blocks look the same to make the code - * simpler; if we have time later, we'll make the optimizations. - */ -#define XFS_ABTB_MAGIC 0x41425442 /* 'ABTB' for bno tree */ -#define XFS_ABTC_MAGIC 0x41425443 /* 'ABTC' for cnt tree */ - -/* - * Data record/key structure - */ -typedef struct xfs_alloc_rec { - __be32 ar_startblock; /* starting block number */ - __be32 ar_blockcount; /* count of free blocks */ -} xfs_alloc_rec_t, xfs_alloc_key_t; - -typedef struct xfs_alloc_rec_incore { - xfs_agblock_t ar_startblock; /* starting block number */ - xfs_extlen_t ar_blockcount; /* count of free blocks */ -} xfs_alloc_rec_incore_t; - -/* btree pointer type */ -typedef __be32 xfs_alloc_ptr_t; - -/* - * Minimum and maximum blocksize and sectorsize. - * The blocksize upper limit is pretty much arbitrary. - * The sectorsize upper limit is due to sizeof(sb_sectsize). - */ -#define XFS_MIN_BLOCKSIZE_LOG 9 /* i.e. 512 bytes */ -#define XFS_MAX_BLOCKSIZE_LOG 16 /* i.e. 65536 bytes */ -#define XFS_MIN_BLOCKSIZE (1 << XFS_MIN_BLOCKSIZE_LOG) -#define XFS_MAX_BLOCKSIZE (1 << XFS_MAX_BLOCKSIZE_LOG) -#define XFS_MIN_SECTORSIZE_LOG 9 /* i.e. 512 bytes */ -#define XFS_MAX_SECTORSIZE_LOG 15 /* i.e. 32768 bytes */ -#define XFS_MIN_SECTORSIZE (1 << XFS_MIN_SECTORSIZE_LOG) -#define XFS_MAX_SECTORSIZE (1 << XFS_MAX_SECTORSIZE_LOG) - -/* - * Block numbers in the AG: - * SB is sector 0, AGF is sector 1, AGI is sector 2, AGFL is sector 3. - */ -#define XFS_BNO_BLOCK(mp) ((xfs_agblock_t)(XFS_AGFL_BLOCK(mp) + 1)) -#define XFS_CNT_BLOCK(mp) ((xfs_agblock_t)(XFS_BNO_BLOCK(mp) + 1)) - -/* * Btree block header size depends on a superblock flag. - * - * (not quite yet, but soon) */ -#define XFS_ALLOC_BLOCK_LEN(mp) XFS_BTREE_SBLOCK_LEN +#define XFS_ALLOC_BLOCK_LEN(mp) \ + (xfs_sb_version_hascrc(&((mp)->m_sb)) ? \ + XFS_BTREE_SBLOCK_CRC_LEN : XFS_BTREE_SBLOCK_LEN) /* * Record, key, and pointer address macros for btree blocks. diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_alloc.h xfsprogs-3.2.1ubuntu1/include/xfs_alloc.h --- xfsprogs-3.1.9ubuntu2/include/xfs_alloc.h 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_alloc.h 2014-05-02 00:09:15.000000000 +0000 @@ -19,10 +19,12 @@ #define __XFS_ALLOC_H__ struct xfs_buf; +struct xfs_btree_cur; struct xfs_mount; struct xfs_perag; struct xfs_trans; -struct xfs_busy_extent; + +extern struct workqueue_struct *xfs_alloc_wq; /* * Freespace allocation types. Argument to xfs_alloc_[v]extent. @@ -74,6 +76,22 @@ #define XFS_ALLOC_SET_ASIDE(mp) (4 + ((mp)->m_sb.sb_agcount * 4)) /* + * When deciding how much space to allocate out of an AG, we limit the + * allocation maximum size to the size the AG. However, we cannot use all the + * blocks in the AG - some are permanently used by metadata. These + * blocks are generally: + * - the AG superblock, AGF, AGI and AGFL + * - the AGF (bno and cnt) and AGI btree root blocks + * - 4 blocks on the AGFL according to XFS_ALLOC_SET_ASIDE() limits + * + * The AG headers are sector sized, so the amount of space they take up is + * dependent on filesystem geometry. The others are all single blocks. + */ +#define XFS_ALLOC_AG_MAX_USABLE(mp) \ + ((mp)->m_sb.sb_agblocks - XFS_BB_TO_FSB(mp, XFS_FSS_TO_BB(mp, 4)) - 7) + + +/* * Argument structure for xfs_alloc routines. * This is turned into a structure to avoid having 20 arguments passed * down several levels of the stack. @@ -117,19 +135,6 @@ xfs_alloc_longest_free_extent(struct xfs_mount *mp, struct xfs_perag *pag); -#ifdef __KERNEL__ - -void -xfs_alloc_busy_insert(xfs_trans_t *tp, - xfs_agnumber_t agno, - xfs_agblock_t bno, - xfs_extlen_t len); - -void -xfs_alloc_busy_clear(struct xfs_mount *mp, struct xfs_busy_extent *busyp); - -#endif /* __KERNEL__ */ - /* * Compute and fill in value of m_ag_maxlevels. */ @@ -205,4 +210,25 @@ xfs_fsblock_t bno, /* starting block number of extent */ xfs_extlen_t len); /* length of extent */ +int /* error */ +xfs_alloc_lookup_le( + struct xfs_btree_cur *cur, /* btree cursor */ + xfs_agblock_t bno, /* starting block of extent */ + xfs_extlen_t len, /* length of extent */ + int *stat); /* success/failure */ + +int /* error */ +xfs_alloc_lookup_ge( + struct xfs_btree_cur *cur, /* btree cursor */ + xfs_agblock_t bno, /* starting block of extent */ + xfs_extlen_t len, /* length of extent */ + int *stat); /* success/failure */ + +int /* error */ +xfs_alloc_get_rec( + struct xfs_btree_cur *cur, /* btree cursor */ + xfs_agblock_t *bno, /* output: starting block of extent */ + xfs_extlen_t *len, /* output: length of extent */ + int *stat); /* output: success/failure */ + #endif /* __XFS_ALLOC_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_arch.h xfsprogs-3.2.1ubuntu1/include/xfs_arch.h --- xfsprogs-3.1.9ubuntu2/include/xfs_arch.h 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_arch.h 2013-06-06 22:52:59.000000000 +0000 @@ -47,6 +47,14 @@ #define be16_to_cpu(val) ((__force __u16)(__be16)(val)) #define be32_to_cpu(val) ((__force __u32)(__be32)(val)) #define be64_to_cpu(val) ((__force __u64)(__be64)(val)) + +#define cpu_to_le32(val) ((__force __be32)__swab32((__u32)(val))) +#define le32_to_cpu(val) (__swab32((__force __u32)(__le32)(val))) + +#define __constant_cpu_to_le32(val) \ + ((__force __le32)___constant_swab32((__u32)(val))) +#define __constant_cpu_to_be32(val) \ + ((__force __be32)(__u32)(val)) #else #define cpu_to_be16(val) ((__force __be16)__swab16((__u16)(val))) #define cpu_to_be32(val) ((__force __be32)__swab32((__u32)(val))) @@ -54,6 +62,14 @@ #define be16_to_cpu(val) (__swab16((__force __u16)(__be16)(val))) #define be32_to_cpu(val) (__swab32((__force __u32)(__be32)(val))) #define be64_to_cpu(val) (__swab64((__force __u64)(__be64)(val))) + +#define cpu_to_le32(val) ((__force __le32)(__u32)(val)) +#define le32_to_cpu(val) ((__force __u32)(__le32)(val)) + +#define __constant_cpu_to_le32(val) \ + ((__force __le32)(__u32)(val)) +#define __constant_cpu_to_be32(val) \ + ((__force __be32)___constant_swab32((__u32)(val))) #endif static inline void be16_add_cpu(__be16 *a, __s16 b) diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_attr_leaf.h xfsprogs-3.2.1ubuntu1/include/xfs_attr_leaf.h --- xfsprogs-3.1.9ubuntu2/include/xfs_attr_leaf.h 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_attr_leaf.h 2014-05-02 00:09:15.000000000 +0000 @@ -1,5 +1,6 @@ /* * Copyright (c) 2000,2002-2003,2005 Silicon Graphics, Inc. + * Copyright (c) 2013 Red Hat, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -18,180 +19,15 @@ #ifndef __XFS_ATTR_LEAF_H__ #define __XFS_ATTR_LEAF_H__ -/* - * Attribute storage layout, internal structure, access macros, etc. - * - * Attribute lists are structured around Btrees where all the data - * elements are in the leaf nodes. Attribute names are hashed into an int, - * then that int is used as the index into the Btree. Since the hashval - * of an attribute name may not be unique, we may have duplicate keys. The - * internal links in the Btree are logical block offsets into the file. - */ - struct attrlist; struct attrlist_cursor_kern; struct xfs_attr_list_context; -struct xfs_dabuf; struct xfs_da_args; struct xfs_da_state; struct xfs_da_state_blk; struct xfs_inode; struct xfs_trans; -/*======================================================================== - * Attribute structure when equal to XFS_LBSIZE(mp) bytes. - *========================================================================*/ - -/* - * This is the structure of the leaf nodes in the Btree. - * - * Struct leaf_entry's are packed from the top. Name/values grow from the - * bottom but are not packed. The freemap contains run-length-encoded entries - * for the free bytes after the leaf_entry's, but only the N largest such, - * smaller runs are dropped. When the freemap doesn't show enough space - * for an allocation, we compact the name/value area and try again. If we - * still don't have enough space, then we have to split the block. The - * name/value structs (both local and remote versions) must be 32bit aligned. - * - * Since we have duplicate hash keys, for each key that matches, compare - * the actual name string. The root and intermediate node search always - * takes the first-in-the-block key match found, so we should only have - * to work "forw"ard. If none matches, continue with the "forw"ard leaf - * nodes until the hash key changes or the attribute name is found. - * - * We store the fact that an attribute is a ROOT/USER/SECURE attribute in - * the leaf_entry. The namespaces are independent only because we also look - * at the namespace bit when we are looking for a matching attribute name. - * - * We also store an "incomplete" bit in the leaf_entry. It shows that an - * attribute is in the middle of being created and should not be shown to - * the user if we crash during the time that the bit is set. We clear the - * bit when we have finished setting up the attribute. We do this because - * we cannot create some large attributes inside a single transaction, and we - * need some indication that we weren't finished if we crash in the middle. - */ -#define XFS_ATTR_LEAF_MAPSIZE 3 /* how many freespace slots */ - -typedef struct xfs_attr_leaf_map { /* RLE map of free bytes */ - __be16 base; /* base of free region */ - __be16 size; /* length of free region */ -} xfs_attr_leaf_map_t; - -typedef struct xfs_attr_leaf_hdr { /* constant-structure header block */ - xfs_da_blkinfo_t info; /* block type, links, etc. */ - __be16 count; /* count of active leaf_entry's */ - __be16 usedbytes; /* num bytes of names/values stored */ - __be16 firstused; /* first used byte in name area */ - __u8 holes; /* != 0 if blk needs compaction */ - __u8 pad1; - xfs_attr_leaf_map_t freemap[XFS_ATTR_LEAF_MAPSIZE]; - /* N largest free regions */ -} xfs_attr_leaf_hdr_t; - -typedef struct xfs_attr_leaf_entry { /* sorted on key, not name */ - __be32 hashval; /* hash value of name */ - __be16 nameidx; /* index into buffer of name/value */ - __u8 flags; /* LOCAL/ROOT/SECURE/INCOMPLETE flag */ - __u8 pad2; /* unused pad byte */ -} xfs_attr_leaf_entry_t; - -typedef struct xfs_attr_leaf_name_local { - __be16 valuelen; /* number of bytes in value */ - __u8 namelen; /* length of name bytes */ - __u8 nameval[1]; /* name/value bytes */ -} xfs_attr_leaf_name_local_t; - -typedef struct xfs_attr_leaf_name_remote { - __be32 valueblk; /* block number of value bytes */ - __be32 valuelen; /* number of bytes in value */ - __u8 namelen; /* length of name bytes */ - __u8 name[1]; /* name bytes */ -} xfs_attr_leaf_name_remote_t; - -typedef struct xfs_attr_leafblock { - xfs_attr_leaf_hdr_t hdr; /* constant-structure header block */ - xfs_attr_leaf_entry_t entries[1]; /* sorted on key, not name */ - xfs_attr_leaf_name_local_t namelist; /* grows from bottom of buf */ - xfs_attr_leaf_name_remote_t valuelist; /* grows from bottom of buf */ -} xfs_attr_leafblock_t; - -/* - * Flags used in the leaf_entry[i].flags field. - * NOTE: the INCOMPLETE bit must not collide with the flags bits specified - * on the system call, they are "or"ed together for various operations. - */ -#define XFS_ATTR_LOCAL_BIT 0 /* attr is stored locally */ -#define XFS_ATTR_ROOT_BIT 1 /* limit access to trusted attrs */ -#define XFS_ATTR_SECURE_BIT 2 /* limit access to secure attrs */ -#define XFS_ATTR_INCOMPLETE_BIT 7 /* attr in middle of create/delete */ -#define XFS_ATTR_LOCAL (1 << XFS_ATTR_LOCAL_BIT) -#define XFS_ATTR_ROOT (1 << XFS_ATTR_ROOT_BIT) -#define XFS_ATTR_SECURE (1 << XFS_ATTR_SECURE_BIT) -#define XFS_ATTR_INCOMPLETE (1 << XFS_ATTR_INCOMPLETE_BIT) - -/* - * Conversion macros for converting namespace bits from argument flags - * to ondisk flags. - */ -#define XFS_ATTR_NSP_ARGS_MASK (ATTR_ROOT | ATTR_SECURE) -#define XFS_ATTR_NSP_ONDISK_MASK (XFS_ATTR_ROOT | XFS_ATTR_SECURE) -#define XFS_ATTR_NSP_ONDISK(flags) ((flags) & XFS_ATTR_NSP_ONDISK_MASK) -#define XFS_ATTR_NSP_ARGS(flags) ((flags) & XFS_ATTR_NSP_ARGS_MASK) -#define XFS_ATTR_NSP_ARGS_TO_ONDISK(x) (((x) & ATTR_ROOT ? XFS_ATTR_ROOT : 0) |\ - ((x) & ATTR_SECURE ? XFS_ATTR_SECURE : 0)) -#define XFS_ATTR_NSP_ONDISK_TO_ARGS(x) (((x) & XFS_ATTR_ROOT ? ATTR_ROOT : 0) |\ - ((x) & XFS_ATTR_SECURE ? ATTR_SECURE : 0)) - -/* - * Alignment for namelist and valuelist entries (since they are mixed - * there can be only one alignment value) - */ -#define XFS_ATTR_LEAF_NAME_ALIGN ((uint)sizeof(xfs_dablk_t)) - -/* - * Cast typed pointers for "local" and "remote" name/value structs. - */ -static inline xfs_attr_leaf_name_remote_t * -xfs_attr_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx) -{ - return (xfs_attr_leaf_name_remote_t *) - &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)]; -} - -static inline xfs_attr_leaf_name_local_t * -xfs_attr_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx) -{ - return (xfs_attr_leaf_name_local_t *) - &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)]; -} - -static inline char *xfs_attr_leaf_name(xfs_attr_leafblock_t *leafp, int idx) -{ - return &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)]; -} - -/* - * Calculate total bytes used (including trailing pad for alignment) for - * a "local" name/value structure, a "remote" name/value structure, and - * a pointer which might be either. - */ -static inline int xfs_attr_leaf_entsize_remote(int nlen) -{ - return ((uint)sizeof(xfs_attr_leaf_name_remote_t) - 1 + (nlen) + \ - XFS_ATTR_LEAF_NAME_ALIGN - 1) & ~(XFS_ATTR_LEAF_NAME_ALIGN - 1); -} - -static inline int xfs_attr_leaf_entsize_local(int nlen, int vlen) -{ - return ((uint)sizeof(xfs_attr_leaf_name_local_t) - 1 + (nlen) + (vlen) + - XFS_ATTR_LEAF_NAME_ALIGN - 1) & ~(XFS_ATTR_LEAF_NAME_ALIGN - 1); -} - -static inline int xfs_attr_leaf_entsize_local_max(int bsize) -{ - return (((bsize) >> 1) + ((bsize) >> 2)); -} - /* * Used to keep a list of "remote value" extents when unlinking an inode. */ @@ -215,51 +51,59 @@ int xfs_attr_shortform_to_leaf(struct xfs_da_args *args); int xfs_attr_shortform_remove(struct xfs_da_args *args); int xfs_attr_shortform_list(struct xfs_attr_list_context *context); -int xfs_attr_shortform_allfit(struct xfs_dabuf *bp, struct xfs_inode *dp); +int xfs_attr_shortform_allfit(struct xfs_buf *bp, struct xfs_inode *dp); int xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes); /* * Internal routines when attribute fork size == XFS_LBSIZE(mp). */ -int xfs_attr_leaf_to_node(struct xfs_da_args *args); -int xfs_attr_leaf_to_shortform(struct xfs_dabuf *bp, +int xfs_attr3_leaf_to_node(struct xfs_da_args *args); +int xfs_attr3_leaf_to_shortform(struct xfs_buf *bp, struct xfs_da_args *args, int forkoff); -int xfs_attr_leaf_clearflag(struct xfs_da_args *args); -int xfs_attr_leaf_setflag(struct xfs_da_args *args); -int xfs_attr_leaf_flipflags(xfs_da_args_t *args); +int xfs_attr3_leaf_clearflag(struct xfs_da_args *args); +int xfs_attr3_leaf_setflag(struct xfs_da_args *args); +int xfs_attr3_leaf_flipflags(struct xfs_da_args *args); /* * Routines used for growing the Btree. */ -int xfs_attr_leaf_split(struct xfs_da_state *state, +int xfs_attr3_leaf_split(struct xfs_da_state *state, struct xfs_da_state_blk *oldblk, struct xfs_da_state_blk *newblk); -int xfs_attr_leaf_lookup_int(struct xfs_dabuf *leaf, +int xfs_attr3_leaf_lookup_int(struct xfs_buf *leaf, struct xfs_da_args *args); -int xfs_attr_leaf_getvalue(struct xfs_dabuf *bp, struct xfs_da_args *args); -int xfs_attr_leaf_add(struct xfs_dabuf *leaf_buffer, +int xfs_attr3_leaf_getvalue(struct xfs_buf *bp, struct xfs_da_args *args); +int xfs_attr3_leaf_add(struct xfs_buf *leaf_buffer, struct xfs_da_args *args); -int xfs_attr_leaf_remove(struct xfs_dabuf *leaf_buffer, +int xfs_attr3_leaf_remove(struct xfs_buf *leaf_buffer, struct xfs_da_args *args); -int xfs_attr_leaf_list_int(struct xfs_dabuf *bp, +int xfs_attr3_leaf_list_int(struct xfs_buf *bp, struct xfs_attr_list_context *context); /* * Routines used for shrinking the Btree. */ -int xfs_attr_leaf_toosmall(struct xfs_da_state *state, int *retval); -void xfs_attr_leaf_unbalance(struct xfs_da_state *state, +int xfs_attr3_leaf_toosmall(struct xfs_da_state *state, int *retval); +void xfs_attr3_leaf_unbalance(struct xfs_da_state *state, struct xfs_da_state_blk *drop_blk, struct xfs_da_state_blk *save_blk); -int xfs_attr_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp); +int xfs_attr3_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp); /* * Utility routines. */ -xfs_dahash_t xfs_attr_leaf_lasthash(struct xfs_dabuf *bp, int *count); -int xfs_attr_leaf_order(struct xfs_dabuf *leaf1_bp, - struct xfs_dabuf *leaf2_bp); +xfs_dahash_t xfs_attr_leaf_lasthash(struct xfs_buf *bp, int *count); +int xfs_attr_leaf_order(struct xfs_buf *leaf1_bp, + struct xfs_buf *leaf2_bp); int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int *local); +int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, + xfs_dablk_t bno, xfs_daddr_t mappedbno, + struct xfs_buf **bpp); +void xfs_attr3_leaf_hdr_from_disk(struct xfs_attr3_icleaf_hdr *to, + struct xfs_attr_leafblock *from); +void xfs_attr3_leaf_hdr_to_disk(struct xfs_attr_leafblock *to, + struct xfs_attr3_icleaf_hdr *from); + #endif /* __XFS_ATTR_LEAF_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_attr_remote.h xfsprogs-3.2.1ubuntu1/include/xfs_attr_remote.h --- xfsprogs-3.1.9ubuntu2/include/xfs_attr_remote.h 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_attr_remote.h 2014-05-02 00:09:15.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2013 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_ATTR_REMOTE_H__ +#define __XFS_ATTR_REMOTE_H__ + +int xfs_attr3_rmt_blocks(struct xfs_mount *mp, int attrlen); + +int xfs_attr_rmtval_get(struct xfs_da_args *args); +int xfs_attr_rmtval_set(struct xfs_da_args *args); +int xfs_attr_rmtval_remove(struct xfs_da_args *args); + +#endif /* __XFS_ATTR_REMOTE_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_bmap_btree.h xfsprogs-3.2.1ubuntu1/include/xfs_bmap_btree.h --- xfsprogs-3.1.9ubuntu2/include/xfs_bmap_btree.h 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_bmap_btree.h 2014-05-02 00:09:15.000000000 +0000 @@ -18,8 +18,6 @@ #ifndef __XFS_BMAP_BTREE_H__ #define __XFS_BMAP_BTREE_H__ -#define XFS_BMAP_MAGIC 0x424d4150 /* 'BMAP' */ - struct xfs_btree_cur; struct xfs_btree_block; struct xfs_mount; @@ -27,85 +25,6 @@ struct xfs_trans; /* - * Bmap root header, on-disk form only. - */ -typedef struct xfs_bmdr_block { - __be16 bb_level; /* 0 is a leaf */ - __be16 bb_numrecs; /* current # of data records */ -} xfs_bmdr_block_t; - -/* - * Bmap btree record and extent descriptor. - * l0:63 is an extent flag (value 1 indicates non-normal). - * l0:9-62 are startoff. - * l0:0-8 and l1:21-63 are startblock. - * l1:0-20 are blockcount. - */ -#define BMBT_EXNTFLAG_BITLEN 1 -#define BMBT_STARTOFF_BITLEN 54 -#define BMBT_STARTBLOCK_BITLEN 52 -#define BMBT_BLOCKCOUNT_BITLEN 21 - -typedef struct xfs_bmbt_rec { - __be64 l0, l1; -} xfs_bmbt_rec_t; - -typedef __uint64_t xfs_bmbt_rec_base_t; /* use this for casts */ -typedef xfs_bmbt_rec_t xfs_bmdr_rec_t; - -typedef struct xfs_bmbt_rec_host { - __uint64_t l0, l1; -} xfs_bmbt_rec_host_t; - -/* - * Values and macros for delayed-allocation startblock fields. - */ -#define STARTBLOCKVALBITS 17 -#define STARTBLOCKMASKBITS (15 + XFS_BIG_BLKNOS * 20) -#define DSTARTBLOCKMASKBITS (15 + 20) -#define STARTBLOCKMASK \ - (((((xfs_fsblock_t)1) << STARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS) -#define DSTARTBLOCKMASK \ - (((((xfs_dfsbno_t)1) << DSTARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS) - -static inline int isnullstartblock(xfs_fsblock_t x) -{ - return ((x) & STARTBLOCKMASK) == STARTBLOCKMASK; -} - -static inline int isnulldstartblock(xfs_dfsbno_t x) -{ - return ((x) & DSTARTBLOCKMASK) == DSTARTBLOCKMASK; -} - -static inline xfs_fsblock_t nullstartblock(int k) -{ - ASSERT(k < (1 << STARTBLOCKVALBITS)); - return STARTBLOCKMASK | (k); -} - -static inline xfs_filblks_t startblockval(xfs_fsblock_t x) -{ - return (xfs_filblks_t)((x) & ~STARTBLOCKMASK); -} - -/* - * Possible extent formats. - */ -typedef enum { - XFS_EXTFMT_NOSTATE = 0, - XFS_EXTFMT_HASSTATE -} xfs_exntfmt_t; - -/* - * Possible extent states. - */ -typedef enum { - XFS_EXT_NORM, XFS_EXT_UNWRITTEN, - XFS_EXT_DMAPI_OFFLINE, XFS_EXT_INVALID -} xfs_exntst_t; - -/* * Extent state and extent format macros. */ #define XFS_EXTFMT_INODE(x) \ @@ -114,32 +33,11 @@ #define ISUNWRITTEN(x) ((x)->br_state == XFS_EXT_UNWRITTEN) /* - * Incore version of above. - */ -typedef struct xfs_bmbt_irec -{ - xfs_fileoff_t br_startoff; /* starting file offset */ - xfs_fsblock_t br_startblock; /* starting block number */ - xfs_filblks_t br_blockcount; /* number of blocks */ - xfs_exntst_t br_state; /* extent state */ -} xfs_bmbt_irec_t; - -/* - * Key structure for non-leaf levels of the tree. - */ -typedef struct xfs_bmbt_key { - __be64 br_startoff; /* starting file offset */ -} xfs_bmbt_key_t, xfs_bmdr_key_t; - -/* btree pointer type */ -typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; - -/* * Btree block header size depends on a superblock flag. - * - * (not quite yet, but soon) */ -#define XFS_BMBT_BLOCK_LEN(mp) XFS_BTREE_LBLOCK_LEN +#define XFS_BMBT_BLOCK_LEN(mp) \ + (xfs_sb_version_hascrc(&((mp)->m_sb)) ? \ + XFS_BTREE_LBLOCK_CRC_LEN : XFS_BTREE_LBLOCK_LEN) #define XFS_BMBT_REC_ADDR(mp, block, index) \ ((xfs_bmbt_rec_t *) \ @@ -186,15 +84,17 @@ #define XFS_BMAP_BROOT_PTR_ADDR(mp, bb, i, sz) \ XFS_BMBT_PTR_ADDR(mp, bb, i, xfs_bmbt_maxrecs(mp, sz, 0)) -#define XFS_BMAP_BROOT_SPACE_CALC(nrecs) \ - (int)(XFS_BTREE_LBLOCK_LEN + \ +#define XFS_BMAP_BROOT_SPACE_CALC(mp, nrecs) \ + (int)(XFS_BMBT_BLOCK_LEN(mp) + \ ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))) -#define XFS_BMAP_BROOT_SPACE(bb) \ - (XFS_BMAP_BROOT_SPACE_CALC(be16_to_cpu((bb)->bb_numrecs))) +#define XFS_BMAP_BROOT_SPACE(mp, bb) \ + (XFS_BMAP_BROOT_SPACE_CALC(mp, be16_to_cpu((bb)->bb_numrecs))) #define XFS_BMDR_SPACE_CALC(nrecs) \ (int)(sizeof(xfs_bmdr_block_t) + \ ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))) +#define XFS_BMAP_BMDR_SPACE(bb) \ + (XFS_BMDR_SPACE_CALC(be16_to_cpu((bb)->bb_numrecs))) /* * Maximum number of bmap btree levels. @@ -204,7 +104,7 @@ /* * Prototypes for xfs_bmap.c to call. */ -extern void xfs_bmdr_to_bmbt(struct xfs_mount *, xfs_bmdr_block_t *, int, +extern void xfs_bmdr_to_bmbt(struct xfs_inode *, xfs_bmdr_block_t *, int, struct xfs_btree_block *, int); extern void xfs_bmbt_get_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s); extern xfs_filblks_t xfs_bmbt_get_blockcount(xfs_bmbt_rec_host_t *r); @@ -233,8 +133,11 @@ extern int xfs_bmdr_maxrecs(struct xfs_mount *, int blocklen, int leaf); extern int xfs_bmbt_maxrecs(struct xfs_mount *, int blocklen, int leaf); +extern int xfs_bmbt_change_owner(struct xfs_trans *tp, struct xfs_inode *ip, + int whichfork, xfs_ino_t new_owner, + struct list_head *buffer_list); + extern struct xfs_btree_cur *xfs_bmbt_init_cursor(struct xfs_mount *, struct xfs_trans *, struct xfs_inode *, int); - #endif /* __XFS_BMAP_BTREE_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_bmap.h xfsprogs-3.2.1ubuntu1/include/xfs_bmap.h --- xfsprogs-3.1.9ubuntu2/include/xfs_bmap.h 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_bmap.h 2013-10-10 21:07:17.000000000 +0000 @@ -62,36 +62,32 @@ #define XFS_BMAP_MAX_NMAP 4 /* - * Flags for xfs_bmapi + * Flags for xfs_bmapi_* */ -#define XFS_BMAPI_WRITE 0x001 /* write operation: allocate space */ -#define XFS_BMAPI_DELAY 0x002 /* delayed write operation */ -#define XFS_BMAPI_ENTIRE 0x004 /* return entire extent, not trimmed */ -#define XFS_BMAPI_METADATA 0x008 /* mapping metadata not user data */ -#define XFS_BMAPI_ATTRFORK 0x010 /* use attribute fork not data */ -#define XFS_BMAPI_RSVBLOCKS 0x020 /* OK to alloc. reserved data blocks */ -#define XFS_BMAPI_PREALLOC 0x040 /* preallocation op: unwritten space */ -#define XFS_BMAPI_IGSTATE 0x080 /* Ignore state - */ +#define XFS_BMAPI_ENTIRE 0x001 /* return entire extent, not trimmed */ +#define XFS_BMAPI_METADATA 0x002 /* mapping metadata not user data */ +#define XFS_BMAPI_ATTRFORK 0x004 /* use attribute fork not data */ +#define XFS_BMAPI_PREALLOC 0x008 /* preallocation op: unwritten space */ +#define XFS_BMAPI_IGSTATE 0x010 /* Ignore state - */ /* combine contig. space */ -#define XFS_BMAPI_CONTIG 0x100 /* must allocate only one extent */ +#define XFS_BMAPI_CONTIG 0x020 /* must allocate only one extent */ /* * unwritten extent conversion - this needs write cache flushing and no additional * allocation alignments. When specified with XFS_BMAPI_PREALLOC it converts * from written to unwritten, otherwise convert from unwritten to written. */ -#define XFS_BMAPI_CONVERT 0x200 +#define XFS_BMAPI_CONVERT 0x040 +#define XFS_BMAPI_STACK_SWITCH 0x080 #define XFS_BMAPI_FLAGS \ - { XFS_BMAPI_WRITE, "WRITE" }, \ - { XFS_BMAPI_DELAY, "DELAY" }, \ { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ { XFS_BMAPI_METADATA, "METADATA" }, \ { XFS_BMAPI_ATTRFORK, "ATTRFORK" }, \ - { XFS_BMAPI_RSVBLOCKS, "RSVBLOCKS" }, \ { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ { XFS_BMAPI_CONTIG, "CONTIG" }, \ - { XFS_BMAPI_CONVERT, "CONVERT" } + { XFS_BMAPI_CONVERT, "CONVERT" }, \ + { XFS_BMAPI_STACK_SWITCH, "STACK_SWITCH" } static inline int xfs_bmapi_aflag(int w) @@ -112,29 +108,6 @@ } /* - * Argument structure for xfs_bmap_alloc. - */ -typedef struct xfs_bmalloca { - xfs_fsblock_t firstblock; /* i/o first block allocated */ - xfs_fsblock_t rval; /* starting block of new extent */ - xfs_fileoff_t off; /* offset in file filling in */ - struct xfs_trans *tp; /* transaction pointer */ - struct xfs_inode *ip; /* incore inode pointer */ - struct xfs_bmbt_irec *prevp; /* extent before the new one */ - struct xfs_bmbt_irec *gotp; /* extent after, or delayed */ - xfs_extlen_t alen; /* i/o length asked/allocated */ - xfs_extlen_t total; /* total blocks needed for xaction */ - xfs_extlen_t minlen; /* minimum allocation size (blocks) */ - xfs_extlen_t minleft; /* amount must be left after alloc */ - char eof; /* set if allocating past last extent */ - char wasdel; /* replacing a delayed allocation */ - char userdata;/* set if is user data */ - char low; /* low on space, using seq'l ags */ - char aeof; /* allocated space at eof */ - char conv; /* overwriting unwritten extents */ -} xfs_bmalloca_t; - -/* * Flags for xfs_bmap_add_extent*. */ #define BMAP_LEFT_CONTIG (1 << 0) @@ -154,251 +127,47 @@ { BMAP_RIGHT_FILLING, "RF" }, \ { BMAP_ATTRFORK, "ATTR" } -/* - * Add bmap trace insert entries for all the contents of the extent list. - * - * Quite excessive tracing. Only do this for debug builds. - */ -#if defined(__KERNEL) && defined(DEBUG) -void -xfs_bmap_trace_exlist( - struct xfs_inode *ip, /* incore inode pointer */ - xfs_extnum_t cnt, /* count of entries in list */ - int whichfork, - unsigned long caller_ip); /* data or attr fork */ +#ifdef DEBUG +void xfs_bmap_trace_exlist(struct xfs_inode *ip, xfs_extnum_t cnt, + int whichfork, unsigned long caller_ip); #define XFS_BMAP_TRACE_EXLIST(ip,c,w) \ xfs_bmap_trace_exlist(ip,c,w, _THIS_IP_) #else #define XFS_BMAP_TRACE_EXLIST(ip,c,w) #endif -/* - * Convert inode from non-attributed to attributed. - * Must not be in a transaction, ip must not be locked. - */ -int /* error code */ -xfs_bmap_add_attrfork( - struct xfs_inode *ip, /* incore inode pointer */ - int size, /* space needed for new attribute */ - int rsvd); /* flag for reserved block allocation */ - -/* - * Add the extent to the list of extents to be free at transaction end. - * The list is maintained sorted (by block number). - */ -void -xfs_bmap_add_free( - xfs_fsblock_t bno, /* fs block number of extent */ - xfs_filblks_t len, /* length of extent */ - xfs_bmap_free_t *flist, /* list of extents */ - struct xfs_mount *mp); /* mount point structure */ - -/* - * Routine to clean up the free list data structure when - * an error occurs during a transaction. - */ -void -xfs_bmap_cancel( - xfs_bmap_free_t *flist); /* free list to clean up */ - -/* - * Compute and fill in the value of the maximum depth of a bmap btree - * in this filesystem. Done once, during mount. - */ -void -xfs_bmap_compute_maxlevels( - struct xfs_mount *mp, /* file system mount structure */ - int whichfork); /* data or attr fork */ - -/* - * Returns the file-relative block number of the first unused block in the file. - * This is the lowest-address hole if the file has holes, else the first block - * past the end of file. - */ -int /* error */ -xfs_bmap_first_unused( - struct xfs_trans *tp, /* transaction pointer */ - struct xfs_inode *ip, /* incore inode */ - xfs_extlen_t len, /* size of hole to find */ - xfs_fileoff_t *unused, /* unused block num */ - int whichfork); /* data or attr fork */ - -/* - * Returns the file-relative block number of the last block + 1 before - * last_block (input value) in the file. - * This is not based on i_size, it is based on the extent list. - * Returns 0 for local files, as they do not have an extent list. - */ -int /* error */ -xfs_bmap_last_before( - struct xfs_trans *tp, /* transaction pointer */ - struct xfs_inode *ip, /* incore inode */ - xfs_fileoff_t *last_block, /* last block */ - int whichfork); /* data or attr fork */ - -/* - * Returns the file-relative block number of the first block past eof in - * the file. This is not based on i_size, it is based on the extent list. - * Returns 0 for local files, as they do not have an extent list. - */ -int /* error */ -xfs_bmap_last_offset( - struct xfs_trans *tp, /* transaction pointer */ - struct xfs_inode *ip, /* incore inode */ - xfs_fileoff_t *unused, /* last block num */ - int whichfork); /* data or attr fork */ - -/* - * Returns whether the selected fork of the inode has exactly one - * block or not. For the data fork we check this matches di_size, - * implying the file's range is 0..bsize-1. - */ -int -xfs_bmap_one_block( - struct xfs_inode *ip, /* incore inode */ - int whichfork); /* data or attr fork */ - -/* - * Read in the extents to iu_extents. - * All inode fields are set up by caller, we just traverse the btree - * and copy the records in. - */ -int /* error */ -xfs_bmap_read_extents( - struct xfs_trans *tp, /* transaction pointer */ - struct xfs_inode *ip, /* incore inode */ - int whichfork); /* data or attr fork */ - -/* - * Map file blocks to filesystem blocks. - * File range is given by the bno/len pair. - * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set) - * into a hole or past eof. - * Only allocates blocks from a single allocation group, - * to avoid locking problems. - * The returned value in "firstblock" from the first call in a transaction - * must be remembered and presented to subsequent calls in "firstblock". - * An upper bound for the number of blocks to be allocated is supplied to - * the first call in "total"; if no allocation group has that many free - * blocks then the call will fail (return NULLFSBLOCK in "firstblock"). - */ -int /* error */ -xfs_bmapi( - struct xfs_trans *tp, /* transaction pointer */ - struct xfs_inode *ip, /* incore inode */ - xfs_fileoff_t bno, /* starting file offs. mapped */ - xfs_filblks_t len, /* length to map in file */ - int flags, /* XFS_BMAPI_... */ - xfs_fsblock_t *firstblock, /* first allocated block - controls a.g. for allocs */ - xfs_extlen_t total, /* total blocks needed */ - struct xfs_bmbt_irec *mval, /* output: map values */ - int *nmap, /* i/o: mval size/count */ - xfs_bmap_free_t *flist); /* i/o: list extents to free */ - -/* - * Map file blocks to filesystem blocks, simple version. - * One block only, read-only. - * For flags, only the XFS_BMAPI_ATTRFORK flag is examined. - * For the other flag values, the effect is as if XFS_BMAPI_METADATA - * was set and all the others were clear. - */ -int /* error */ -xfs_bmapi_single( - struct xfs_trans *tp, /* transaction pointer */ - struct xfs_inode *ip, /* incore inode */ - int whichfork, /* data or attr fork */ - xfs_fsblock_t *fsb, /* output: mapped block */ - xfs_fileoff_t bno); /* starting file offs. mapped */ - -/* - * Unmap (remove) blocks from a file. - * If nexts is nonzero then the number of extents to remove is limited to - * that value. If not all extents in the block range can be removed then - * *done is set. - */ -int /* error */ -xfs_bunmapi( - struct xfs_trans *tp, /* transaction pointer */ - struct xfs_inode *ip, /* incore inode */ - xfs_fileoff_t bno, /* starting offset to unmap */ - xfs_filblks_t len, /* length to unmap in file */ - int flags, /* XFS_BMAPI_... */ - xfs_extnum_t nexts, /* number of extents max */ - xfs_fsblock_t *firstblock, /* first allocated block - controls a.g. for allocs */ - xfs_bmap_free_t *flist, /* i/o: list extents to free */ - int *done); /* set if not done yet */ - -/* - * Check an extent list, which has just been read, for - * any bit in the extent flag field. - */ -int -xfs_check_nostate_extents( - struct xfs_ifork *ifp, - xfs_extnum_t idx, - xfs_extnum_t num); - -uint -xfs_default_attroffset( - struct xfs_inode *ip); - -#ifdef __KERNEL__ - -/* - * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi - * caller. Frees all the extents that need freeing, which must be done - * last due to locking considerations. - * - * Return 1 if the given transaction was committed and a new one allocated, - * and 0 otherwise. - */ -int /* error */ -xfs_bmap_finish( - struct xfs_trans **tp, /* transaction pointer addr */ - xfs_bmap_free_t *flist, /* i/o: list extents to free */ - int *committed); /* xact committed or not */ - -/* bmap to userspace formatter - copy to user & advance pointer */ -typedef int (*xfs_bmap_format_t)(void **, struct getbmapx *, int *); - -/* - * Get inode's extents as described in bmv, and format for output. - */ -int /* error code */ -xfs_getbmap( - xfs_inode_t *ip, - struct getbmapx *bmv, /* user bmap structure */ - xfs_bmap_format_t formatter, /* format to user */ - void *arg); /* formatter arg */ - -/* - * Check if the endoff is outside the last extent. If so the caller will grow - * the allocation to a stripe unit boundary - */ -int -xfs_bmap_eof( - struct xfs_inode *ip, - xfs_fileoff_t endoff, - int whichfork, - int *eof); - -/* - * Count fsblocks of the given fork. - */ -int -xfs_bmap_count_blocks( - xfs_trans_t *tp, - struct xfs_inode *ip, - int whichfork, - int *count); - -int -xfs_bmap_punch_delalloc_range( - struct xfs_inode *ip, - xfs_fileoff_t start_fsb, - xfs_fileoff_t length); -#endif /* __KERNEL__ */ +int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd); +void xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork); +void xfs_bmap_add_free(xfs_fsblock_t bno, xfs_filblks_t len, + struct xfs_bmap_free *flist, struct xfs_mount *mp); +void xfs_bmap_cancel(struct xfs_bmap_free *flist); +void xfs_bmap_compute_maxlevels(struct xfs_mount *mp, int whichfork); +int xfs_bmap_first_unused(struct xfs_trans *tp, struct xfs_inode *ip, + xfs_extlen_t len, xfs_fileoff_t *unused, int whichfork); +int xfs_bmap_last_before(struct xfs_trans *tp, struct xfs_inode *ip, + xfs_fileoff_t *last_block, int whichfork); +int xfs_bmap_last_offset(struct xfs_trans *tp, struct xfs_inode *ip, + xfs_fileoff_t *unused, int whichfork); +int xfs_bmap_one_block(struct xfs_inode *ip, int whichfork); +int xfs_bmap_read_extents(struct xfs_trans *tp, struct xfs_inode *ip, + int whichfork); +int xfs_bmapi_read(struct xfs_inode *ip, xfs_fileoff_t bno, + xfs_filblks_t len, struct xfs_bmbt_irec *mval, + int *nmap, int flags); +int xfs_bmapi_delay(struct xfs_inode *ip, xfs_fileoff_t bno, + xfs_filblks_t len, struct xfs_bmbt_irec *mval, + int *nmap, int flags); +int xfs_bmapi_write(struct xfs_trans *tp, struct xfs_inode *ip, + xfs_fileoff_t bno, xfs_filblks_t len, int flags, + xfs_fsblock_t *firstblock, xfs_extlen_t total, + struct xfs_bmbt_irec *mval, int *nmap, + struct xfs_bmap_free *flist); +int xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip, + xfs_fileoff_t bno, xfs_filblks_t len, int flags, + xfs_extnum_t nexts, xfs_fsblock_t *firstblock, + struct xfs_bmap_free *flist, int *done); +int xfs_check_nostate_extents(struct xfs_ifork *ifp, xfs_extnum_t idx, + xfs_extnum_t num); +uint xfs_default_attroffset(struct xfs_inode *ip); #endif /* __XFS_BMAP_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_btree.h xfsprogs-3.2.1ubuntu1/include/xfs_btree.h --- xfsprogs-3.1.9ubuntu2/include/xfs_btree.h 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_btree.h 2014-06-19 22:42:17.000000000 +0000 @@ -37,77 +37,24 @@ #define XFS_BTNUM_CNT ((xfs_btnum_t)XFS_BTNUM_CNTi) #define XFS_BTNUM_BMAP ((xfs_btnum_t)XFS_BTNUM_BMAPi) #define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi) - -/* - * Generic btree header. - * - * This is a combination of the actual format used on disk for short and long - * format btrees. The first three fields are shared by both format, but - * the pointers are different and should be used with care. - * - * To get the size of the actual short or long form headers please use - * the size macros below. Never use sizeof(xfs_btree_block). - */ -struct xfs_btree_block { - __be32 bb_magic; /* magic number for block type */ - __be16 bb_level; /* 0 is a leaf */ - __be16 bb_numrecs; /* current # of data records */ - union { - struct { - __be32 bb_leftsib; - __be32 bb_rightsib; - } s; /* short form pointers */ - struct { - __be64 bb_leftsib; - __be64 bb_rightsib; - } l; /* long form pointers */ - } bb_u; /* rest */ -}; - -#define XFS_BTREE_SBLOCK_LEN 16 /* size of a short form block */ -#define XFS_BTREE_LBLOCK_LEN 24 /* size of a long form block */ - - -/* - * Generic key, ptr and record wrapper structures. - * - * These are disk format structures, and are converted where necessary - * by the btree specific code that needs to interpret them. - */ -union xfs_btree_ptr { - __be32 s; /* short form ptr */ - __be64 l; /* long form ptr */ -}; - -union xfs_btree_key { - xfs_bmbt_key_t bmbt; - xfs_bmdr_key_t bmbr; /* bmbt root block */ - xfs_alloc_key_t alloc; - xfs_inobt_key_t inobt; -}; - -union xfs_btree_rec { - xfs_bmbt_rec_t bmbt; - xfs_bmdr_rec_t bmbr; /* bmbt root block */ - xfs_alloc_rec_t alloc; - xfs_inobt_rec_t inobt; -}; +#define XFS_BTNUM_FINO ((xfs_btnum_t)XFS_BTNUM_FINOi) /* * For logging record fields. */ -#define XFS_BB_MAGIC 0x01 -#define XFS_BB_LEVEL 0x02 -#define XFS_BB_NUMRECS 0x04 -#define XFS_BB_LEFTSIB 0x08 -#define XFS_BB_RIGHTSIB 0x10 +#define XFS_BB_MAGIC (1 << 0) +#define XFS_BB_LEVEL (1 << 1) +#define XFS_BB_NUMRECS (1 << 2) +#define XFS_BB_LEFTSIB (1 << 3) +#define XFS_BB_RIGHTSIB (1 << 4) +#define XFS_BB_BLKNO (1 << 5) +#define XFS_BB_LSN (1 << 6) +#define XFS_BB_UUID (1 << 7) +#define XFS_BB_OWNER (1 << 8) #define XFS_BB_NUM_BITS 5 #define XFS_BB_ALL_BITS ((1 << XFS_BB_NUM_BITS) - 1) - -/* - * Magic numbers for btree blocks. - */ -extern const __uint32_t xfs_magics[]; +#define XFS_BB_NUM_BITS_CRC 9 +#define XFS_BB_ALL_BITS_CRC ((1 << XFS_BB_NUM_BITS_CRC) - 1) /* * Generic stats interface @@ -121,6 +68,7 @@ case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(abtc, stat); break; \ case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \ case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \ + case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(fibt, stat); break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) @@ -134,6 +82,7 @@ case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(abtc, stat, val); break; \ case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \ case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \ + case XFS_BTNUM_FINO: __XFS_BTREE_STATS_ADD(fibt, stat, val); break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) @@ -188,7 +137,9 @@ __int64_t (*key_diff)(struct xfs_btree_cur *cur, union xfs_btree_key *key); -#ifdef DEBUG + const struct xfs_buf_ops *buf_ops; + +#if defined(DEBUG) || defined(XFS_WARN) /* check that k1 is lower than k2 */ int (*keys_inorder)(struct xfs_btree_cur *cur, union xfs_btree_key *k1, @@ -273,6 +224,7 @@ #define XFS_BTREE_LONG_PTRS (1<<0) /* pointers are 64bits long */ #define XFS_BTREE_ROOT_IN_INODE (1<<1) /* root may be variable size */ #define XFS_BTREE_LASTREC_UPDATE (1<<2) /* track last rec externally */ +#define XFS_BTREE_CRC_BLOCKS (1<<3) /* uses extended btree blocks */ #define XFS_BTREE_NOERROR 0 @@ -281,7 +233,7 @@ /* * Convert from buffer to btree block header. */ -#define XFS_BUF_TO_BLOCK(bp) ((struct xfs_btree_block *)XFS_BUF_PTR(bp)) +#define XFS_BUF_TO_BLOCK(bp) ((struct xfs_btree_block *)((bp)->b_addr)) /* @@ -374,7 +326,8 @@ xfs_fsblock_t fsbno, /* file system block number */ uint lock, /* lock flags for read_buf */ struct xfs_buf **bpp, /* buffer for fsbno */ - int refval);/* ref count value for buffer */ + int refval, /* ref count value for buffer */ + const struct xfs_buf_ops *ops); /* * Read-ahead the block, don't wait for it, don't return a buffer. @@ -384,7 +337,8 @@ xfs_btree_reada_bufl( struct xfs_mount *mp, /* file system mount point */ xfs_fsblock_t fsbno, /* file system block number */ - xfs_extlen_t count); /* count of filesystem blocks */ + xfs_extlen_t count, /* count of filesystem blocks */ + const struct xfs_buf_ops *ops); /* * Read-ahead the block, don't wait for it, don't return a buffer. @@ -395,8 +349,32 @@ struct xfs_mount *mp, /* file system mount point */ xfs_agnumber_t agno, /* allocation group number */ xfs_agblock_t agbno, /* allocation group block number */ - xfs_extlen_t count); /* count of filesystem blocks */ + xfs_extlen_t count, /* count of filesystem blocks */ + const struct xfs_buf_ops *ops); +/* + * Initialise a new btree block header + */ +void +xfs_btree_init_block( + struct xfs_mount *mp, + struct xfs_buf *bp, + __u32 magic, + __u16 level, + __u16 numrecs, + __u64 owner, + unsigned int flags); + +void +xfs_btree_init_block_int( + struct xfs_mount *mp, + struct xfs_btree_block *buf, + xfs_daddr_t blkno, + __u32 magic, + __u16 level, + __u16 numrecs, + __u64 owner, + unsigned int flags); /* * Common btree core entry points. @@ -409,6 +387,16 @@ int xfs_btree_insert(struct xfs_btree_cur *, int *); int xfs_btree_delete(struct xfs_btree_cur *, int *); int xfs_btree_get_rec(struct xfs_btree_cur *, union xfs_btree_rec **, int *); +int xfs_btree_change_owner(struct xfs_btree_cur *cur, __uint64_t new_owner, + struct list_head *buffer_list); + +/* + * btree block CRC helpers + */ +void xfs_btree_lblock_calc_crc(struct xfs_buf *); +bool xfs_btree_lblock_verify_crc(struct xfs_buf *); +void xfs_btree_sblock_calc_crc(struct xfs_buf *); +bool xfs_btree_sblock_verify_crc(struct xfs_buf *); /* * Internal btree helpers also used by xfs_bmap.c. diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_buf_item.h xfsprogs-3.2.1ubuntu1/include/xfs_buf_item.h --- xfsprogs-3.1.9ubuntu2/include/xfs_buf_item.h 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_buf_item.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_BUF_ITEM_H__ -#define __XFS_BUF_ITEM_H__ - -extern kmem_zone_t *xfs_buf_item_zone; - -/* - * This is the structure used to lay out a buf log item in the - * log. The data map describes which 128 byte chunks of the buffer - * have been logged. - * For 6.2 and beyond, this is XFS_LI_BUF. We use this to log everything. - */ -typedef struct xfs_buf_log_format { - unsigned short blf_type; /* buf log item type indicator */ - unsigned short blf_size; /* size of this item */ - ushort blf_flags; /* misc state */ - ushort blf_len; /* number of blocks in this buf */ - __int64_t blf_blkno; /* starting blkno of this buf */ - unsigned int blf_map_size; /* size of data bitmap in words */ - unsigned int blf_data_map[1];/* variable size bitmap of */ - /* regions of buffer in this item */ -} xfs_buf_log_format_t; - -/* - * This flag indicates that the buffer contains on disk inodes - * and requires special recovery handling. - */ -#define XFS_BLF_INODE_BUF 0x1 -/* - * This flag indicates that the buffer should not be replayed - * during recovery because its blocks are being freed. - */ -#define XFS_BLF_CANCEL 0x2 -/* - * This flag indicates that the buffer contains on disk - * user or group dquots and may require special recovery handling. - */ -#define XFS_BLF_UDQUOT_BUF 0x4 -#define XFS_BLF_PDQUOT_BUF 0x8 -#define XFS_BLF_GDQUOT_BUF 0x10 - -#define XFS_BLF_CHUNK 128 -#define XFS_BLF_SHIFT 7 -#define BIT_TO_WORD_SHIFT 5 -#define NBWORD (NBBY * sizeof(unsigned int)) - -/* - * buf log item flags - */ -#define XFS_BLI_HOLD 0x01 -#define XFS_BLI_DIRTY 0x02 -#define XFS_BLI_STALE 0x04 -#define XFS_BLI_LOGGED 0x08 -#define XFS_BLI_INODE_ALLOC_BUF 0x10 -#define XFS_BLI_STALE_INODE 0x20 -#define XFS_BLI_INODE_BUF 0x40 - -#define XFS_BLI_FLAGS \ - { XFS_BLI_HOLD, "HOLD" }, \ - { XFS_BLI_DIRTY, "DIRTY" }, \ - { XFS_BLI_STALE, "STALE" }, \ - { XFS_BLI_LOGGED, "LOGGED" }, \ - { XFS_BLI_INODE_ALLOC_BUF, "INODE_ALLOC" }, \ - { XFS_BLI_STALE_INODE, "STALE_INODE" }, \ - { XFS_BLI_INODE_BUF, "INODE_BUF" } - -#ifdef __KERNEL__ - -struct xfs_buf; -struct xfs_mount; -struct xfs_buf_log_item; - -/* - * This is the in core log item structure used to track information - * needed to log buffers. It tracks how many times the lock has been - * locked, and which 128 byte chunks of the buffer are dirty. - */ -typedef struct xfs_buf_log_item { - xfs_log_item_t bli_item; /* common item structure */ - struct xfs_buf *bli_buf; /* real buffer pointer */ - unsigned int bli_flags; /* misc flags */ - unsigned int bli_recur; /* lock recursion count */ - atomic_t bli_refcount; /* cnt of tp refs */ -#ifdef XFS_TRANS_DEBUG - char *bli_orig; /* original buffer copy */ - char *bli_logged; /* bytes logged (bitmap) */ -#endif - xfs_buf_log_format_t bli_format; /* in-log header */ -} xfs_buf_log_item_t; - -void xfs_buf_item_init(struct xfs_buf *, struct xfs_mount *); -void xfs_buf_item_relse(struct xfs_buf *); -void xfs_buf_item_log(xfs_buf_log_item_t *, uint, uint); -uint xfs_buf_item_dirty(xfs_buf_log_item_t *); -void xfs_buf_attach_iodone(struct xfs_buf *, - void(*)(struct xfs_buf *, xfs_log_item_t *), - xfs_log_item_t *); -void xfs_buf_iodone_callbacks(struct xfs_buf *); -void xfs_buf_iodone(struct xfs_buf *, struct xfs_log_item *); - -#ifdef XFS_TRANS_DEBUG -void -xfs_buf_item_flush_log_debug( - struct xfs_buf *bp, - uint first, - uint last); -#else -#define xfs_buf_item_flush_log_debug(bp, first, last) -#endif - -#endif /* __KERNEL__ */ - -#endif /* __XFS_BUF_ITEM_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_cksum.h xfsprogs-3.2.1ubuntu1/include/xfs_cksum.h --- xfsprogs-3.1.9ubuntu2/include/xfs_cksum.h 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_cksum.h 2013-06-06 22:52:59.000000000 +0000 @@ -0,0 +1,63 @@ +#ifndef _XFS_CKSUM_H +#define _XFS_CKSUM_H 1 + +#define XFS_CRC_SEED (~(__uint32_t)0) + +/* + * Calculate the intermediate checksum for a buffer that has the CRC field + * inside it. The offset of the 32bit crc fields is passed as the + * cksum_offset parameter. + */ +static inline __uint32_t +xfs_start_cksum(char *buffer, size_t length, unsigned long cksum_offset) +{ + __uint32_t zero = 0; + __uint32_t crc; + + /* Calculate CRC up to the checksum. */ + crc = crc32c(XFS_CRC_SEED, buffer, cksum_offset); + + /* Skip checksum field */ + crc = crc32c(crc, &zero, sizeof(__u32)); + + /* Calculate the rest of the CRC. */ + return crc32c(crc, &buffer[cksum_offset + sizeof(__be32)], + length - (cksum_offset + sizeof(__be32))); +} + +/* + * Convert the intermediate checksum to the final ondisk format. + * + * The CRC32c calculation uses LE format even on BE machines, but returns the + * result in host endian format. Hence we need to byte swap it back to LE format + * so that it is consistent on disk. + */ +static inline __le32 +xfs_end_cksum(__uint32_t crc) +{ + return ~cpu_to_le32(crc); +} + +/* + * Helper to generate the checksum for a buffer. + */ +static inline void +xfs_update_cksum(char *buffer, size_t length, unsigned long cksum_offset) +{ + __uint32_t crc = xfs_start_cksum(buffer, length, cksum_offset); + + *(__le32 *)(buffer + cksum_offset) = xfs_end_cksum(crc); +} + +/* + * Helper to verify the checksum for a buffer. + */ +static inline int +xfs_verify_cksum(char *buffer, size_t length, unsigned long cksum_offset) +{ + __uint32_t crc = xfs_start_cksum(buffer, length, cksum_offset); + + return *(__le32 *)(buffer + cksum_offset) == xfs_end_cksum(crc); +} + +#endif /* _XFS_CKSUM_H */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_da_btree.h xfsprogs-3.2.1ubuntu1/include/xfs_da_btree.h --- xfsprogs-3.1.9ubuntu2/include/xfs_da_btree.h 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_da_btree.h 2014-05-02 00:09:15.000000000 +0000 @@ -1,5 +1,6 @@ /* * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc. + * Copyright (c) 2013 Red Hat, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -18,63 +19,12 @@ #ifndef __XFS_DA_BTREE_H__ #define __XFS_DA_BTREE_H__ -struct xfs_buf; struct xfs_bmap_free; struct xfs_inode; -struct xfs_mount; struct xfs_trans; struct zone; /*======================================================================== - * Directory Structure when greater than XFS_LBSIZE(mp) bytes. - *========================================================================*/ - -/* - * This structure is common to both leaf nodes and non-leaf nodes in the Btree. - * - * Is is used to manage a doubly linked list of all blocks at the same - * level in the Btree, and to identify which type of block this is. - */ -#define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */ -#define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */ -#define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */ -#define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */ - -typedef struct xfs_da_blkinfo { - __be32 forw; /* previous block in list */ - __be32 back; /* following block in list */ - __be16 magic; /* validity check on block */ - __be16 pad; /* unused */ -} xfs_da_blkinfo_t; - -/* - * This is the structure of the root and intermediate nodes in the Btree. - * The leaf nodes are defined above. - * - * Entries are not packed. - * - * Since we have duplicate keys, use a binary search but always follow - * all match in the block, not just the first match found. - */ -#define XFS_DA_NODE_MAXDEPTH 5 /* max depth of Btree */ - -typedef struct xfs_da_intnode { - struct xfs_da_node_hdr { /* constant-structure header block */ - xfs_da_blkinfo_t info; /* block type, links, etc. */ - __be16 count; /* count of active entries */ - __be16 level; /* level above leaves (leaf == 0) */ - } hdr; - struct xfs_da_node_entry { - __be32 hashval; /* hash value for this descendant */ - __be32 before; /* Btree block before this key */ - } btree[1]; /* variable sized array of keys */ -} xfs_da_intnode_t; -typedef struct xfs_da_node_hdr xfs_da_node_hdr_t; -typedef struct xfs_da_node_entry xfs_da_node_entry_t; - -#define XFS_LBSIZE(mp) (mp)->m_sb.sb_blocksize - -/*======================================================================== * Btree searching and modification structure definitions. *========================================================================*/ @@ -93,6 +43,7 @@ typedef struct xfs_da_args { const __uint8_t *name; /* string (maybe not NULL terminated) */ int namelen; /* length of string (maybe no NULL) */ + __uint8_t filetype; /* filetype of inode for directories */ __uint8_t *value; /* set of bytes (maybe contain NULLs) */ int valuelen; /* length of value */ int flags; /* argument flags (eg: ATTR_NOCREATE) */ @@ -133,35 +84,6 @@ { XFS_DA_OP_CILOOKUP, "CILOOKUP" } /* - * Structure to describe buffer(s) for a block. - * This is needed in the directory version 2 format case, when - * multiple non-contiguous fsblocks might be needed to cover one - * logical directory block. - * If the buffer count is 1 then the data pointer points to the - * same place as the b_addr field for the buffer, else to kmem_alloced memory. - */ -typedef struct xfs_dabuf { - int nbuf; /* number of buffer pointers present */ - short dirty; /* data needs to be copied back */ - short bbcount; /* how large is data in bbs */ - void *data; /* pointer for buffers' data */ -#ifdef XFS_DABUF_DEBUG - inst_t *ra; /* return address of caller to make */ - struct xfs_dabuf *next; /* next in global chain */ - struct xfs_dabuf *prev; /* previous in global chain */ - struct xfs_buftarg *target; /* device for buffer */ - xfs_daddr_t blkno; /* daddr first in bps[0] */ -#endif - struct xfs_buf *bps[1]; /* actually nbuf of these */ -} xfs_dabuf_t; -#define XFS_DA_BUF_SIZE(n) \ - (sizeof(xfs_dabuf_t) + sizeof(struct xfs_buf *) * ((n) - 1)) - -#ifdef XFS_DABUF_DEBUG -extern xfs_dabuf_t *xfs_dabuf_global_list; -#endif - -/* * Storage for holding state during Btree searches and split/join ops. * * Only need space for 5 intermediate nodes. With a minimum of 62-way @@ -169,7 +91,7 @@ * which is slightly more than enough. */ typedef struct xfs_da_state_blk { - xfs_dabuf_t *bp; /* buffer containing block */ + struct xfs_buf *bp; /* buffer containing block */ xfs_dablk_t blkno; /* filesystem blkno of buffer */ xfs_daddr_t disk_blkno; /* on-disk blkno (in BBs) of buffer */ int index; /* relevant index into block */ @@ -221,43 +143,50 @@ /* * Routines used for growing the Btree. */ -int xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level, - xfs_dabuf_t **bpp, int whichfork); -int xfs_da_split(xfs_da_state_t *state); +int xfs_da3_node_create(struct xfs_da_args *args, xfs_dablk_t blkno, + int level, struct xfs_buf **bpp, int whichfork); +int xfs_da3_split(xfs_da_state_t *state); /* * Routines used for shrinking the Btree. */ -int xfs_da_join(xfs_da_state_t *state); -void xfs_da_fixhashpath(xfs_da_state_t *state, - xfs_da_state_path_t *path_to_to_fix); +int xfs_da3_join(xfs_da_state_t *state); +void xfs_da3_fixhashpath(struct xfs_da_state *state, + struct xfs_da_state_path *path_to_to_fix); /* * Routines used for finding things in the Btree. */ -int xfs_da_node_lookup_int(xfs_da_state_t *state, int *result); -int xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, +int xfs_da3_node_lookup_int(xfs_da_state_t *state, int *result); +int xfs_da3_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, int forward, int release, int *result); /* * Utility routines. */ -int xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, +int xfs_da3_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, xfs_da_state_blk_t *new_blk); +int xfs_da3_node_read(struct xfs_trans *tp, struct xfs_inode *dp, + xfs_dablk_t bno, xfs_daddr_t mappedbno, + struct xfs_buf **bpp, int which_fork); /* * Utility routines. */ int xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno); +int xfs_da_grow_inode_int(struct xfs_da_args *args, xfs_fileoff_t *bno, + int count); int xfs_da_get_buf(struct xfs_trans *trans, struct xfs_inode *dp, xfs_dablk_t bno, xfs_daddr_t mappedbno, - xfs_dabuf_t **bp, int whichfork); + struct xfs_buf **bp, int whichfork); int xfs_da_read_buf(struct xfs_trans *trans, struct xfs_inode *dp, xfs_dablk_t bno, xfs_daddr_t mappedbno, - xfs_dabuf_t **bpp, int whichfork); + struct xfs_buf **bpp, int whichfork, + const struct xfs_buf_ops *ops); xfs_daddr_t xfs_da_reada_buf(struct xfs_trans *trans, struct xfs_inode *dp, - xfs_dablk_t bno, int whichfork); + xfs_dablk_t bno, xfs_daddr_t mapped_bno, + int whichfork, const struct xfs_buf_ops *ops); int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, - xfs_dabuf_t *dead_buf); + struct xfs_buf *dead_buf); uint xfs_da_hashname(const __uint8_t *name_string, int name_length); enum xfs_dacmp xfs_da_compname(struct xfs_da_args *args, @@ -267,15 +196,7 @@ xfs_da_state_t *xfs_da_state_alloc(void); void xfs_da_state_free(xfs_da_state_t *state); -void xfs_da_buf_done(xfs_dabuf_t *dabuf); -void xfs_da_log_buf(struct xfs_trans *tp, xfs_dabuf_t *dabuf, uint first, - uint last); -void xfs_da_brelse(struct xfs_trans *tp, xfs_dabuf_t *dabuf); -void xfs_da_binval(struct xfs_trans *tp, xfs_dabuf_t *dabuf); -xfs_daddr_t xfs_da_blkno(xfs_dabuf_t *dabuf); - extern struct kmem_zone *xfs_da_state_zone; -extern struct kmem_zone *xfs_dabuf_zone; extern const struct xfs_nameops xfs_default_nameops; #endif /* __XFS_DA_BTREE_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_da_format.h xfsprogs-3.2.1ubuntu1/include/xfs_da_format.h --- xfsprogs-3.1.9ubuntu2/include/xfs_da_format.h 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_da_format.h 2014-05-02 00:09:15.000000000 +0000 @@ -0,0 +1,1362 @@ +/* + * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. + * Copyright (c) 2013 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_DA_FORMAT_H__ +#define __XFS_DA_FORMAT_H__ + +/*======================================================================== + * Directory Structure when greater than XFS_LBSIZE(mp) bytes. + *========================================================================*/ + +/* + * This structure is common to both leaf nodes and non-leaf nodes in the Btree. + * + * It is used to manage a doubly linked list of all blocks at the same + * level in the Btree, and to identify which type of block this is. + */ +#define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */ +#define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */ +#define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */ +#define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */ + +typedef struct xfs_da_blkinfo { + __be32 forw; /* previous block in list */ + __be32 back; /* following block in list */ + __be16 magic; /* validity check on block */ + __be16 pad; /* unused */ +} xfs_da_blkinfo_t; + +/* + * CRC enabled directory structure types + * + * The headers change size for the additional verification information, but + * otherwise the tree layouts and contents are unchanged. Hence the da btree + * code can use the struct xfs_da_blkinfo for manipulating the tree links and + * magic numbers without modification for both v2 and v3 nodes. + */ +#define XFS_DA3_NODE_MAGIC 0x3ebe /* magic number: non-leaf blocks */ +#define XFS_ATTR3_LEAF_MAGIC 0x3bee /* magic number: attribute leaf blks */ +#define XFS_DIR3_LEAF1_MAGIC 0x3df1 /* magic number: v2 dirlf single blks */ +#define XFS_DIR3_LEAFN_MAGIC 0x3dff /* magic number: v2 dirlf multi blks */ + +struct xfs_da3_blkinfo { + /* + * the node link manipulation code relies on the fact that the first + * element of this structure is the struct xfs_da_blkinfo so it can + * ignore the differences in the rest of the structures. + */ + struct xfs_da_blkinfo hdr; + __be32 crc; /* CRC of block */ + __be64 blkno; /* first block of the buffer */ + __be64 lsn; /* sequence number of last write */ + uuid_t uuid; /* filesystem we belong to */ + __be64 owner; /* inode that owns the block */ +}; + +/* + * This is the structure of the root and intermediate nodes in the Btree. + * The leaf nodes are defined above. + * + * Entries are not packed. + * + * Since we have duplicate keys, use a binary search but always follow + * all match in the block, not just the first match found. + */ +#define XFS_DA_NODE_MAXDEPTH 5 /* max depth of Btree */ + +typedef struct xfs_da_node_hdr { + struct xfs_da_blkinfo info; /* block type, links, etc. */ + __be16 __count; /* count of active entries */ + __be16 __level; /* level above leaves (leaf == 0) */ +} xfs_da_node_hdr_t; + +struct xfs_da3_node_hdr { + struct xfs_da3_blkinfo info; /* block type, links, etc. */ + __be16 __count; /* count of active entries */ + __be16 __level; /* level above leaves (leaf == 0) */ + __be32 __pad32; +}; + +#define XFS_DA3_NODE_CRC_OFF (offsetof(struct xfs_da3_node_hdr, info.crc)) + +typedef struct xfs_da_node_entry { + __be32 hashval; /* hash value for this descendant */ + __be32 before; /* Btree block before this key */ +} xfs_da_node_entry_t; + +typedef struct xfs_da_intnode { + struct xfs_da_node_hdr hdr; + struct xfs_da_node_entry __btree[]; +} xfs_da_intnode_t; + +struct xfs_da3_intnode { + struct xfs_da3_node_hdr hdr; + struct xfs_da_node_entry __btree[]; +}; + +/* + * In-core version of the node header to abstract the differences in the v2 and + * v3 disk format of the headers. Callers need to convert to/from disk format as + * appropriate. + */ +struct xfs_da3_icnode_hdr { + __uint32_t forw; + __uint32_t back; + __uint16_t magic; + __uint16_t count; + __uint16_t level; +}; + +extern void xfs_da3_node_hdr_from_disk(struct xfs_da3_icnode_hdr *to, + struct xfs_da_intnode *from); +extern void xfs_da3_node_hdr_to_disk(struct xfs_da_intnode *to, + struct xfs_da3_icnode_hdr *from); + +static inline int +__xfs_da3_node_hdr_size(bool v3) +{ + if (v3) + return sizeof(struct xfs_da3_node_hdr); + return sizeof(struct xfs_da_node_hdr); +} +static inline int +xfs_da3_node_hdr_size(struct xfs_da_intnode *dap) +{ + bool v3 = dap->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC); + + return __xfs_da3_node_hdr_size(v3); +} + +static inline struct xfs_da_node_entry * +xfs_da3_node_tree_p(struct xfs_da_intnode *dap) +{ + if (dap->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC)) { + struct xfs_da3_intnode *dap3 = (struct xfs_da3_intnode *)dap; + return dap3->__btree; + } + return dap->__btree; +} + +extern void xfs_da3_intnode_from_disk(struct xfs_da3_icnode_hdr *to, + struct xfs_da_intnode *from); +extern void xfs_da3_intnode_to_disk(struct xfs_da_intnode *to, + struct xfs_da3_icnode_hdr *from); + +#define XFS_LBSIZE(mp) (mp)->m_sb.sb_blocksize + +/* + * Directory version 2. + * + * There are 4 possible formats: + * - shortform - embedded into the inode + * - single block - data with embedded leaf at the end + * - multiple data blocks, single leaf+freeindex block + * - data blocks, node and leaf blocks (btree), freeindex blocks + * + * Note: many node blocks structures and constants are shared with the attr + * code and defined in xfs_da_btree.h. + */ + +#define XFS_DIR2_BLOCK_MAGIC 0x58443242 /* XD2B: single block dirs */ +#define XFS_DIR2_DATA_MAGIC 0x58443244 /* XD2D: multiblock dirs */ +#define XFS_DIR2_FREE_MAGIC 0x58443246 /* XD2F: free index blocks */ + +/* + * Directory Version 3 With CRCs. + * + * The tree formats are the same as for version 2 directories. The difference + * is in the block header and dirent formats. In many cases the v3 structures + * use v2 definitions as they are no different and this makes code sharing much + * easier. + * + * Also, the xfs_dir3_*() functions handle both v2 and v3 formats - if the + * format is v2 then they switch to the existing v2 code, or the format is v3 + * they implement the v3 functionality. This means the existing dir2 is a mix of + * xfs_dir2/xfs_dir3 calls and functions. The xfs_dir3 functions are called + * where there is a difference in the formats, otherwise the code is unchanged. + * + * Where it is possible, the code decides what to do based on the magic numbers + * in the blocks rather than feature bits in the superblock. This means the code + * is as independent of the external XFS code as possible as doesn't require + * passing struct xfs_mount pointers into places where it isn't really + * necessary. + * + * Version 3 includes: + * + * - a larger block header for CRC and identification purposes and so the + * offsets of all the structures inside the blocks are different. + * + * - new magic numbers to be able to detect the v2/v3 types on the fly. + */ + +#define XFS_DIR3_BLOCK_MAGIC 0x58444233 /* XDB3: single block dirs */ +#define XFS_DIR3_DATA_MAGIC 0x58444433 /* XDD3: multiblock dirs */ +#define XFS_DIR3_FREE_MAGIC 0x58444633 /* XDF3: free index blocks */ + +/* + * Dirents in version 3 directories have a file type field. Additions to this + * list are an on-disk format change, requiring feature bits. Valid values + * are as follows: + */ +#define XFS_DIR3_FT_UNKNOWN 0 +#define XFS_DIR3_FT_REG_FILE 1 +#define XFS_DIR3_FT_DIR 2 +#define XFS_DIR3_FT_CHRDEV 3 +#define XFS_DIR3_FT_BLKDEV 4 +#define XFS_DIR3_FT_FIFO 5 +#define XFS_DIR3_FT_SOCK 6 +#define XFS_DIR3_FT_SYMLINK 7 +#define XFS_DIR3_FT_WHT 8 + +#define XFS_DIR3_FT_MAX 9 + +/* + * Byte offset in data block and shortform entry. + */ +typedef __uint16_t xfs_dir2_data_off_t; +#define NULLDATAOFF 0xffffU +typedef uint xfs_dir2_data_aoff_t; /* argument form */ + +/* + * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t. + * Only need 16 bits, this is the byte offset into the single block form. + */ +typedef struct { __uint8_t i[2]; } __arch_pack xfs_dir2_sf_off_t; + +/* + * Offset in data space of a data entry. + */ +typedef __uint32_t xfs_dir2_dataptr_t; +#define XFS_DIR2_MAX_DATAPTR ((xfs_dir2_dataptr_t)0xffffffff) +#define XFS_DIR2_NULL_DATAPTR ((xfs_dir2_dataptr_t)0) + +/* + * Byte offset in a directory. + */ +typedef xfs_off_t xfs_dir2_off_t; + +/* + * Directory block number (logical dirblk in file) + */ +typedef __uint32_t xfs_dir2_db_t; + +/* + * Inode number stored as 8 8-bit values. + */ +typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t; + +/* + * Inode number stored as 4 8-bit values. + * Works a lot of the time, when all the inode numbers in a directory + * fit in 32 bits. + */ +typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t; + +typedef union { + xfs_dir2_ino8_t i8; + xfs_dir2_ino4_t i4; +} xfs_dir2_inou_t; +#define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL) + +/* + * Directory layout when stored internal to an inode. + * + * Small directories are packed as tightly as possible so as to fit into the + * literal area of the inode. These "shortform" directories consist of a + * single xfs_dir2_sf_hdr header followed by zero or more xfs_dir2_sf_entry + * structures. Due the different inode number storage size and the variable + * length name field in the xfs_dir2_sf_entry all these structure are + * variable length, and the accessors in this file should be used to iterate + * over them. + */ +typedef struct xfs_dir2_sf_hdr { + __uint8_t count; /* count of entries */ + __uint8_t i8count; /* count of 8-byte inode #s */ + xfs_dir2_inou_t parent; /* parent dir inode number */ +} __arch_pack xfs_dir2_sf_hdr_t; + +typedef struct xfs_dir2_sf_entry { + __u8 namelen; /* actual name length */ + xfs_dir2_sf_off_t offset; /* saved offset */ + __u8 name[]; /* name, variable size */ + /* + * A single byte containing the file type field follows the inode + * number for version 3 directory entries. + * + * A xfs_dir2_ino8_t or xfs_dir2_ino4_t follows here, at a + * variable offset after the name. + */ +} __arch_pack xfs_dir2_sf_entry_t; + +static inline int xfs_dir2_sf_hdr_size(int i8count) +{ + return sizeof(struct xfs_dir2_sf_hdr) - + (i8count == 0) * + (sizeof(xfs_dir2_ino8_t) - sizeof(xfs_dir2_ino4_t)); +} + +static inline xfs_dir2_data_aoff_t +xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep) +{ + return get_unaligned_be16(&sfep->offset.i); +} + +static inline void +xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off) +{ + put_unaligned_be16(off, &sfep->offset.i); +} + +static inline struct xfs_dir2_sf_entry * +xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr) +{ + return (struct xfs_dir2_sf_entry *) + ((char *)hdr + xfs_dir2_sf_hdr_size(hdr->i8count)); +} + +static inline int +xfs_dir3_sf_entsize( + struct xfs_mount *mp, + struct xfs_dir2_sf_hdr *hdr, + int len) +{ + int count = sizeof(struct xfs_dir2_sf_entry); /* namelen + offset */ + + count += len; /* name */ + count += hdr->i8count ? sizeof(xfs_dir2_ino8_t) : + sizeof(xfs_dir2_ino4_t); /* ino # */ + if (xfs_sb_version_hasftype(&mp->m_sb)) + count += sizeof(__uint8_t); /* file type */ + return count; +} + +static inline struct xfs_dir2_sf_entry * +xfs_dir3_sf_nextentry( + struct xfs_mount *mp, + struct xfs_dir2_sf_hdr *hdr, + struct xfs_dir2_sf_entry *sfep) +{ + return (struct xfs_dir2_sf_entry *) + ((char *)sfep + xfs_dir3_sf_entsize(mp, hdr, sfep->namelen)); +} + +/* + * in dir3 shortform directories, the file type field is stored at a variable + * offset after the inode number. Because it's only a single byte, endian + * conversion is not necessary. + */ +static inline __uint8_t * +xfs_dir3_sfe_ftypep( + struct xfs_dir2_sf_hdr *hdr, + struct xfs_dir2_sf_entry *sfep) +{ + return (__uint8_t *)&sfep->name[sfep->namelen]; +} + +static inline __uint8_t +xfs_dir3_sfe_get_ftype( + struct xfs_mount *mp, + struct xfs_dir2_sf_hdr *hdr, + struct xfs_dir2_sf_entry *sfep) +{ + __uint8_t *ftp; + + if (!xfs_sb_version_hasftype(&mp->m_sb)) + return XFS_DIR3_FT_UNKNOWN; + + ftp = xfs_dir3_sfe_ftypep(hdr, sfep); + if (*ftp >= XFS_DIR3_FT_MAX) + return XFS_DIR3_FT_UNKNOWN; + return *ftp; +} + +static inline void +xfs_dir3_sfe_put_ftype( + struct xfs_mount *mp, + struct xfs_dir2_sf_hdr *hdr, + struct xfs_dir2_sf_entry *sfep, + __uint8_t ftype) +{ + __uint8_t *ftp; + + ASSERT(ftype < XFS_DIR3_FT_MAX); + + if (!xfs_sb_version_hasftype(&mp->m_sb)) + return; + ftp = xfs_dir3_sfe_ftypep(hdr, sfep); + *ftp = ftype; +} + +/* + * Data block structures. + * + * A pure data block looks like the following drawing on disk: + * + * +-------------------------------------------------+ + * | xfs_dir2_data_hdr_t | + * +-------------------------------------------------+ + * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t | + * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t | + * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t | + * | ... | + * +-------------------------------------------------+ + * | unused space | + * +-------------------------------------------------+ + * + * As all the entries are variable size structures the accessors below should + * be used to iterate over them. + * + * In addition to the pure data blocks for the data and node formats, + * most structures are also used for the combined data/freespace "block" + * format below. + */ + +#define XFS_DIR2_DATA_ALIGN_LOG 3 /* i.e., 8 bytes */ +#define XFS_DIR2_DATA_ALIGN (1 << XFS_DIR2_DATA_ALIGN_LOG) +#define XFS_DIR2_DATA_FREE_TAG 0xffff +#define XFS_DIR2_DATA_FD_COUNT 3 + +/* + * Directory address space divided into sections, + * spaces separated by 32GB. + */ +#define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG)) +#define XFS_DIR2_DATA_SPACE 0 +#define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE) +#define XFS_DIR2_DATA_FIRSTDB(mp) \ + xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET) + +/* + * Describe a free area in the data block. + * + * The freespace will be formatted as a xfs_dir2_data_unused_t. + */ +typedef struct xfs_dir2_data_free { + __be16 offset; /* start of freespace */ + __be16 length; /* length of freespace */ +} xfs_dir2_data_free_t; + +/* + * Header for the data blocks. + * + * The code knows that XFS_DIR2_DATA_FD_COUNT is 3. + */ +typedef struct xfs_dir2_data_hdr { + __be32 magic; /* XFS_DIR2_DATA_MAGIC or */ + /* XFS_DIR2_BLOCK_MAGIC */ + xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT]; +} xfs_dir2_data_hdr_t; + +/* + * define a structure for all the verification fields we are adding to the + * directory block structures. This will be used in several structures. + * The magic number must be the first entry to align with all the dir2 + * structures so we determine how to decode them just by the magic number. + */ +struct xfs_dir3_blk_hdr { + __be32 magic; /* magic number */ + __be32 crc; /* CRC of block */ + __be64 blkno; /* first block of the buffer */ + __be64 lsn; /* sequence number of last write */ + uuid_t uuid; /* filesystem we belong to */ + __be64 owner; /* inode that owns the block */ +}; + +struct xfs_dir3_data_hdr { + struct xfs_dir3_blk_hdr hdr; + xfs_dir2_data_free_t best_free[XFS_DIR2_DATA_FD_COUNT]; + __be32 pad; /* 64 bit alignment */ +}; + +#define XFS_DIR3_DATA_CRC_OFF offsetof(struct xfs_dir3_data_hdr, hdr.crc) + +static inline struct xfs_dir2_data_free * +xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr) +{ + if (hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { + struct xfs_dir3_data_hdr *hdr3 = (struct xfs_dir3_data_hdr *)hdr; + return hdr3->best_free; + } + return hdr->bestfree; +} + +/* + * Active entry in a data block. + * + * Aligned to 8 bytes. After the variable length name field there is a + * 2 byte tag field, which can be accessed using xfs_dir3_data_entry_tag_p. + * + * For dir3 structures, there is file type field between the name and the tag. + * This can only be manipulated by helper functions. It is packed hard against + * the end of the name so any padding for rounding is between the file type and + * the tag. + */ +typedef struct xfs_dir2_data_entry { + __be64 inumber; /* inode number */ + __u8 namelen; /* name length */ + __u8 name[]; /* name bytes, no null */ + /* __u8 filetype; */ /* type of inode we point to */ + /* __be16 tag; */ /* starting offset of us */ +} xfs_dir2_data_entry_t; + +/* + * Unused entry in a data block. + * + * Aligned to 8 bytes. Tag appears as the last 2 bytes and must be accessed + * using xfs_dir2_data_unused_tag_p. + */ +typedef struct xfs_dir2_data_unused { + __be16 freetag; /* XFS_DIR2_DATA_FREE_TAG */ + __be16 length; /* total free length */ + /* variable offset */ + __be16 tag; /* starting offset of us */ +} xfs_dir2_data_unused_t; + +/* + * Size of a data entry. + */ +static inline int +__xfs_dir3_data_entsize( + bool ftype, + int n) +{ + int size = offsetof(struct xfs_dir2_data_entry, name[0]); + + size += n; + size += sizeof(xfs_dir2_data_off_t); + if (ftype) + size += sizeof(__uint8_t); + return roundup(size, XFS_DIR2_DATA_ALIGN); +} +static inline int +xfs_dir3_data_entsize( + struct xfs_mount *mp, + int n) +{ + bool ftype = xfs_sb_version_hasftype(&mp->m_sb) ? true : false; + return __xfs_dir3_data_entsize(ftype, n); +} + +static inline __uint8_t +xfs_dir3_dirent_get_ftype( + struct xfs_mount *mp, + struct xfs_dir2_data_entry *dep) +{ + if (xfs_sb_version_hasftype(&mp->m_sb)) { + __uint8_t type = dep->name[dep->namelen]; + + ASSERT(type < XFS_DIR3_FT_MAX); + if (type < XFS_DIR3_FT_MAX) + return type; + + } + return XFS_DIR3_FT_UNKNOWN; +} + +static inline void +xfs_dir3_dirent_put_ftype( + struct xfs_mount *mp, + struct xfs_dir2_data_entry *dep, + __uint8_t type) +{ + ASSERT(type < XFS_DIR3_FT_MAX); + ASSERT(dep->namelen != 0); + + if (xfs_sb_version_hasftype(&mp->m_sb)) + dep->name[dep->namelen] = type; +} + +/* + * Pointer to an entry's tag word. + */ +static inline __be16 * +xfs_dir3_data_entry_tag_p( + struct xfs_mount *mp, + struct xfs_dir2_data_entry *dep) +{ + return (__be16 *)((char *)dep + + xfs_dir3_data_entsize(mp, dep->namelen) - sizeof(__be16)); +} + +/* + * Pointer to a freespace's tag word. + */ +static inline __be16 * +xfs_dir2_data_unused_tag_p(struct xfs_dir2_data_unused *dup) +{ + return (__be16 *)((char *)dup + + be16_to_cpu(dup->length) - sizeof(__be16)); +} + +static inline size_t +xfs_dir3_data_hdr_size(bool dir3) +{ + if (dir3) + return sizeof(struct xfs_dir3_data_hdr); + return sizeof(struct xfs_dir2_data_hdr); +} + +static inline size_t +xfs_dir3_data_entry_offset(struct xfs_dir2_data_hdr *hdr) +{ + bool dir3 = hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC); + return xfs_dir3_data_hdr_size(dir3); +} + +static inline struct xfs_dir2_data_entry * +xfs_dir3_data_entry_p(struct xfs_dir2_data_hdr *hdr) +{ + return (struct xfs_dir2_data_entry *) + ((char *)hdr + xfs_dir3_data_entry_offset(hdr)); +} + +static inline struct xfs_dir2_data_unused * +xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr) +{ + return (struct xfs_dir2_data_unused *) + ((char *)hdr + xfs_dir3_data_entry_offset(hdr)); +} + +/* + * Offsets of . and .. in data space (always block 0) + * + * XXX: there is scope for significant optimisation of the logic here. Right + * now we are checking for "dir3 format" over and over again. Ideally we should + * only do it once for each operation. + */ +static inline xfs_dir2_data_aoff_t +xfs_dir3_data_dot_offset(struct xfs_mount *mp) +{ + return xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&mp->m_sb)); +} + +static inline xfs_dir2_data_aoff_t +xfs_dir3_data_dotdot_offset(struct xfs_mount *mp) +{ + return xfs_dir3_data_dot_offset(mp) + + xfs_dir3_data_entsize(mp, 1); +} + +static inline xfs_dir2_data_aoff_t +xfs_dir3_data_first_offset(struct xfs_mount *mp) +{ + return xfs_dir3_data_dotdot_offset(mp) + + xfs_dir3_data_entsize(mp, 2); +} + +/* + * location of . and .. in data space (always block 0) + */ +static inline struct xfs_dir2_data_entry * +xfs_dir3_data_dot_entry_p( + struct xfs_mount *mp, + struct xfs_dir2_data_hdr *hdr) +{ + return (struct xfs_dir2_data_entry *) + ((char *)hdr + xfs_dir3_data_dot_offset(mp)); +} + +static inline struct xfs_dir2_data_entry * +xfs_dir3_data_dotdot_entry_p( + struct xfs_mount *mp, + struct xfs_dir2_data_hdr *hdr) +{ + return (struct xfs_dir2_data_entry *) + ((char *)hdr + xfs_dir3_data_dotdot_offset(mp)); +} + +static inline struct xfs_dir2_data_entry * +xfs_dir3_data_first_entry_p( + struct xfs_mount *mp, + struct xfs_dir2_data_hdr *hdr) +{ + return (struct xfs_dir2_data_entry *) + ((char *)hdr + xfs_dir3_data_first_offset(mp)); +} + +/* + * Leaf block structures. + * + * A pure leaf block looks like the following drawing on disk: + * + * +---------------------------+ + * | xfs_dir2_leaf_hdr_t | + * +---------------------------+ + * | xfs_dir2_leaf_entry_t | + * | xfs_dir2_leaf_entry_t | + * | xfs_dir2_leaf_entry_t | + * | xfs_dir2_leaf_entry_t | + * | ... | + * +---------------------------+ + * | xfs_dir2_data_off_t | + * | xfs_dir2_data_off_t | + * | xfs_dir2_data_off_t | + * | ... | + * +---------------------------+ + * | xfs_dir2_leaf_tail_t | + * +---------------------------+ + * + * The xfs_dir2_data_off_t members (bests) and tail are at the end of the block + * for single-leaf (magic = XFS_DIR2_LEAF1_MAGIC) blocks only, but not present + * for directories with separate leaf nodes and free space blocks + * (magic = XFS_DIR2_LEAFN_MAGIC). + * + * As all the entries are variable size structures the accessors below should + * be used to iterate over them. + */ + +/* + * Offset of the leaf/node space. First block in this space + * is the btree root. + */ +#define XFS_DIR2_LEAF_SPACE 1 +#define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE) +#define XFS_DIR2_LEAF_FIRSTDB(mp) \ + xfs_dir2_byte_to_db(mp, XFS_DIR2_LEAF_OFFSET) + +/* + * Leaf block header. + */ +typedef struct xfs_dir2_leaf_hdr { + xfs_da_blkinfo_t info; /* header for da routines */ + __be16 count; /* count of entries */ + __be16 stale; /* count of stale entries */ +} xfs_dir2_leaf_hdr_t; + +struct xfs_dir3_leaf_hdr { + struct xfs_da3_blkinfo info; /* header for da routines */ + __be16 count; /* count of entries */ + __be16 stale; /* count of stale entries */ + __be32 pad; /* 64 bit alignment */ +}; + +struct xfs_dir3_icleaf_hdr { + __uint32_t forw; + __uint32_t back; + __uint16_t magic; + __uint16_t count; + __uint16_t stale; +}; + +/* + * Leaf block entry. + */ +typedef struct xfs_dir2_leaf_entry { + __be32 hashval; /* hash value of name */ + __be32 address; /* address of data entry */ +} xfs_dir2_leaf_entry_t; + +/* + * Leaf block tail. + */ +typedef struct xfs_dir2_leaf_tail { + __be32 bestcount; +} xfs_dir2_leaf_tail_t; + +/* + * Leaf block. + */ +typedef struct xfs_dir2_leaf { + xfs_dir2_leaf_hdr_t hdr; /* leaf header */ + xfs_dir2_leaf_entry_t __ents[]; /* entries */ +} xfs_dir2_leaf_t; + +struct xfs_dir3_leaf { + struct xfs_dir3_leaf_hdr hdr; /* leaf header */ + struct xfs_dir2_leaf_entry __ents[]; /* entries */ +}; + +#define XFS_DIR3_LEAF_CRC_OFF offsetof(struct xfs_dir3_leaf_hdr, info.crc) + +extern void xfs_dir3_leaf_hdr_from_disk(struct xfs_dir3_icleaf_hdr *to, + struct xfs_dir2_leaf *from); + +static inline int +xfs_dir3_leaf_hdr_size(struct xfs_dir2_leaf *lp) +{ + if (lp->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) || + lp->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) + return sizeof(struct xfs_dir3_leaf_hdr); + return sizeof(struct xfs_dir2_leaf_hdr); +} + +static inline int +xfs_dir3_max_leaf_ents(struct xfs_mount *mp, struct xfs_dir2_leaf *lp) +{ + return (mp->m_dirblksize - xfs_dir3_leaf_hdr_size(lp)) / + (uint)sizeof(struct xfs_dir2_leaf_entry); +} + +/* + * Get address of the bestcount field in the single-leaf block. + */ +static inline struct xfs_dir2_leaf_entry * +xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp) +{ + if (lp->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) || + lp->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) { + struct xfs_dir3_leaf *lp3 = (struct xfs_dir3_leaf *)lp; + return lp3->__ents; + } + return lp->__ents; +} + +/* + * Get address of the bestcount field in the single-leaf block. + */ +static inline struct xfs_dir2_leaf_tail * +xfs_dir2_leaf_tail_p(struct xfs_mount *mp, struct xfs_dir2_leaf *lp) +{ + return (struct xfs_dir2_leaf_tail *) + ((char *)lp + mp->m_dirblksize - + sizeof(struct xfs_dir2_leaf_tail)); +} + +/* + * Get address of the bests array in the single-leaf block. + */ +static inline __be16 * +xfs_dir2_leaf_bests_p(struct xfs_dir2_leaf_tail *ltp) +{ + return (__be16 *)ltp - be32_to_cpu(ltp->bestcount); +} + +/* + * DB blocks here are logical directory block numbers, not filesystem blocks. + */ + +/* + * Convert dataptr to byte in file space + */ +static inline xfs_dir2_off_t +xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) +{ + return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG; +} + +/* + * Convert byte in file space to dataptr. It had better be aligned. + */ +static inline xfs_dir2_dataptr_t +xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by) +{ + return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG); +} + +/* + * Convert byte in space to (DB) block + */ +static inline xfs_dir2_db_t +xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by) +{ + return (xfs_dir2_db_t) + (by >> (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)); +} + +/* + * Convert dataptr to a block number + */ +static inline xfs_dir2_db_t +xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) +{ + return xfs_dir2_byte_to_db(mp, xfs_dir2_dataptr_to_byte(mp, dp)); +} + +/* + * Convert byte in space to offset in a block + */ +static inline xfs_dir2_data_aoff_t +xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by) +{ + return (xfs_dir2_data_aoff_t)(by & + ((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) - 1)); +} + +/* + * Convert dataptr to a byte offset in a block + */ +static inline xfs_dir2_data_aoff_t +xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) +{ + return xfs_dir2_byte_to_off(mp, xfs_dir2_dataptr_to_byte(mp, dp)); +} + +/* + * Convert block and offset to byte in space + */ +static inline xfs_dir2_off_t +xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db, + xfs_dir2_data_aoff_t o) +{ + return ((xfs_dir2_off_t)db << + (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) + o; +} + +/* + * Convert block (DB) to block (dablk) + */ +static inline xfs_dablk_t +xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db) +{ + return (xfs_dablk_t)(db << mp->m_sb.sb_dirblklog); +} + +/* + * Convert byte in space to (DA) block + */ +static inline xfs_dablk_t +xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by) +{ + return xfs_dir2_db_to_da(mp, xfs_dir2_byte_to_db(mp, by)); +} + +/* + * Convert block and offset to dataptr + */ +static inline xfs_dir2_dataptr_t +xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db, + xfs_dir2_data_aoff_t o) +{ + return xfs_dir2_byte_to_dataptr(mp, xfs_dir2_db_off_to_byte(mp, db, o)); +} + +/* + * Convert block (dablk) to block (DB) + */ +static inline xfs_dir2_db_t +xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da) +{ + return (xfs_dir2_db_t)(da >> mp->m_sb.sb_dirblklog); +} + +/* + * Convert block (dablk) to byte offset in space + */ +static inline xfs_dir2_off_t +xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da) +{ + return xfs_dir2_db_off_to_byte(mp, xfs_dir2_da_to_db(mp, da), 0); +} + +/* + * Free space block defintions for the node format. + */ + +/* + * Offset of the freespace index. + */ +#define XFS_DIR2_FREE_SPACE 2 +#define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE) +#define XFS_DIR2_FREE_FIRSTDB(mp) \ + xfs_dir2_byte_to_db(mp, XFS_DIR2_FREE_OFFSET) + +typedef struct xfs_dir2_free_hdr { + __be32 magic; /* XFS_DIR2_FREE_MAGIC */ + __be32 firstdb; /* db of first entry */ + __be32 nvalid; /* count of valid entries */ + __be32 nused; /* count of used entries */ +} xfs_dir2_free_hdr_t; + +typedef struct xfs_dir2_free { + xfs_dir2_free_hdr_t hdr; /* block header */ + __be16 bests[]; /* best free counts */ + /* unused entries are -1 */ +} xfs_dir2_free_t; + +struct xfs_dir3_free_hdr { + struct xfs_dir3_blk_hdr hdr; + __be32 firstdb; /* db of first entry */ + __be32 nvalid; /* count of valid entries */ + __be32 nused; /* count of used entries */ + __be32 pad; /* 64 bit alignment */ +}; + +struct xfs_dir3_free { + struct xfs_dir3_free_hdr hdr; + __be16 bests[]; /* best free counts */ + /* unused entries are -1 */ +}; + +#define XFS_DIR3_FREE_CRC_OFF offsetof(struct xfs_dir3_free, hdr.hdr.crc) + +/* + * In core version of the free block header, abstracted away from on-disk format + * differences. Use this in the code, and convert to/from the disk version using + * xfs_dir3_free_hdr_from_disk/xfs_dir3_free_hdr_to_disk. + */ +struct xfs_dir3_icfree_hdr { + __uint32_t magic; + __uint32_t firstdb; + __uint32_t nvalid; + __uint32_t nused; + +}; + +void xfs_dir3_free_hdr_from_disk(struct xfs_dir3_icfree_hdr *to, + struct xfs_dir2_free *from); + +static inline int +xfs_dir3_free_hdr_size(struct xfs_mount *mp) +{ + if (xfs_sb_version_hascrc(&mp->m_sb)) + return sizeof(struct xfs_dir3_free_hdr); + return sizeof(struct xfs_dir2_free_hdr); +} + +static inline int +xfs_dir3_free_max_bests(struct xfs_mount *mp) +{ + return (mp->m_dirblksize - xfs_dir3_free_hdr_size(mp)) / + sizeof(xfs_dir2_data_off_t); +} + +static inline __be16 * +xfs_dir3_free_bests_p(struct xfs_mount *mp, struct xfs_dir2_free *free) +{ + return (__be16 *)((char *)free + xfs_dir3_free_hdr_size(mp)); +} + +/* + * Convert data space db to the corresponding free db. + */ +static inline xfs_dir2_db_t +xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db) +{ + return XFS_DIR2_FREE_FIRSTDB(mp) + db / xfs_dir3_free_max_bests(mp); +} + +/* + * Convert data space db to the corresponding index in a free db. + */ +static inline int +xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db) +{ + return db % xfs_dir3_free_max_bests(mp); +} + +/* + * Single block format. + * + * The single block format looks like the following drawing on disk: + * + * +-------------------------------------------------+ + * | xfs_dir2_data_hdr_t | + * +-------------------------------------------------+ + * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t | + * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t | + * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t : + * | ... | + * +-------------------------------------------------+ + * | unused space | + * +-------------------------------------------------+ + * | ... | + * | xfs_dir2_leaf_entry_t | + * | xfs_dir2_leaf_entry_t | + * +-------------------------------------------------+ + * | xfs_dir2_block_tail_t | + * +-------------------------------------------------+ + * + * As all the entries are variable size structures the accessors below should + * be used to iterate over them. + */ + +typedef struct xfs_dir2_block_tail { + __be32 count; /* count of leaf entries */ + __be32 stale; /* count of stale lf entries */ +} xfs_dir2_block_tail_t; + +/* + * Pointer to the leaf header embedded in a data block (1-block format) + */ +static inline struct xfs_dir2_block_tail * +xfs_dir2_block_tail_p(struct xfs_mount *mp, struct xfs_dir2_data_hdr *hdr) +{ + return ((struct xfs_dir2_block_tail *) + ((char *)hdr + mp->m_dirblksize)) - 1; +} + +/* + * Pointer to the leaf entries embedded in a data block (1-block format) + */ +static inline struct xfs_dir2_leaf_entry * +xfs_dir2_block_leaf_p(struct xfs_dir2_block_tail *btp) +{ + return ((struct xfs_dir2_leaf_entry *)btp) - be32_to_cpu(btp->count); +} + + +/* + * Attribute storage layout + * + * Attribute lists are structured around Btrees where all the data + * elements are in the leaf nodes. Attribute names are hashed into an int, + * then that int is used as the index into the Btree. Since the hashval + * of an attribute name may not be unique, we may have duplicate keys. The + * internal links in the Btree are logical block offsets into the file. + * + *======================================================================== + * Attribute structure when equal to XFS_LBSIZE(mp) bytes. + *======================================================================== + * + * Struct leaf_entry's are packed from the top. Name/values grow from the + * bottom but are not packed. The freemap contains run-length-encoded entries + * for the free bytes after the leaf_entry's, but only the N largest such, + * smaller runs are dropped. When the freemap doesn't show enough space + * for an allocation, we compact the name/value area and try again. If we + * still don't have enough space, then we have to split the block. The + * name/value structs (both local and remote versions) must be 32bit aligned. + * + * Since we have duplicate hash keys, for each key that matches, compare + * the actual name string. The root and intermediate node search always + * takes the first-in-the-block key match found, so we should only have + * to work "forw"ard. If none matches, continue with the "forw"ard leaf + * nodes until the hash key changes or the attribute name is found. + * + * We store the fact that an attribute is a ROOT/USER/SECURE attribute in + * the leaf_entry. The namespaces are independent only because we also look + * at the namespace bit when we are looking for a matching attribute name. + * + * We also store an "incomplete" bit in the leaf_entry. It shows that an + * attribute is in the middle of being created and should not be shown to + * the user if we crash during the time that the bit is set. We clear the + * bit when we have finished setting up the attribute. We do this because + * we cannot create some large attributes inside a single transaction, and we + * need some indication that we weren't finished if we crash in the middle. + */ +#define XFS_ATTR_LEAF_MAPSIZE 3 /* how many freespace slots */ + +typedef struct xfs_attr_leaf_map { /* RLE map of free bytes */ + __be16 base; /* base of free region */ + __be16 size; /* length of free region */ +} xfs_attr_leaf_map_t; + +typedef struct xfs_attr_leaf_hdr { /* constant-structure header block */ + xfs_da_blkinfo_t info; /* block type, links, etc. */ + __be16 count; /* count of active leaf_entry's */ + __be16 usedbytes; /* num bytes of names/values stored */ + __be16 firstused; /* first used byte in name area */ + __u8 holes; /* != 0 if blk needs compaction */ + __u8 pad1; + xfs_attr_leaf_map_t freemap[XFS_ATTR_LEAF_MAPSIZE]; + /* N largest free regions */ +} xfs_attr_leaf_hdr_t; + +typedef struct xfs_attr_leaf_entry { /* sorted on key, not name */ + __be32 hashval; /* hash value of name */ + __be16 nameidx; /* index into buffer of name/value */ + __u8 flags; /* LOCAL/ROOT/SECURE/INCOMPLETE flag */ + __u8 pad2; /* unused pad byte */ +} xfs_attr_leaf_entry_t; + +typedef struct xfs_attr_leaf_name_local { + __be16 valuelen; /* number of bytes in value */ + __u8 namelen; /* length of name bytes */ + __u8 nameval[1]; /* name/value bytes */ +} xfs_attr_leaf_name_local_t; + +typedef struct xfs_attr_leaf_name_remote { + __be32 valueblk; /* block number of value bytes */ + __be32 valuelen; /* number of bytes in value */ + __u8 namelen; /* length of name bytes */ + __u8 name[1]; /* name bytes */ +} xfs_attr_leaf_name_remote_t; + +typedef struct xfs_attr_leafblock { + xfs_attr_leaf_hdr_t hdr; /* constant-structure header block */ + xfs_attr_leaf_entry_t entries[1]; /* sorted on key, not name */ + xfs_attr_leaf_name_local_t namelist; /* grows from bottom of buf */ + xfs_attr_leaf_name_remote_t valuelist; /* grows from bottom of buf */ +} xfs_attr_leafblock_t; + +/* + * CRC enabled leaf structures. Called "version 3" structures to match the + * version number of the directory and dablk structures for this feature, and + * attr2 is already taken by the variable inode attribute fork size feature. + */ +struct xfs_attr3_leaf_hdr { + struct xfs_da3_blkinfo info; + __be16 count; + __be16 usedbytes; + __be16 firstused; + __u8 holes; + __u8 pad1; + struct xfs_attr_leaf_map freemap[XFS_ATTR_LEAF_MAPSIZE]; + __be32 pad2; /* 64 bit alignment */ +}; + +#define XFS_ATTR3_LEAF_CRC_OFF (offsetof(struct xfs_attr3_leaf_hdr, info.crc)) + +struct xfs_attr3_leafblock { + struct xfs_attr3_leaf_hdr hdr; + struct xfs_attr_leaf_entry entries[1]; + + /* + * The rest of the block contains the following structures after the + * leaf entries, growing from the bottom up. The variables are never + * referenced, the locations accessed purely from helper functions. + * + * struct xfs_attr_leaf_name_local + * struct xfs_attr_leaf_name_remote + */ +}; + +/* + * incore, neutral version of the attribute leaf header + */ +struct xfs_attr3_icleaf_hdr { + __uint32_t forw; + __uint32_t back; + __uint16_t magic; + __uint16_t count; + __uint16_t usedbytes; + __uint16_t firstused; + __u8 holes; + struct { + __uint16_t base; + __uint16_t size; + } freemap[XFS_ATTR_LEAF_MAPSIZE]; +}; + +/* + * Flags used in the leaf_entry[i].flags field. + * NOTE: the INCOMPLETE bit must not collide with the flags bits specified + * on the system call, they are "or"ed together for various operations. + */ +#define XFS_ATTR_LOCAL_BIT 0 /* attr is stored locally */ +#define XFS_ATTR_ROOT_BIT 1 /* limit access to trusted attrs */ +#define XFS_ATTR_SECURE_BIT 2 /* limit access to secure attrs */ +#define XFS_ATTR_INCOMPLETE_BIT 7 /* attr in middle of create/delete */ +#define XFS_ATTR_LOCAL (1 << XFS_ATTR_LOCAL_BIT) +#define XFS_ATTR_ROOT (1 << XFS_ATTR_ROOT_BIT) +#define XFS_ATTR_SECURE (1 << XFS_ATTR_SECURE_BIT) +#define XFS_ATTR_INCOMPLETE (1 << XFS_ATTR_INCOMPLETE_BIT) + +/* + * Conversion macros for converting namespace bits from argument flags + * to ondisk flags. + */ +#define XFS_ATTR_NSP_ARGS_MASK (ATTR_ROOT | ATTR_SECURE) +#define XFS_ATTR_NSP_ONDISK_MASK (XFS_ATTR_ROOT | XFS_ATTR_SECURE) +#define XFS_ATTR_NSP_ONDISK(flags) ((flags) & XFS_ATTR_NSP_ONDISK_MASK) +#define XFS_ATTR_NSP_ARGS(flags) ((flags) & XFS_ATTR_NSP_ARGS_MASK) +#define XFS_ATTR_NSP_ARGS_TO_ONDISK(x) (((x) & ATTR_ROOT ? XFS_ATTR_ROOT : 0) |\ + ((x) & ATTR_SECURE ? XFS_ATTR_SECURE : 0)) +#define XFS_ATTR_NSP_ONDISK_TO_ARGS(x) (((x) & XFS_ATTR_ROOT ? ATTR_ROOT : 0) |\ + ((x) & XFS_ATTR_SECURE ? ATTR_SECURE : 0)) + +/* + * Alignment for namelist and valuelist entries (since they are mixed + * there can be only one alignment value) + */ +#define XFS_ATTR_LEAF_NAME_ALIGN ((uint)sizeof(xfs_dablk_t)) + +static inline int +xfs_attr3_leaf_hdr_size(struct xfs_attr_leafblock *leafp) +{ + if (leafp->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)) + return sizeof(struct xfs_attr3_leaf_hdr); + return sizeof(struct xfs_attr_leaf_hdr); +} + +static inline struct xfs_attr_leaf_entry * +xfs_attr3_leaf_entryp(xfs_attr_leafblock_t *leafp) +{ + if (leafp->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)) + return &((struct xfs_attr3_leafblock *)leafp)->entries[0]; + return &leafp->entries[0]; +} + +/* + * Cast typed pointers for "local" and "remote" name/value structs. + */ +static inline char * +xfs_attr3_leaf_name(xfs_attr_leafblock_t *leafp, int idx) +{ + struct xfs_attr_leaf_entry *entries = xfs_attr3_leaf_entryp(leafp); + + return &((char *)leafp)[be16_to_cpu(entries[idx].nameidx)]; +} + +static inline xfs_attr_leaf_name_remote_t * +xfs_attr3_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx) +{ + return (xfs_attr_leaf_name_remote_t *)xfs_attr3_leaf_name(leafp, idx); +} + +static inline xfs_attr_leaf_name_local_t * +xfs_attr3_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx) +{ + return (xfs_attr_leaf_name_local_t *)xfs_attr3_leaf_name(leafp, idx); +} + +/* + * Calculate total bytes used (including trailing pad for alignment) for + * a "local" name/value structure, a "remote" name/value structure, and + * a pointer which might be either. + */ +static inline int xfs_attr_leaf_entsize_remote(int nlen) +{ + return ((uint)sizeof(xfs_attr_leaf_name_remote_t) - 1 + (nlen) + \ + XFS_ATTR_LEAF_NAME_ALIGN - 1) & ~(XFS_ATTR_LEAF_NAME_ALIGN - 1); +} + +static inline int xfs_attr_leaf_entsize_local(int nlen, int vlen) +{ + return ((uint)sizeof(xfs_attr_leaf_name_local_t) - 1 + (nlen) + (vlen) + + XFS_ATTR_LEAF_NAME_ALIGN - 1) & ~(XFS_ATTR_LEAF_NAME_ALIGN - 1); +} + +static inline int xfs_attr_leaf_entsize_local_max(int bsize) +{ + return (((bsize) >> 1) + ((bsize) >> 2)); +} + + + +/* + * Remote attribute block format definition + * + * There is one of these headers per filesystem block in a remote attribute. + * This is done to ensure there is a 1:1 mapping between the attribute value + * length and the number of blocks needed to store the attribute. This makes the + * verification of a buffer a little more complex, but greatly simplifies the + * allocation, reading and writing of these attributes as we don't have to guess + * the number of blocks needed to store the attribute data. + */ +#define XFS_ATTR3_RMT_MAGIC 0x5841524d /* XARM */ + +struct xfs_attr3_rmt_hdr { + __be32 rm_magic; + __be32 rm_offset; + __be32 rm_bytes; + __be32 rm_crc; + uuid_t rm_uuid; + __be64 rm_owner; + __be64 rm_blkno; + __be64 rm_lsn; +}; + +#define XFS_ATTR3_RMT_CRC_OFF offsetof(struct xfs_attr3_rmt_hdr, rm_crc) + +#define XFS_ATTR3_RMT_BUF_SPACE(mp, bufsize) \ + ((bufsize) - (xfs_sb_version_hascrc(&(mp)->m_sb) ? \ + sizeof(struct xfs_attr3_rmt_hdr) : 0)) + +#endif /* __XFS_DA_FORMAT_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_dfrag.h xfsprogs-3.2.1ubuntu1/include/xfs_dfrag.h --- xfsprogs-3.1.9ubuntu2/include/xfs_dfrag.h 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_dfrag.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2000,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_DFRAG_H__ -#define __XFS_DFRAG_H__ - -/* - * Structure passed to xfs_swapext - */ - -typedef struct xfs_swapext -{ - __int64_t sx_version; /* version */ - __int64_t sx_fdtarget; /* fd of target file */ - __int64_t sx_fdtmp; /* fd of tmp file */ - xfs_off_t sx_offset; /* offset into file */ - xfs_off_t sx_length; /* leng from offset */ - char sx_pad[16]; /* pad space, unused */ - xfs_bstat_t sx_stat; /* stat of target b4 copy */ -} xfs_swapext_t; - -/* - * Version flag - */ -#define XFS_SX_VERSION 0 - -#ifdef __KERNEL__ -/* - * Prototypes for visible xfs_dfrag.c routines. - */ - -/* - * Syscall interface for xfs_swapext - */ -int xfs_swapext(struct xfs_swapext *sx); - -#endif /* __KERNEL__ */ - -#endif /* __XFS_DFRAG_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_dinode.h xfsprogs-3.2.1ubuntu1/include/xfs_dinode.h --- xfsprogs-3.1.9ubuntu2/include/xfs_dinode.h 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_dinode.h 2014-05-02 00:09:15.000000000 +0000 @@ -19,7 +19,7 @@ #define __XFS_DINODE_H__ #define XFS_DINODE_MAGIC 0x494e /* 'IN' */ -#define XFS_DINODE_GOOD_VERSION(v) (((v) == 1 || (v) == 2)) +#define XFS_DINODE_GOOD_VERSION(v) ((v) >= 1 && (v) <= 3) typedef struct xfs_timestamp { __be32 t_sec; /* timestamp seconds */ @@ -33,12 +33,15 @@ * variable size the leftover area split into a data and an attribute fork. * The format of the data and attribute fork depends on the format of the * inode as indicated by di_format and di_aformat. To access the data and - * attribute use the XFS_DFORK_PTR, XFS_DFORK_DPTR, and XFS_DFORK_PTR macros + * attribute use the XFS_DFORK_DPTR, XFS_DFORK_APTR, and XFS_DFORK_PTR macros * below. * * There is a very similar struct icdinode in xfs_inode which matches the * layout of the first 96 bytes of this structure, but is kept in native * format instead of big endian. + * + * Note: di_flushiter is only used by v1/2 inodes - it's effectively a zeroed + * padding field for v3 inodes. */ typedef struct xfs_dinode { __be16 di_magic; /* inode magic # = XFS_DINODE_MAGIC */ @@ -70,11 +73,38 @@ /* di_next_unlinked is the only non-core field in the old dinode */ __be32 di_next_unlinked;/* agi unlinked list ptr */ -} __attribute__((packed)) xfs_dinode_t; + + /* start of the extended dinode, writable fields */ + __le32 di_crc; /* CRC of the inode */ + __be64 di_changecount; /* number of attribute changes */ + __be64 di_lsn; /* flush sequence */ + __be64 di_flags2; /* more random flags */ + __u8 di_pad2[16]; /* more padding for future expansion */ + + /* fields only written to during inode creation */ + xfs_timestamp_t di_crtime; /* time created */ + __be64 di_ino; /* inode number */ + uuid_t di_uuid; /* UUID of the filesystem */ + + /* structure must be padded to 64 bit alignment */ +} xfs_dinode_t; + +#define XFS_DINODE_CRC_OFF offsetof(struct xfs_dinode, di_crc) #define DI_MAX_FLUSH 0xffff /* + * Size of the core inode on disk. Version 1 and 2 inodes have + * the same size, but version 3 has grown a few additional fields. + */ +static inline uint xfs_dinode_size(int version) +{ + if (version == 3) + return sizeof(struct xfs_dinode); + return offsetof(struct xfs_dinode, di_crc); +} + +/* * The 32 bit link count in the inode theoretically maxes out at UINT_MAX. * Since the pathconf interface is signed, we use 2^31 - 1 instead. * The old inode format had a 16 bit link count, so its maximum is USHRT_MAX. @@ -104,11 +134,8 @@ /* * Inode size for given fs. */ -#define XFS_LITINO(mp) \ - ((int)(((mp)->m_sb.sb_inodesize) - sizeof(struct xfs_dinode))) - -#define XFS_BROOT_SIZE_ADJ \ - (XFS_BTREE_LBLOCK_LEN - sizeof(xfs_bmdr_block_t)) +#define XFS_LITINO(mp, version) \ + ((int)(((mp)->m_sb.sb_inodesize) - xfs_dinode_size(version))) /* * Inode data & attribute fork sizes, per inode. @@ -119,10 +146,10 @@ #define XFS_DFORK_DSIZE(dip,mp) \ (XFS_DFORK_Q(dip) ? \ XFS_DFORK_BOFF(dip) : \ - XFS_LITINO(mp)) + XFS_LITINO(mp, (dip)->di_version)) #define XFS_DFORK_ASIZE(dip,mp) \ (XFS_DFORK_Q(dip) ? \ - XFS_LITINO(mp) - XFS_DFORK_BOFF(dip) : \ + XFS_LITINO(mp, (dip)->di_version) - XFS_DFORK_BOFF(dip) : \ 0) #define XFS_DFORK_SIZE(dip,mp,w) \ ((w) == XFS_DATA_FORK ? \ @@ -133,7 +160,7 @@ * Return pointers to the data or attribute forks. */ #define XFS_DFORK_DPTR(dip) \ - ((char *)(dip) + sizeof(struct xfs_dinode)) + ((char *)dip + xfs_dinode_size(dip->di_version)) #define XFS_DFORK_APTR(dip) \ (XFS_DFORK_DPTR(dip) + XFS_DFORK_BOFF(dip)) #define XFS_DFORK_PTR(dip,w) \ @@ -148,7 +175,7 @@ be32_to_cpu((dip)->di_nextents) : \ be16_to_cpu((dip)->di_anextents)) -#define XFS_BUF_TO_DINODE(bp) ((xfs_dinode_t *)XFS_BUF_PTR(bp)) +#define XFS_BUF_TO_DINODE(bp) ((xfs_dinode_t *)((bp)->b_addr)) /* * For block and character special files the 32bit dev_t is stored at the diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_dir2_block.h xfsprogs-3.2.1ubuntu1/include/xfs_dir2_block.h --- xfsprogs-3.1.9ubuntu2/include/xfs_dir2_block.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_dir2_block.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_DIR2_BLOCK_H__ -#define __XFS_DIR2_BLOCK_H__ - -/* - * xfs_dir2_block.h - * Directory version 2, single block format structures - */ - -struct uio; -struct xfs_dabuf; -struct xfs_da_args; -struct xfs_dir2_data_hdr; -struct xfs_dir2_leaf_entry; -struct xfs_inode; -struct xfs_mount; -struct xfs_trans; - -/* - * The single block format is as follows: - * xfs_dir2_data_hdr_t structure - * xfs_dir2_data_entry_t and xfs_dir2_data_unused_t structures - * xfs_dir2_leaf_entry_t structures - * xfs_dir2_block_tail_t structure - */ - -#define XFS_DIR2_BLOCK_MAGIC 0x58443242 /* XD2B: for one block dirs */ - -typedef struct xfs_dir2_block_tail { - __be32 count; /* count of leaf entries */ - __be32 stale; /* count of stale lf entries */ -} xfs_dir2_block_tail_t; - -/* - * Generic single-block structure, for xfs_db. - */ -typedef struct xfs_dir2_block { - xfs_dir2_data_hdr_t hdr; /* magic XFS_DIR2_BLOCK_MAGIC */ - xfs_dir2_data_union_t u[1]; - xfs_dir2_leaf_entry_t leaf[1]; - xfs_dir2_block_tail_t tail; -} xfs_dir2_block_t; - -/* - * Pointer to the leaf header embedded in a data block (1-block format) - */ -static inline xfs_dir2_block_tail_t * -xfs_dir2_block_tail_p(struct xfs_mount *mp, xfs_dir2_block_t *block) -{ - return (((xfs_dir2_block_tail_t *) - ((char *)(block) + (mp)->m_dirblksize)) - 1); -} - -/* - * Pointer to the leaf entries embedded in a data block (1-block format) - */ -static inline struct xfs_dir2_leaf_entry * -xfs_dir2_block_leaf_p(xfs_dir2_block_tail_t *btp) -{ - return ((struct xfs_dir2_leaf_entry *)btp) - be32_to_cpu(btp->count); -} - -/* - * Function declarations. - */ -extern int xfs_dir2_block_addname(struct xfs_da_args *args); -extern int xfs_dir2_block_getdents(struct xfs_inode *dp, void *dirent, - xfs_off_t *offset, filldir_t filldir); -extern int xfs_dir2_block_lookup(struct xfs_da_args *args); -extern int xfs_dir2_block_removename(struct xfs_da_args *args); -extern int xfs_dir2_block_replace(struct xfs_da_args *args); -extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args, - struct xfs_dabuf *lbp, struct xfs_dabuf *dbp); -extern int xfs_dir2_sf_to_block(struct xfs_da_args *args); - -#endif /* __XFS_DIR2_BLOCK_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_dir2_data.h xfsprogs-3.2.1ubuntu1/include/xfs_dir2_data.h --- xfsprogs-3.1.9ubuntu2/include/xfs_dir2_data.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_dir2_data.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2000,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_DIR2_DATA_H__ -#define __XFS_DIR2_DATA_H__ - -/* - * Directory format 2, data block structures. - */ - -struct xfs_dabuf; -struct xfs_da_args; -struct xfs_inode; -struct xfs_trans; - -/* - * Constants. - */ -#define XFS_DIR2_DATA_MAGIC 0x58443244 /* XD2D: for multiblock dirs */ -#define XFS_DIR2_DATA_ALIGN_LOG 3 /* i.e., 8 bytes */ -#define XFS_DIR2_DATA_ALIGN (1 << XFS_DIR2_DATA_ALIGN_LOG) -#define XFS_DIR2_DATA_FREE_TAG 0xffff -#define XFS_DIR2_DATA_FD_COUNT 3 - -/* - * Directory address space divided into sections, - * spaces separated by 32GB. - */ -#define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG)) -#define XFS_DIR2_DATA_SPACE 0 -#define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE) -#define XFS_DIR2_DATA_FIRSTDB(mp) \ - xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET) - -/* - * Offsets of . and .. in data space (always block 0) - */ -#define XFS_DIR2_DATA_DOT_OFFSET \ - ((xfs_dir2_data_aoff_t)sizeof(xfs_dir2_data_hdr_t)) -#define XFS_DIR2_DATA_DOTDOT_OFFSET \ - (XFS_DIR2_DATA_DOT_OFFSET + xfs_dir2_data_entsize(1)) -#define XFS_DIR2_DATA_FIRST_OFFSET \ - (XFS_DIR2_DATA_DOTDOT_OFFSET + xfs_dir2_data_entsize(2)) - -/* - * Structures. - */ - -/* - * Describe a free area in the data block. - * The freespace will be formatted as a xfs_dir2_data_unused_t. - */ -typedef struct xfs_dir2_data_free { - __be16 offset; /* start of freespace */ - __be16 length; /* length of freespace */ -} xfs_dir2_data_free_t; - -/* - * Header for the data blocks. - * Always at the beginning of a directory-sized block. - * The code knows that XFS_DIR2_DATA_FD_COUNT is 3. - */ -typedef struct xfs_dir2_data_hdr { - __be32 magic; /* XFS_DIR2_DATA_MAGIC */ - /* or XFS_DIR2_BLOCK_MAGIC */ - xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT]; -} xfs_dir2_data_hdr_t; - -/* - * Active entry in a data block. Aligned to 8 bytes. - * Tag appears as the last 2 bytes. - */ -typedef struct xfs_dir2_data_entry { - __be64 inumber; /* inode number */ - __u8 namelen; /* name length */ - __u8 name[1]; /* name bytes, no null */ - /* variable offset */ - __be16 tag; /* starting offset of us */ -} xfs_dir2_data_entry_t; - -/* - * Unused entry in a data block. Aligned to 8 bytes. - * Tag appears as the last 2 bytes. - */ -typedef struct xfs_dir2_data_unused { - __be16 freetag; /* XFS_DIR2_DATA_FREE_TAG */ - __be16 length; /* total free length */ - /* variable offset */ - __be16 tag; /* starting offset of us */ -} xfs_dir2_data_unused_t; - -typedef union { - xfs_dir2_data_entry_t entry; - xfs_dir2_data_unused_t unused; -} xfs_dir2_data_union_t; - -/* - * Generic data block structure, for xfs_db. - */ -typedef struct xfs_dir2_data { - xfs_dir2_data_hdr_t hdr; /* magic XFS_DIR2_DATA_MAGIC */ - xfs_dir2_data_union_t u[1]; -} xfs_dir2_data_t; - -/* - * Macros. - */ - -/* - * Size of a data entry. - */ -static inline int xfs_dir2_data_entsize(int n) -{ - return (int)roundup(offsetof(xfs_dir2_data_entry_t, name[0]) + (n) + \ - (uint)sizeof(xfs_dir2_data_off_t), XFS_DIR2_DATA_ALIGN); -} - -/* - * Pointer to an entry's tag word. - */ -static inline __be16 * -xfs_dir2_data_entry_tag_p(xfs_dir2_data_entry_t *dep) -{ - return (__be16 *)((char *)dep + - xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16)); -} - -/* - * Pointer to a freespace's tag word. - */ -static inline __be16 * -xfs_dir2_data_unused_tag_p(xfs_dir2_data_unused_t *dup) -{ - return (__be16 *)((char *)dup + - be16_to_cpu(dup->length) - sizeof(__be16)); -} - -/* - * Function declarations. - */ -#ifdef DEBUG -extern void xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_dabuf *bp); -#else -#define xfs_dir2_data_check(dp,bp) -#endif -extern xfs_dir2_data_free_t *xfs_dir2_data_freefind(xfs_dir2_data_t *d, - xfs_dir2_data_unused_t *dup); -extern xfs_dir2_data_free_t *xfs_dir2_data_freeinsert(xfs_dir2_data_t *d, - xfs_dir2_data_unused_t *dup, int *loghead); -extern void xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d, - int *loghead); -extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno, - struct xfs_dabuf **bpp); -extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp, - xfs_dir2_data_entry_t *dep); -extern void xfs_dir2_data_log_header(struct xfs_trans *tp, - struct xfs_dabuf *bp); -extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_dabuf *bp, - xfs_dir2_data_unused_t *dup); -extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_dabuf *bp, - xfs_dir2_data_aoff_t offset, - xfs_dir2_data_aoff_t len, int *needlogp, - int *needscanp); -extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_dabuf *bp, - xfs_dir2_data_unused_t *dup, - xfs_dir2_data_aoff_t offset, - xfs_dir2_data_aoff_t len, int *needlogp, - int *needscanp); - -#endif /* __XFS_DIR2_DATA_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_dir2.h xfsprogs-3.2.1ubuntu1/include/xfs_dir2.h --- xfsprogs-3.1.9ubuntu2/include/xfs_dir2.h 2011-10-21 22:46:08.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_dir2.h 2014-05-02 00:09:15.000000000 +0000 @@ -16,48 +16,18 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_DIR2_H__ -#define __XFS_DIR2_H__ +#define __XFS_DIR2_H__ -struct uio; -struct xfs_dabuf; -struct xfs_da_args; -struct xfs_dir2_put_args; struct xfs_bmap_free; +struct xfs_da_args; struct xfs_inode; struct xfs_mount; struct xfs_trans; - -/* - * Directory version 2. - * There are 4 possible formats: - * shortform - * single block - data with embedded leaf at the end - * multiple data blocks, single leaf+freeindex block - * data blocks, node&leaf blocks (btree), freeindex blocks - * - * The shortform format is in xfs_dir2_sf.h. - * The single block format is in xfs_dir2_block.h. - * The data block format is in xfs_dir2_data.h. - * The leaf and freeindex block formats are in xfs_dir2_leaf.h. - * Node blocks are the same as the other version, in xfs_da_btree.h. - */ - -/* - * Byte offset in data block and shortform entry. - */ -typedef __uint16_t xfs_dir2_data_off_t; -#define NULLDATAOFF 0xffffU -typedef uint xfs_dir2_data_aoff_t; /* argument form */ - -/* - * Directory block number (logical dirblk in file) - */ -typedef __uint32_t xfs_dir2_db_t; - -/* - * Byte offset in a directory. - */ -typedef xfs_off_t xfs_dir2_off_t; +struct xfs_dir2_sf_hdr; +struct xfs_dir2_sf_entry; +struct xfs_dir2_data_hdr; +struct xfs_dir2_data_entry; +struct xfs_dir2_data_unused; extern struct xfs_name xfs_name_dotdot; @@ -86,21 +56,54 @@ struct xfs_bmap_free *flist, xfs_extlen_t tot); extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name, uint resblks); -extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino); + +#define S_SHIFT 12 +extern const unsigned char xfs_mode_to_ftype[]; /* - * Utility routines for v2 directories. + * Direct call from the bmap code, bypassing the generic directory layer. */ -extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, - xfs_dir2_db_t *dbp); -extern int xfs_dir2_isblock(struct xfs_trans *tp, struct xfs_inode *dp, - int *vp); -extern int xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp, - int *vp); +extern int xfs_dir2_sf_to_block(struct xfs_da_args *args); + +/* + * Interface routines used by userspace utilities + */ +extern xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *sfp); +extern void xfs_dir2_sf_put_parent_ino(struct xfs_dir2_sf_hdr *sfp, + xfs_ino_t ino); +extern xfs_ino_t xfs_dir3_sfe_get_ino(struct xfs_mount *mp, + struct xfs_dir2_sf_hdr *sfp, struct xfs_dir2_sf_entry *sfep); +extern void xfs_dir3_sfe_put_ino(struct xfs_mount *mp, + struct xfs_dir2_sf_hdr *hdr, struct xfs_dir2_sf_entry *sfep, + xfs_ino_t ino); + +extern int xfs_dir2_isblock(struct xfs_trans *tp, struct xfs_inode *dp, int *r); +extern int xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp, int *r); extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, - struct xfs_dabuf *bp); + struct xfs_buf *bp); -extern int xfs_dir_cilookup_result(struct xfs_da_args *args, - const unsigned char *name, int len); +extern void xfs_dir2_data_freescan(struct xfs_mount *mp, + struct xfs_dir2_data_hdr *hdr, int *loghead); +extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_buf *bp, + struct xfs_dir2_data_entry *dep); +extern void xfs_dir2_data_log_header(struct xfs_trans *tp, + struct xfs_buf *bp); +extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_buf *bp, + struct xfs_dir2_data_unused *dup); +extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_buf *bp, + xfs_dir2_data_aoff_t offset, xfs_dir2_data_aoff_t len, + int *needlogp, int *needscanp); +extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_buf *bp, + struct xfs_dir2_data_unused *dup, xfs_dir2_data_aoff_t offset, + xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp); + +extern struct xfs_dir2_data_free *xfs_dir2_data_freefind( + struct xfs_dir2_data_hdr *hdr, struct xfs_dir2_data_unused *dup); + +extern const struct xfs_buf_ops xfs_dir3_block_buf_ops; +extern const struct xfs_buf_ops xfs_dir3_leafn_buf_ops; +extern const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops; +extern const struct xfs_buf_ops xfs_dir3_free_buf_ops; +extern const struct xfs_buf_ops xfs_dir3_data_buf_ops; #endif /* __XFS_DIR2_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_dir2_leaf.h xfsprogs-3.2.1ubuntu1/include/xfs_dir2_leaf.h --- xfsprogs-3.1.9ubuntu2/include/xfs_dir2_leaf.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_dir2_leaf.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,253 +0,0 @@ -/* - * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_DIR2_LEAF_H__ -#define __XFS_DIR2_LEAF_H__ - -struct uio; -struct xfs_dabuf; -struct xfs_da_args; -struct xfs_inode; -struct xfs_mount; -struct xfs_trans; - -/* - * Offset of the leaf/node space. First block in this space - * is the btree root. - */ -#define XFS_DIR2_LEAF_SPACE 1 -#define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE) -#define XFS_DIR2_LEAF_FIRSTDB(mp) \ - xfs_dir2_byte_to_db(mp, XFS_DIR2_LEAF_OFFSET) - -/* - * Offset in data space of a data entry. - */ -typedef __uint32_t xfs_dir2_dataptr_t; -#define XFS_DIR2_MAX_DATAPTR ((xfs_dir2_dataptr_t)0xffffffff) -#define XFS_DIR2_NULL_DATAPTR ((xfs_dir2_dataptr_t)0) - -/* - * Leaf block header. - */ -typedef struct xfs_dir2_leaf_hdr { - xfs_da_blkinfo_t info; /* header for da routines */ - __be16 count; /* count of entries */ - __be16 stale; /* count of stale entries */ -} xfs_dir2_leaf_hdr_t; - -/* - * Leaf block entry. - */ -typedef struct xfs_dir2_leaf_entry { - __be32 hashval; /* hash value of name */ - __be32 address; /* address of data entry */ -} xfs_dir2_leaf_entry_t; - -/* - * Leaf block tail. - */ -typedef struct xfs_dir2_leaf_tail { - __be32 bestcount; -} xfs_dir2_leaf_tail_t; - -/* - * Leaf block. - * bests and tail are at the end of the block for single-leaf only - * (magic = XFS_DIR2_LEAF1_MAGIC not XFS_DIR2_LEAFN_MAGIC). - */ -typedef struct xfs_dir2_leaf { - xfs_dir2_leaf_hdr_t hdr; /* leaf header */ - xfs_dir2_leaf_entry_t ents[1]; /* entries */ - /* ... */ - xfs_dir2_data_off_t bests[1]; /* best free counts */ - xfs_dir2_leaf_tail_t tail; /* leaf tail */ -} xfs_dir2_leaf_t; - -/* - * DB blocks here are logical directory block numbers, not filesystem blocks. - */ - -static inline int xfs_dir2_max_leaf_ents(struct xfs_mount *mp) -{ - return (int)(((mp)->m_dirblksize - (uint)sizeof(xfs_dir2_leaf_hdr_t)) / - (uint)sizeof(xfs_dir2_leaf_entry_t)); -} - -/* - * Get address of the bestcount field in the single-leaf block. - */ -static inline xfs_dir2_leaf_tail_t * -xfs_dir2_leaf_tail_p(struct xfs_mount *mp, xfs_dir2_leaf_t *lp) -{ - return (xfs_dir2_leaf_tail_t *) - ((char *)(lp) + (mp)->m_dirblksize - - (uint)sizeof(xfs_dir2_leaf_tail_t)); -} - -/* - * Get address of the bests array in the single-leaf block. - */ -static inline __be16 * -xfs_dir2_leaf_bests_p(xfs_dir2_leaf_tail_t *ltp) -{ - return (__be16 *)ltp - be32_to_cpu(ltp->bestcount); -} - -/* - * Convert dataptr to byte in file space - */ -static inline xfs_dir2_off_t -xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) -{ - return (xfs_dir2_off_t)(dp) << XFS_DIR2_DATA_ALIGN_LOG; -} - -/* - * Convert byte in file space to dataptr. It had better be aligned. - */ -static inline xfs_dir2_dataptr_t -xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by) -{ - return (xfs_dir2_dataptr_t)((by) >> XFS_DIR2_DATA_ALIGN_LOG); -} - -/* - * Convert byte in space to (DB) block - */ -static inline xfs_dir2_db_t -xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by) -{ - return (xfs_dir2_db_t)((by) >> \ - ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog)); -} - -/* - * Convert dataptr to a block number - */ -static inline xfs_dir2_db_t -xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) -{ - return xfs_dir2_byte_to_db(mp, xfs_dir2_dataptr_to_byte(mp, dp)); -} - -/* - * Convert byte in space to offset in a block - */ -static inline xfs_dir2_data_aoff_t -xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by) -{ - return (xfs_dir2_data_aoff_t)((by) & \ - ((1 << ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog)) - 1)); -} - -/* - * Convert dataptr to a byte offset in a block - */ -static inline xfs_dir2_data_aoff_t -xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) -{ - return xfs_dir2_byte_to_off(mp, xfs_dir2_dataptr_to_byte(mp, dp)); -} - -/* - * Convert block and offset to byte in space - */ -static inline xfs_dir2_off_t -xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db, - xfs_dir2_data_aoff_t o) -{ - return ((xfs_dir2_off_t)(db) << \ - ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog)) + (o); -} - -/* - * Convert block (DB) to block (dablk) - */ -static inline xfs_dablk_t -xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db) -{ - return (xfs_dablk_t)((db) << (mp)->m_sb.sb_dirblklog); -} - -/* - * Convert byte in space to (DA) block - */ -static inline xfs_dablk_t -xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by) -{ - return xfs_dir2_db_to_da(mp, xfs_dir2_byte_to_db(mp, by)); -} - -/* - * Convert block and offset to dataptr - */ -static inline xfs_dir2_dataptr_t -xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db, - xfs_dir2_data_aoff_t o) -{ - return xfs_dir2_byte_to_dataptr(mp, xfs_dir2_db_off_to_byte(mp, db, o)); -} - -/* - * Convert block (dablk) to block (DB) - */ -static inline xfs_dir2_db_t -xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da) -{ - return (xfs_dir2_db_t)((da) >> (mp)->m_sb.sb_dirblklog); -} - -/* - * Convert block (dablk) to byte offset in space - */ -static inline xfs_dir2_off_t -xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da) -{ - return xfs_dir2_db_off_to_byte(mp, xfs_dir2_da_to_db(mp, da), 0); -} - -/* - * Function declarations. - */ -extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args, - struct xfs_dabuf *dbp); -extern int xfs_dir2_leaf_addname(struct xfs_da_args *args); -extern void xfs_dir2_leaf_compact(struct xfs_da_args *args, - struct xfs_dabuf *bp); -extern void xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp, - int *lowstalep, int *highstalep, - int *lowlogp, int *highlogp); -extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent, - size_t bufsize, xfs_off_t *offset, - filldir_t filldir); -extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno, - struct xfs_dabuf **bpp, int magic); -extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp, - int first, int last); -extern void xfs_dir2_leaf_log_header(struct xfs_trans *tp, - struct xfs_dabuf *bp); -extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args); -extern int xfs_dir2_leaf_removename(struct xfs_da_args *args); -extern int xfs_dir2_leaf_replace(struct xfs_da_args *args); -extern int xfs_dir2_leaf_search_hash(struct xfs_da_args *args, - struct xfs_dabuf *lbp); -extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args, - struct xfs_dabuf *lbp, xfs_dir2_db_t db); -extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state); - -#endif /* __XFS_DIR2_LEAF_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_dir2_node.h xfsprogs-3.2.1ubuntu1/include/xfs_dir2_node.h --- xfsprogs-3.1.9ubuntu2/include/xfs_dir2_node.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_dir2_node.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2000,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_DIR2_NODE_H__ -#define __XFS_DIR2_NODE_H__ - -/* - * Directory version 2, btree node format structures - */ - -struct uio; -struct xfs_dabuf; -struct xfs_da_args; -struct xfs_da_state; -struct xfs_da_state_blk; -struct xfs_inode; -struct xfs_trans; - -/* - * Offset of the freespace index. - */ -#define XFS_DIR2_FREE_SPACE 2 -#define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE) -#define XFS_DIR2_FREE_FIRSTDB(mp) \ - xfs_dir2_byte_to_db(mp, XFS_DIR2_FREE_OFFSET) - -#define XFS_DIR2_FREE_MAGIC 0x58443246 /* XD2F */ - -typedef struct xfs_dir2_free_hdr { - __be32 magic; /* XFS_DIR2_FREE_MAGIC */ - __be32 firstdb; /* db of first entry */ - __be32 nvalid; /* count of valid entries */ - __be32 nused; /* count of used entries */ -} xfs_dir2_free_hdr_t; - -typedef struct xfs_dir2_free { - xfs_dir2_free_hdr_t hdr; /* block header */ - __be16 bests[1]; /* best free counts */ - /* unused entries are -1 */ -} xfs_dir2_free_t; - -#define XFS_DIR2_MAX_FREE_BESTS(mp) \ - (((mp)->m_dirblksize - (uint)sizeof(xfs_dir2_free_hdr_t)) / \ - (uint)sizeof(xfs_dir2_data_off_t)) - -/* - * Convert data space db to the corresponding free db. - */ -static inline xfs_dir2_db_t -xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db) -{ - return (XFS_DIR2_FREE_FIRSTDB(mp) + (db) / XFS_DIR2_MAX_FREE_BESTS(mp)); -} - -/* - * Convert data space db to the corresponding index in a free db. - */ -static inline int -xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db) -{ - return ((db) % XFS_DIR2_MAX_FREE_BESTS(mp)); -} - -extern int xfs_dir2_leaf_to_node(struct xfs_da_args *args, - struct xfs_dabuf *lbp); -extern xfs_dahash_t xfs_dir2_leafn_lasthash(struct xfs_dabuf *bp, int *count); -extern int xfs_dir2_leafn_lookup_int(struct xfs_dabuf *bp, - struct xfs_da_args *args, int *indexp, - struct xfs_da_state *state); -extern int xfs_dir2_leafn_order(struct xfs_dabuf *leaf1_bp, - struct xfs_dabuf *leaf2_bp); -extern int xfs_dir2_leafn_split(struct xfs_da_state *state, - struct xfs_da_state_blk *oldblk, - struct xfs_da_state_blk *newblk); -extern int xfs_dir2_leafn_toosmall(struct xfs_da_state *state, int *action); -extern void xfs_dir2_leafn_unbalance(struct xfs_da_state *state, - struct xfs_da_state_blk *drop_blk, - struct xfs_da_state_blk *save_blk); -extern int xfs_dir2_node_addname(struct xfs_da_args *args); -extern int xfs_dir2_node_lookup(struct xfs_da_args *args); -extern int xfs_dir2_node_removename(struct xfs_da_args *args); -extern int xfs_dir2_node_replace(struct xfs_da_args *args); -extern int xfs_dir2_node_trim_free(struct xfs_da_args *args, xfs_fileoff_t fo, - int *rvalp); - -#endif /* __XFS_DIR2_NODE_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_dir2_sf.h xfsprogs-3.2.1ubuntu1/include/xfs_dir2_sf.h --- xfsprogs-3.1.9ubuntu2/include/xfs_dir2_sf.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_dir2_sf.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_DIR2_SF_H__ -#define __XFS_DIR2_SF_H__ - -/* - * Directory layout when stored internal to an inode. - * - * Small directories are packed as tightly as possible so as to - * fit into the literal area of the inode. - */ - -struct uio; -struct xfs_dabuf; -struct xfs_da_args; -struct xfs_dir2_block; -struct xfs_inode; -struct xfs_mount; -struct xfs_trans; - -/* - * Inode number stored as 8 8-bit values. - */ -typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t; - -/* - * Inode number stored as 4 8-bit values. - * Works a lot of the time, when all the inode numbers in a directory - * fit in 32 bits. - */ -typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t; - -typedef union { - xfs_dir2_ino8_t i8; - xfs_dir2_ino4_t i4; -} xfs_dir2_inou_t; -#define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL) - -/* - * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t. - * Only need 16 bits, this is the byte offset into the single block form. - */ -typedef struct { __uint8_t i[2]; } __arch_pack xfs_dir2_sf_off_t; - -/* - * The parent directory has a dedicated field, and the self-pointer must - * be calculated on the fly. - * - * Entries are packed toward the top as tightly as possible. The header - * and the elements must be memcpy'd out into a work area to get correct - * alignment for the inode number fields. - */ -typedef struct xfs_dir2_sf_hdr { - __uint8_t count; /* count of entries */ - __uint8_t i8count; /* count of 8-byte inode #s */ - xfs_dir2_inou_t parent; /* parent dir inode number */ -} __arch_pack xfs_dir2_sf_hdr_t; - -typedef struct xfs_dir2_sf_entry { - __uint8_t namelen; /* actual name length */ - xfs_dir2_sf_off_t offset; /* saved offset */ - __uint8_t name[1]; /* name, variable size */ - xfs_dir2_inou_t inumber; /* inode number, var. offset */ -} __arch_pack xfs_dir2_sf_entry_t; - -typedef struct xfs_dir2_sf { - xfs_dir2_sf_hdr_t hdr; /* shortform header */ - xfs_dir2_sf_entry_t list[1]; /* shortform entries */ -} xfs_dir2_sf_t; - -static inline int xfs_dir2_sf_hdr_size(int i8count) -{ - return ((uint)sizeof(xfs_dir2_sf_hdr_t) - \ - ((i8count) == 0) * \ - ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); -} - -static inline xfs_dir2_inou_t *xfs_dir2_sf_inumberp(xfs_dir2_sf_entry_t *sfep) -{ - return (xfs_dir2_inou_t *)&(sfep)->name[(sfep)->namelen]; -} - -static inline xfs_intino_t -xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from) -{ - return ((sfp)->hdr.i8count == 0 ? \ - (xfs_intino_t)XFS_GET_DIR_INO4((from)->i4) : \ - (xfs_intino_t)XFS_GET_DIR_INO8((from)->i8)); -} - -static inline void xfs_dir2_sf_put_inumber(xfs_dir2_sf_t *sfp, xfs_ino_t *from, - xfs_dir2_inou_t *to) -{ - if ((sfp)->hdr.i8count == 0) - XFS_PUT_DIR_INO4(*(from), (to)->i4); - else - XFS_PUT_DIR_INO8(*(from), (to)->i8); -} - -static inline xfs_dir2_data_aoff_t -xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep) -{ - return INT_GET_UNALIGNED_16_BE(&(sfep)->offset.i); -} - -static inline void -xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off) -{ - INT_SET_UNALIGNED_16_BE(&(sfep)->offset.i, off); -} - -static inline int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_t *sfp, int len) -{ - return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (len) - \ - ((sfp)->hdr.i8count == 0) * \ - ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); -} - -static inline int -xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) -{ - return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (sfep)->namelen - \ - ((sfp)->hdr.i8count == 0) * \ - ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); -} - -static inline xfs_dir2_sf_entry_t *xfs_dir2_sf_firstentry(xfs_dir2_sf_t *sfp) -{ - return ((xfs_dir2_sf_entry_t *) \ - ((char *)(sfp) + xfs_dir2_sf_hdr_size(sfp->hdr.i8count))); -} - -static inline xfs_dir2_sf_entry_t * -xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) -{ - return ((xfs_dir2_sf_entry_t *) \ - ((char *)(sfep) + xfs_dir2_sf_entsize_byentry(sfp,sfep))); -} - -/* - * Functions. - */ -extern int xfs_dir2_block_sfsize(struct xfs_inode *dp, - struct xfs_dir2_block *block, - xfs_dir2_sf_hdr_t *sfhp); -extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp, - int size, xfs_dir2_sf_hdr_t *sfhp); -extern int xfs_dir2_sf_addname(struct xfs_da_args *args); -extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino); -extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, void *dirent, - xfs_off_t *offset, filldir_t filldir); -extern int xfs_dir2_sf_lookup(struct xfs_da_args *args); -extern int xfs_dir2_sf_removename(struct xfs_da_args *args); -extern int xfs_dir2_sf_replace(struct xfs_da_args *args); - -#endif /* __XFS_DIR2_SF_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_dir_leaf.h xfsprogs-3.2.1ubuntu1/include/xfs_dir_leaf.h --- xfsprogs-3.1.9ubuntu2/include/xfs_dir_leaf.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_dir_leaf.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_DIR_LEAF_H__ -#define __XFS_DIR_LEAF_H__ - -/* - * Version 1 Directory layout, internal structure, access macros, etc. - * to allow various xfsprogs tools to read these structures. - * - * Large directories are structured around Btrees where all the data - * elements are in the leaf nodes. Filenames are hashed into an int, - * then that int is used as the index into the Btree. Since the hashval - * of a filename may not be unique, we may have duplicate keys. The - * internal links in the Btree are logical block offsets into the file. - */ - -/*======================================================================== - * Directory Structure when equal to XFS_LBSIZE(mp) bytes. - *========================================================================*/ - -/* - * This is the structure of the leaf nodes in the Btree. - * - * Struct leaf_entry's are packed from the top. Names grow from the bottom - * but are not packed. The freemap contains run-length-encoded entries - * for the free bytes after the leaf_entry's, but only the N largest such, - * smaller runs are dropped. When the freemap doesn't show enough space - * for an allocation, we compact the namelist area and try again. If we - * still don't have enough space, then we have to split the block. - * - * Since we have duplicate hash keys, for each key that matches, compare - * the actual string. The root and intermediate node search always takes - * the first-in-the-block key match found, so we should only have to work - * "forw"ard. If none matches, continue with the "forw"ard leaf nodes - * until the hash key changes or the filename is found. - * - * The parent directory and the self-pointer are explicitly represented - * (ie: there are entries for "." and ".."). - * - * Note that the count being a __uint16_t limits us to something like a - * blocksize of 1.3MB in the face of worst case (short) filenames. - */ - -#define XFS_DIR_LEAF_MAGIC 0xfeeb - -#define XFS_DIR_LEAF_MAPSIZE 3 /* how many freespace slots */ - - -typedef struct xfs_dir_leaf_map { /* RLE map of free bytes */ - __be16 base; /* base of free region */ - __be16 size; /* run length of free region */ -} xfs_dir_leaf_map_t; - -typedef struct xfs_dir_leaf_hdr { /* constant-structure header block */ - xfs_da_blkinfo_t info; /* block type, links, etc. */ - __be16 count; /* count of active leaf_entry's */ - __be16 namebytes; /* num bytes of name strings stored */ - __be16 firstused; /* first used byte in name area */ - __u8 holes; /* != 0 if blk needs compaction */ - __u8 pad1; - xfs_dir_leaf_map_t freemap[XFS_DIR_LEAF_MAPSIZE]; -} xfs_dir_leaf_hdr_t; - -typedef struct xfs_dir_leaf_entry { /* sorted on key, not name */ - __be32 hashval; /* hash value of name */ - __be16 nameidx; /* index into buffer of name */ - __u8 namelen; /* length of name string */ - __u8 pad2; -} xfs_dir_leaf_entry_t; - -typedef struct xfs_dir_leaf_name { - xfs_dir_ino_t inumber; /* inode number for this key */ - __u8 name[1]; /* name string itself */ -} xfs_dir_leaf_name_t; - -typedef struct xfs_dir_leafblock { - xfs_dir_leaf_hdr_t hdr; /* constant-structure header block */ - xfs_dir_leaf_entry_t entries[1]; /* var sized array */ - xfs_dir_leaf_name_t namelist[1]; /* grows from bottom of buf */ -} xfs_dir_leafblock_t; - -static inline int xfs_dir_leaf_entsize_byname(int len) -{ - return (uint)sizeof(xfs_dir_leaf_name_t)-1 + len; -} - -static inline int xfs_dir_leaf_entsize_byentry(xfs_dir_leaf_entry_t *entry) -{ - return (uint)sizeof(xfs_dir_leaf_name_t)-1 + (entry)->namelen; -} - -static inline xfs_dir_leaf_name_t * -xfs_dir_leaf_namestruct(xfs_dir_leafblock_t *leafp, int offset) -{ - return (xfs_dir_leaf_name_t *)&((char *)(leafp))[offset]; -} - -#endif /* __XFS_DIR_LEAF_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_dir_sf.h xfsprogs-3.2.1ubuntu1/include/xfs_dir_sf.h --- xfsprogs-3.1.9ubuntu2/include/xfs_dir_sf.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_dir_sf.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2000,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_DIR_SF_H__ -#define __XFS_DIR_SF_H__ - -/* - * Directory layout when stored internal to an inode. - * - * Small directories are packed as tightly as possible so as to - * fit into the literal area of the inode. - */ - -typedef struct { __uint8_t i[sizeof(xfs_ino_t)]; } xfs_dir_ino_t; - -/* - * The parent directory has a dedicated field, and the self-pointer must - * be calculated on the fly. - * - * Entries are packed toward the top as tight as possible. The header - * and the elements much be memcpy'd out into a work area to get correct - * alignment for the inode number fields. - */ -typedef struct xfs_dir_sf_hdr { /* constant-structure header block */ - xfs_dir_ino_t parent; /* parent dir inode number */ - __u8 count; /* count of active entries */ -} xfs_dir_sf_hdr_t; - -typedef struct xfs_dir_sf_entry { - xfs_dir_ino_t inumber; /* referenced inode number */ - __u8 namelen; /* actual length of name (no NULL) */ - __u8 name[1]; /* name */ -} xfs_dir_sf_entry_t; - -typedef struct xfs_dir_shortform { - xfs_dir_sf_hdr_t hdr; - xfs_dir_sf_entry_t list[1]; /* variable sized array */ -} xfs_dir_shortform_t; - -/* - * We generate this then sort it, so that readdirs are returned in - * hash-order. Else seekdir won't work. - */ -typedef struct xfs_dir_sf_sort { - __u8 entno; /* .=0, ..=1, else entry# + 2 */ - __u8 seqno; /* sequence # with same hash value */ - __u8 namelen; /* length of name value (no null) */ - __be32 hash; /* this entry's hash value */ - xfs_intino_t ino; /* this entry's inode number */ - __u8 *name; /* name value, pointer into buffer */ -} xfs_dir_sf_sort_t; - -static inline void xfs_dir_sf_get_dirino(xfs_dir_ino_t *from, xfs_ino_t *to) -{ - *to = XFS_GET_DIR_INO8(*from); -} - -static inline void xfs_dir_sf_put_dirino(xfs_ino_t *from, xfs_dir_ino_t *to) -{ - XFS_PUT_DIR_INO8(*from, *to); -} - -static inline int xfs_dir_sf_entsize_byname(int len) -{ - return sizeof(xfs_dir_sf_entry_t) - 1 + len; -} - -static inline int xfs_dir_sf_entsize_byentry(xfs_dir_sf_entry_t *sfep) -{ - return sizeof(xfs_dir_sf_entry_t) - 1 + sfep->namelen; -} - -static inline xfs_dir_sf_entry_t *xfs_dir_sf_nextentry(xfs_dir_sf_entry_t *sfep) -{ - return (xfs_dir_sf_entry_t *)((char *)sfep + - xfs_dir_sf_entsize_byentry(sfep)); -} - -static inline int xfs_dir_sf_allfit(int count, int totallen) -{ - return sizeof(xfs_dir_sf_hdr_t) + - (sizeof(xfs_dir_sf_entry_t) - 1) * count + totallen; -} - -#endif /* __XFS_DIR_SF_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_extfree_item.h xfsprogs-3.2.1ubuntu1/include/xfs_extfree_item.h --- xfsprogs-3.1.9ubuntu2/include/xfs_extfree_item.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_extfree_item.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2000,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_EXTFREE_ITEM_H__ -#define __XFS_EXTFREE_ITEM_H__ - -struct xfs_mount; -struct kmem_zone; - -typedef struct xfs_extent { - xfs_dfsbno_t ext_start; - xfs_extlen_t ext_len; -} xfs_extent_t; - -/* - * Since an xfs_extent_t has types (start:64, len: 32) - * there are different alignments on 32 bit and 64 bit kernels. - * So we provide the different variants for use by a - * conversion routine. - */ - -typedef struct xfs_extent_32 { - __uint64_t ext_start; - __uint32_t ext_len; -} __attribute__((packed)) xfs_extent_32_t; - -typedef struct xfs_extent_64 { - __uint64_t ext_start; - __uint32_t ext_len; - __uint32_t ext_pad; -} xfs_extent_64_t; - -/* - * This is the structure used to lay out an efi log item in the - * log. The efi_extents field is a variable size array whose - * size is given by efi_nextents. - */ -typedef struct xfs_efi_log_format { - __uint16_t efi_type; /* efi log item type */ - __uint16_t efi_size; /* size of this item */ - __uint32_t efi_nextents; /* # extents to free */ - __uint64_t efi_id; /* efi identifier */ - xfs_extent_t efi_extents[1]; /* array of extents to free */ -} xfs_efi_log_format_t; - -typedef struct xfs_efi_log_format_32 { - __uint16_t efi_type; /* efi log item type */ - __uint16_t efi_size; /* size of this item */ - __uint32_t efi_nextents; /* # extents to free */ - __uint64_t efi_id; /* efi identifier */ - xfs_extent_32_t efi_extents[1]; /* array of extents to free */ -} __attribute__((packed)) xfs_efi_log_format_32_t; - -typedef struct xfs_efi_log_format_64 { - __uint16_t efi_type; /* efi log item type */ - __uint16_t efi_size; /* size of this item */ - __uint32_t efi_nextents; /* # extents to free */ - __uint64_t efi_id; /* efi identifier */ - xfs_extent_64_t efi_extents[1]; /* array of extents to free */ -} xfs_efi_log_format_64_t; - -/* - * This is the structure used to lay out an efd log item in the - * log. The efd_extents array is a variable size array whose - * size is given by efd_nextents; - */ -typedef struct xfs_efd_log_format { - __uint16_t efd_type; /* efd log item type */ - __uint16_t efd_size; /* size of this item */ - __uint32_t efd_nextents; /* # of extents freed */ - __uint64_t efd_efi_id; /* id of corresponding efi */ - xfs_extent_t efd_extents[1]; /* array of extents freed */ -} xfs_efd_log_format_t; - -typedef struct xfs_efd_log_format_32 { - __uint16_t efd_type; /* efd log item type */ - __uint16_t efd_size; /* size of this item */ - __uint32_t efd_nextents; /* # of extents freed */ - __uint64_t efd_efi_id; /* id of corresponding efi */ - xfs_extent_32_t efd_extents[1]; /* array of extents freed */ -} __attribute__((packed)) xfs_efd_log_format_32_t; - -typedef struct xfs_efd_log_format_64 { - __uint16_t efd_type; /* efd log item type */ - __uint16_t efd_size; /* size of this item */ - __uint32_t efd_nextents; /* # of extents freed */ - __uint64_t efd_efi_id; /* id of corresponding efi */ - xfs_extent_64_t efd_extents[1]; /* array of extents freed */ -} xfs_efd_log_format_64_t; - - -#ifdef __KERNEL__ - -/* - * Max number of extents in fast allocation path. - */ -#define XFS_EFI_MAX_FAST_EXTENTS 16 - -/* - * Define EFI flag bits. Manipulated by set/clear/test_bit operators. - */ -#define XFS_EFI_RECOVERED 1 -#define XFS_EFI_COMMITTED 2 - -/* - * This is the "extent free intention" log item. It is used - * to log the fact that some extents need to be free. It is - * used in conjunction with the "extent free done" log item - * described below. - */ -typedef struct xfs_efi_log_item { - xfs_log_item_t efi_item; - atomic_t efi_next_extent; - unsigned long efi_flags; /* misc flags */ - xfs_efi_log_format_t efi_format; -} xfs_efi_log_item_t; - -/* - * This is the "extent free done" log item. It is used to log - * the fact that some extents earlier mentioned in an efi item - * have been freed. - */ -typedef struct xfs_efd_log_item { - xfs_log_item_t efd_item; - xfs_efi_log_item_t *efd_efip; - uint efd_next_extent; - xfs_efd_log_format_t efd_format; -} xfs_efd_log_item_t; - -/* - * Max number of extents in fast allocation path. - */ -#define XFS_EFD_MAX_FAST_EXTENTS 16 - -extern struct kmem_zone *xfs_efi_zone; -extern struct kmem_zone *xfs_efd_zone; - -xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint); -xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *, - uint); -int xfs_efi_copy_format(xfs_log_iovec_t *buf, - xfs_efi_log_format_t *dst_efi_fmt); -void xfs_efi_item_free(xfs_efi_log_item_t *); - -#endif /* __KERNEL__ */ - -#endif /* __XFS_EXTFREE_ITEM_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_format.h xfsprogs-3.2.1ubuntu1/include/xfs_format.h --- xfsprogs-3.1.9ubuntu2/include/xfs_format.h 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_format.h 2014-06-19 22:42:17.000000000 +0000 @@ -0,0 +1,454 @@ +/* + * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_FORMAT_H__ +#define __XFS_FORMAT_H__ + +/* + * XFS On Disk Format Definitions + * + * This header file defines all the on-disk format definitions for + * general XFS objects. Directory and attribute related objects are defined in + * xfs_da_format.h, which log and log item formats are defined in + * xfs_log_format.h. Everything else goes here. + */ + +struct xfs_mount; +struct xfs_trans; +struct xfs_inode; +struct xfs_buf; +struct xfs_ifork; + +/* + * RealTime Device format definitions + */ + +/* Min and max rt extent sizes, specified in bytes */ +#define XFS_MAX_RTEXTSIZE (1024 * 1024 * 1024) /* 1GB */ +#define XFS_DFL_RTEXTSIZE (64 * 1024) /* 64kB */ +#define XFS_MIN_RTEXTSIZE (4 * 1024) /* 4kB */ + +#define XFS_BLOCKSIZE(mp) ((mp)->m_sb.sb_blocksize) +#define XFS_BLOCKMASK(mp) ((mp)->m_blockmask) +#define XFS_BLOCKWSIZE(mp) ((mp)->m_blockwsize) +#define XFS_BLOCKWMASK(mp) ((mp)->m_blockwmask) + +/* + * RT Summary and bit manipulation macros. + */ +#define XFS_SUMOFFS(mp,ls,bb) ((int)((ls) * (mp)->m_sb.sb_rbmblocks + (bb))) +#define XFS_SUMOFFSTOBLOCK(mp,s) \ + (((s) * (uint)sizeof(xfs_suminfo_t)) >> (mp)->m_sb.sb_blocklog) +#define XFS_SUMPTR(mp,bp,so) \ + ((xfs_suminfo_t *)((bp)->b_addr + \ + (((so) * (uint)sizeof(xfs_suminfo_t)) & XFS_BLOCKMASK(mp)))) + +#define XFS_BITTOBLOCK(mp,bi) ((bi) >> (mp)->m_blkbit_log) +#define XFS_BLOCKTOBIT(mp,bb) ((bb) << (mp)->m_blkbit_log) +#define XFS_BITTOWORD(mp,bi) \ + ((int)(((bi) >> XFS_NBWORDLOG) & XFS_BLOCKWMASK(mp))) + +#define XFS_RTMIN(a,b) ((a) < (b) ? (a) : (b)) +#define XFS_RTMAX(a,b) ((a) > (b) ? (a) : (b)) + +#define XFS_RTLOBIT(w) xfs_lowbit32(w) +#define XFS_RTHIBIT(w) xfs_highbit32(w) + +#if XFS_BIG_BLKNOS +#define XFS_RTBLOCKLOG(b) xfs_highbit64(b) +#else +#define XFS_RTBLOCKLOG(b) xfs_highbit32(b) +#endif + +/* + * Dquot and dquot block format definitions + */ +#define XFS_DQUOT_MAGIC 0x4451 /* 'DQ' */ +#define XFS_DQUOT_VERSION (u_int8_t)0x01 /* latest version number */ + +/* + * This is the main portion of the on-disk representation of quota + * information for a user. This is the q_core of the xfs_dquot_t that + * is kept in kernel memory. We pad this with some more expansion room + * to construct the on disk structure. + */ +typedef struct xfs_disk_dquot { + __be16 d_magic; /* dquot magic = XFS_DQUOT_MAGIC */ + __u8 d_version; /* dquot version */ + __u8 d_flags; /* XFS_DQ_USER/PROJ/GROUP */ + __be32 d_id; /* user,project,group id */ + __be64 d_blk_hardlimit;/* absolute limit on disk blks */ + __be64 d_blk_softlimit;/* preferred limit on disk blks */ + __be64 d_ino_hardlimit;/* maximum # allocated inodes */ + __be64 d_ino_softlimit;/* preferred inode limit */ + __be64 d_bcount; /* disk blocks owned by the user */ + __be64 d_icount; /* inodes owned by the user */ + __be32 d_itimer; /* zero if within inode limits if not, + this is when we refuse service */ + __be32 d_btimer; /* similar to above; for disk blocks */ + __be16 d_iwarns; /* warnings issued wrt num inodes */ + __be16 d_bwarns; /* warnings issued wrt disk blocks */ + __be32 d_pad0; /* 64 bit align */ + __be64 d_rtb_hardlimit;/* absolute limit on realtime blks */ + __be64 d_rtb_softlimit;/* preferred limit on RT disk blks */ + __be64 d_rtbcount; /* realtime blocks owned */ + __be32 d_rtbtimer; /* similar to above; for RT disk blocks */ + __be16 d_rtbwarns; /* warnings issued wrt RT disk blocks */ + __be16 d_pad; +} xfs_disk_dquot_t; + +/* + * This is what goes on disk. This is separated from the xfs_disk_dquot because + * carrying the unnecessary padding would be a waste of memory. + */ +typedef struct xfs_dqblk { + xfs_disk_dquot_t dd_diskdq; /* portion that lives incore as well */ + char dd_fill[4]; /* filling for posterity */ + + /* + * These two are only present on filesystems with the CRC bits set. + */ + __be32 dd_crc; /* checksum */ + __be64 dd_lsn; /* last modification in log */ + uuid_t dd_uuid; /* location information */ +} xfs_dqblk_t; + +#define XFS_DQUOT_CRC_OFF offsetof(struct xfs_dqblk, dd_crc) + +/* + * Remote symlink format and access functions. + */ +#define XFS_SYMLINK_MAGIC 0x58534c4d /* XSLM */ + +struct xfs_dsymlink_hdr { + __be32 sl_magic; + __be32 sl_offset; + __be32 sl_bytes; + __be32 sl_crc; + uuid_t sl_uuid; + __be64 sl_owner; + __be64 sl_blkno; + __be64 sl_lsn; +}; + +#define XFS_SYMLINK_CRC_OFF offsetof(struct xfs_dsymlink_hdr, sl_crc) + +/* + * The maximum pathlen is 1024 bytes. Since the minimum file system + * blocksize is 512 bytes, we can get a max of 3 extents back from + * bmapi when crc headers are taken into account. + */ +#define XFS_SYMLINK_MAPS 3 + +#define XFS_SYMLINK_BUF_SPACE(mp, bufsize) \ + ((bufsize) - (xfs_sb_version_hascrc(&(mp)->m_sb) ? \ + sizeof(struct xfs_dsymlink_hdr) : 0)) + + +/* + * Allocation Btree format definitions + * + * There are two on-disk btrees, one sorted by blockno and one sorted + * by blockcount and blockno. All blocks look the same to make the code + * simpler; if we have time later, we'll make the optimizations. + */ +#define XFS_ABTB_MAGIC 0x41425442 /* 'ABTB' for bno tree */ +#define XFS_ABTB_CRC_MAGIC 0x41423342 /* 'AB3B' */ +#define XFS_ABTC_MAGIC 0x41425443 /* 'ABTC' for cnt tree */ +#define XFS_ABTC_CRC_MAGIC 0x41423343 /* 'AB3C' */ + +/* + * Data record/key structure + */ +typedef struct xfs_alloc_rec { + __be32 ar_startblock; /* starting block number */ + __be32 ar_blockcount; /* count of free blocks */ +} xfs_alloc_rec_t, xfs_alloc_key_t; + +typedef struct xfs_alloc_rec_incore { + xfs_agblock_t ar_startblock; /* starting block number */ + xfs_extlen_t ar_blockcount; /* count of free blocks */ +} xfs_alloc_rec_incore_t; + +/* btree pointer type */ +typedef __be32 xfs_alloc_ptr_t; + +/* + * Block numbers in the AG: + * SB is sector 0, AGF is sector 1, AGI is sector 2, AGFL is sector 3. + */ +#define XFS_BNO_BLOCK(mp) ((xfs_agblock_t)(XFS_AGFL_BLOCK(mp) + 1)) +#define XFS_CNT_BLOCK(mp) ((xfs_agblock_t)(XFS_BNO_BLOCK(mp) + 1)) + + +/* + * Inode Allocation Btree format definitions + * + * There is a btree for the inode map per allocation group. + */ +#define XFS_IBT_MAGIC 0x49414254 /* 'IABT' */ +#define XFS_IBT_CRC_MAGIC 0x49414233 /* 'IAB3' */ +#define XFS_FIBT_MAGIC 0x46494254 /* 'FIBT' */ +#define XFS_FIBT_CRC_MAGIC 0x46494233 /* 'FIB3' */ + +typedef __uint64_t xfs_inofree_t; +#define XFS_INODES_PER_CHUNK (NBBY * sizeof(xfs_inofree_t)) +#define XFS_INODES_PER_CHUNK_LOG (XFS_NBBYLOG + 3) +#define XFS_INOBT_ALL_FREE ((xfs_inofree_t)-1) +#define XFS_INOBT_MASK(i) ((xfs_inofree_t)1 << (i)) + +static inline xfs_inofree_t xfs_inobt_maskn(int i, int n) +{ + return ((n >= XFS_INODES_PER_CHUNK ? 0 : XFS_INOBT_MASK(n)) - 1) << i; +} + +/* + * Data record structure + */ +typedef struct xfs_inobt_rec { + __be32 ir_startino; /* starting inode number */ + __be32 ir_freecount; /* count of free inodes (set bits) */ + __be64 ir_free; /* free inode mask */ +} xfs_inobt_rec_t; + +typedef struct xfs_inobt_rec_incore { + xfs_agino_t ir_startino; /* starting inode number */ + __int32_t ir_freecount; /* count of free inodes (set bits) */ + xfs_inofree_t ir_free; /* free inode mask */ +} xfs_inobt_rec_incore_t; + + +/* + * Key structure + */ +typedef struct xfs_inobt_key { + __be32 ir_startino; /* starting inode number */ +} xfs_inobt_key_t; + +/* btree pointer type */ +typedef __be32 xfs_inobt_ptr_t; + +/* + * block numbers in the AG. + */ +#define XFS_IBT_BLOCK(mp) ((xfs_agblock_t)(XFS_CNT_BLOCK(mp) + 1)) +#define XFS_FIBT_BLOCK(mp) ((xfs_agblock_t)(XFS_IBT_BLOCK(mp) + 1)) + +/* + * The first data block of an AG depends on whether the filesystem was formatted + * with the finobt feature. If so, account for the finobt reserved root btree + * block. + */ +#define XFS_PREALLOC_BLOCKS(mp) \ + (xfs_sb_version_hasfinobt(&((mp)->m_sb)) ? \ + XFS_FIBT_BLOCK(mp) + 1 : \ + XFS_IBT_BLOCK(mp) + 1) + + + +/* + * BMAP Btree format definitions + * + * This includes both the root block definition that sits inside an inode fork + * and the record/pointer formats for the leaf/node in the blocks. + */ +#define XFS_BMAP_MAGIC 0x424d4150 /* 'BMAP' */ +#define XFS_BMAP_CRC_MAGIC 0x424d4133 /* 'BMA3' */ + +/* + * Bmap root header, on-disk form only. + */ +typedef struct xfs_bmdr_block { + __be16 bb_level; /* 0 is a leaf */ + __be16 bb_numrecs; /* current # of data records */ +} xfs_bmdr_block_t; + +/* + * Bmap btree record and extent descriptor. + * l0:63 is an extent flag (value 1 indicates non-normal). + * l0:9-62 are startoff. + * l0:0-8 and l1:21-63 are startblock. + * l1:0-20 are blockcount. + */ +#define BMBT_EXNTFLAG_BITLEN 1 +#define BMBT_STARTOFF_BITLEN 54 +#define BMBT_STARTBLOCK_BITLEN 52 +#define BMBT_BLOCKCOUNT_BITLEN 21 + +typedef struct xfs_bmbt_rec { + __be64 l0, l1; +} xfs_bmbt_rec_t; + +typedef __uint64_t xfs_bmbt_rec_base_t; /* use this for casts */ +typedef xfs_bmbt_rec_t xfs_bmdr_rec_t; + +typedef struct xfs_bmbt_rec_host { + __uint64_t l0, l1; +} xfs_bmbt_rec_host_t; + +/* + * Values and macros for delayed-allocation startblock fields. + */ +#define STARTBLOCKVALBITS 17 +#define STARTBLOCKMASKBITS (15 + XFS_BIG_BLKNOS * 20) +#define DSTARTBLOCKMASKBITS (15 + 20) +#define STARTBLOCKMASK \ + (((((xfs_fsblock_t)1) << STARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS) +#define DSTARTBLOCKMASK \ + (((((xfs_dfsbno_t)1) << DSTARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS) + +static inline int isnullstartblock(xfs_fsblock_t x) +{ + return ((x) & STARTBLOCKMASK) == STARTBLOCKMASK; +} + +static inline int isnulldstartblock(xfs_dfsbno_t x) +{ + return ((x) & DSTARTBLOCKMASK) == DSTARTBLOCKMASK; +} + +static inline xfs_fsblock_t nullstartblock(int k) +{ + ASSERT(k < (1 << STARTBLOCKVALBITS)); + return STARTBLOCKMASK | (k); +} + +static inline xfs_filblks_t startblockval(xfs_fsblock_t x) +{ + return (xfs_filblks_t)((x) & ~STARTBLOCKMASK); +} + +/* + * Possible extent formats. + */ +typedef enum { + XFS_EXTFMT_NOSTATE = 0, + XFS_EXTFMT_HASSTATE +} xfs_exntfmt_t; + +/* + * Possible extent states. + */ +typedef enum { + XFS_EXT_NORM, XFS_EXT_UNWRITTEN, + XFS_EXT_DMAPI_OFFLINE, XFS_EXT_INVALID +} xfs_exntst_t; + +/* + * Incore version of above. + */ +typedef struct xfs_bmbt_irec +{ + xfs_fileoff_t br_startoff; /* starting file offset */ + xfs_fsblock_t br_startblock; /* starting block number */ + xfs_filblks_t br_blockcount; /* number of blocks */ + xfs_exntst_t br_state; /* extent state */ +} xfs_bmbt_irec_t; + +/* + * Key structure for non-leaf levels of the tree. + */ +typedef struct xfs_bmbt_key { + __be64 br_startoff; /* starting file offset */ +} xfs_bmbt_key_t, xfs_bmdr_key_t; + +/* btree pointer type */ +typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; + + +/* + * Generic Btree block format definitions + * + * This is a combination of the actual format used on disk for short and long + * format btrees. The first three fields are shared by both format, but the + * pointers are different and should be used with care. + * + * To get the size of the actual short or long form headers please use the size + * macros below. Never use sizeof(xfs_btree_block). + * + * The blkno, crc, lsn, owner and uuid fields are only available in filesystems + * with the crc feature bit, and all accesses to them must be conditional on + * that flag. + */ +struct xfs_btree_block { + __be32 bb_magic; /* magic number for block type */ + __be16 bb_level; /* 0 is a leaf */ + __be16 bb_numrecs; /* current # of data records */ + union { + struct { + __be32 bb_leftsib; + __be32 bb_rightsib; + + __be64 bb_blkno; + __be64 bb_lsn; + uuid_t bb_uuid; + __be32 bb_owner; + __le32 bb_crc; + } s; /* short form pointers */ + struct { + __be64 bb_leftsib; + __be64 bb_rightsib; + + __be64 bb_blkno; + __be64 bb_lsn; + uuid_t bb_uuid; + __be64 bb_owner; + __le32 bb_crc; + __be32 bb_pad; /* padding for alignment */ + } l; /* long form pointers */ + } bb_u; /* rest */ +}; + +#define XFS_BTREE_SBLOCK_LEN 16 /* size of a short form block */ +#define XFS_BTREE_LBLOCK_LEN 24 /* size of a long form block */ + +/* sizes of CRC enabled btree blocks */ +#define XFS_BTREE_SBLOCK_CRC_LEN (XFS_BTREE_SBLOCK_LEN + 40) +#define XFS_BTREE_LBLOCK_CRC_LEN (XFS_BTREE_LBLOCK_LEN + 48) + +#define XFS_BTREE_SBLOCK_CRC_OFF \ + offsetof(struct xfs_btree_block, bb_u.s.bb_crc) +#define XFS_BTREE_LBLOCK_CRC_OFF \ + offsetof(struct xfs_btree_block, bb_u.l.bb_crc) + +/* + * Generic key, ptr and record wrapper structures. + * + * These are disk format structures, and are converted where necessary + * by the btree specific code that needs to interpret them. + */ +union xfs_btree_ptr { + __be32 s; /* short form ptr */ + __be64 l; /* long form ptr */ +}; + +union xfs_btree_key { + xfs_bmbt_key_t bmbt; + xfs_bmdr_key_t bmbr; /* bmbt root block */ + xfs_alloc_key_t alloc; + xfs_inobt_key_t inobt; +}; + +union xfs_btree_rec { + xfs_bmbt_rec_t bmbt; + xfs_bmdr_rec_t bmbr; /* bmbt root block */ + xfs_alloc_rec_t alloc; + xfs_inobt_rec_t inobt; +}; + + +#endif /* __XFS_FORMAT_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_fs.h xfsprogs-3.2.1ubuntu1/include/xfs_fs.h --- xfsprogs-3.1.9ubuntu2/include/xfs_fs.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_fs.h 2014-06-19 22:42:17.000000000 +0000 @@ -233,12 +233,18 @@ #define XFS_FSOP_GEOM_FLAGS_LOGV2 0x0100 /* log format version 2 */ #define XFS_FSOP_GEOM_FLAGS_SECTOR 0x0200 /* sector sizes >1BB */ #define XFS_FSOP_GEOM_FLAGS_ATTR2 0x0400 /* inline attributes rework */ -#define XFS_FSOP_GEOM_FLAGS_DIRV2CI 0x1000 /* ASCII only CI names */ +#define XFS_FSOP_GEOM_FLAGS_PROJID32 0x0800 /* 32-bit project IDs */ +#define XFS_FSOP_GEOM_FLAGS_DIRV2CI 0x1000 /* ASCII only CI names */ #define XFS_FSOP_GEOM_FLAGS_LAZYSB 0x4000 /* lazy superblock counters */ +#define XFS_FSOP_GEOM_FLAGS_V5SB 0x8000 /* version 5 superblock */ +#define XFS_FSOP_GEOM_FLAGS_FTYPE 0x10000 /* inode directory types */ +#define XFS_FSOP_GEOM_FLAGS_FINOBT 0x20000 /* free inode btree */ /* - * Minimum and maximum sizes need for growth checks + * Minimum and maximum sizes need for growth checks. + * + * Block counts are in units of filesystem blocks, not basic blocks. */ #define XFS_MIN_AG_BLOCKS 64 #define XFS_MIN_LOG_BLOCKS 512ULL @@ -249,6 +255,11 @@ #define XFS_MAX_LOG_BYTES \ ((2 * 1024 * 1024 * 1024ULL) - XFS_MIN_LOG_BYTES) +/* Used for sanity checks on superblock */ +#define XFS_MAX_DBLOCKS(s) ((xfs_drfsbno_t)(s)->sb_agcount * (s)->sb_agblocks) +#define XFS_MIN_DBLOCKS(s) ((xfs_drfsbno_t)((s)->sb_agcount - 1) * \ + (s)->sb_agblocks + XFS_MIN_AG_BLOCKS) + /* * Structures for XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG & XFS_IOC_FSGROWFSRT */ @@ -304,6 +315,17 @@ } xfs_bstat_t; /* + * Project quota id helpers (previously projid was 16bit only + * and using two 16bit values to hold new 32bit projid was choosen + * to retain compatibility with "old" filesystems). + */ +static inline __uint32_t +bstat_get_projid(struct xfs_bstat *bs) +{ + return (__uint32_t)bs->bs_projid_hi << 16 | bs->bs_projid_lo; +} + +/* * The user-level BulkStat Request interface structure. */ typedef struct xfs_fsop_bulkreq { @@ -334,6 +356,35 @@ /* + * Speculative preallocation trimming. + */ +#define XFS_EOFBLOCKS_VERSION 1 +struct xfs_fs_eofblocks { + __u32 eof_version; + __u32 eof_flags; + uid_t eof_uid; + gid_t eof_gid; + prid_t eof_prid; + __u32 pad32; + __u64 eof_min_file_size; + __u64 pad64[12]; +}; + +/* eof_flags values */ +#define XFS_EOF_FLAGS_SYNC (1 << 0) /* sync/wait mode scan */ +#define XFS_EOF_FLAGS_UID (1 << 1) /* filter by uid */ +#define XFS_EOF_FLAGS_GID (1 << 2) /* filter by gid */ +#define XFS_EOF_FLAGS_PRID (1 << 3) /* filter by project id */ +#define XFS_EOF_FLAGS_MINFILESIZE (1 << 4) /* filter by min file size */ +#define XFS_EOF_FLAGS_VALID \ + (XFS_EOF_FLAGS_SYNC | \ + XFS_EOF_FLAGS_UID | \ + XFS_EOF_FLAGS_GID | \ + XFS_EOF_FLAGS_PRID | \ + XFS_EOF_FLAGS_MINFILESIZE) + + +/* * The user-level Handle Request interface structure. */ typedef struct xfs_fsop_handlereq { @@ -414,6 +465,21 @@ + (handle).ha_fid.fid_len) /* + * Structure passed to XFS_IOC_SWAPEXT + */ +typedef struct xfs_swapext +{ + __int64_t sx_version; /* version */ +#define XFS_SX_VERSION 0 + __int64_t sx_fdtarget; /* fd of target file */ + __int64_t sx_fdtmp; /* fd of tmp file */ + xfs_off_t sx_offset; /* offset into file */ + xfs_off_t sx_length; /* leng from offset */ + char sx_pad[16]; /* pad space, unused */ + xfs_bstat_t sx_stat; /* stat of target b4 copy */ +} xfs_swapext_t; + +/* * Flags for going down operation */ #define XFS_FSOP_GOING_FLAGS_DEFAULT 0x0 /* going down */ @@ -451,6 +517,7 @@ /* XFS_IOC_GETBIOSIZE ---- deprecated 47 */ #define XFS_IOC_GETBMAPX _IOWR('X', 56, struct getbmap) #define XFS_IOC_ZERO_RANGE _IOW ('X', 57, struct xfs_flock64) +#define XFS_IOC_FREE_EOFBLOCKS _IOR ('X', 58, struct xfs_fs_eofblocks) /* * ioctl commands that replace IRIX syssgi()'s @@ -474,10 +541,14 @@ #define XFS_IOC_ERROR_INJECTION _IOW ('X', 116, struct xfs_error_injection) #define XFS_IOC_ERROR_CLEARALL _IOW ('X', 117, struct xfs_error_injection) /* XFS_IOC_ATTRCTL_BY_HANDLE -- deprecated 118 */ + /* XFS_IOC_FREEZE -- FIFREEZE 119 */ /* XFS_IOC_THAW -- FITHAW 120 */ +#ifndef FIFREEZE #define XFS_IOC_FREEZE _IOWR('X', 119, int) #define XFS_IOC_THAW _IOWR('X', 120, int) +#endif + #define XFS_IOC_FSSETDM_BY_HANDLE _IOW ('X', 121, struct xfs_fsop_setdm_handlereq) #define XFS_IOC_ATTRLIST_BY_HANDLE _IOW ('X', 122, struct xfs_fsop_attrlist_handlereq) #define XFS_IOC_ATTRMULTI_BY_HANDLE _IOW ('X', 123, struct xfs_fsop_attrmulti_handlereq) @@ -500,15 +571,4 @@ #define BBTOB(bbs) ((bbs) << BBSHIFT) #endif -/* - * Project quota id helpers (previously projid was 16bit only - * and using two 16bit values to hold new 32bit projid was choosen - * to retain compatibility with "old" filesystems). - */ -static inline __uint32_t -bstat_get_projid(struct xfs_bstat *bs) -{ - return (__uint32_t)bs->bs_projid_hi << 16 | bs->bs_projid_lo; -} - #endif /* __XFS_FS_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs.h xfsprogs-3.2.1ubuntu1/include/xfs.h --- xfsprogs-3.1.9ubuntu2/include/xfs.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs.h 2013-06-06 22:52:59.000000000 +0000 @@ -34,6 +34,7 @@ #define __XFS_H__ #include +#include #include #endif /* __XFS_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_ialloc_btree.h xfsprogs-3.2.1ubuntu1/include/xfs_ialloc_btree.h --- xfsprogs-3.1.9ubuntu2/include/xfs_ialloc_btree.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_ialloc_btree.h 2014-06-19 22:42:17.000000000 +0000 @@ -27,59 +27,11 @@ struct xfs_mount; /* - * There is a btree for the inode map per allocation group. - */ -#define XFS_IBT_MAGIC 0x49414254 /* 'IABT' */ - -typedef __uint64_t xfs_inofree_t; -#define XFS_INODES_PER_CHUNK (NBBY * sizeof(xfs_inofree_t)) -#define XFS_INODES_PER_CHUNK_LOG (XFS_NBBYLOG + 3) -#define XFS_INOBT_ALL_FREE ((xfs_inofree_t)-1) -#define XFS_INOBT_MASK(i) ((xfs_inofree_t)1 << (i)) - -static inline xfs_inofree_t xfs_inobt_maskn(int i, int n) -{ - return ((n >= XFS_INODES_PER_CHUNK ? 0 : XFS_INOBT_MASK(n)) - 1) << i; -} - -/* - * Data record structure - */ -typedef struct xfs_inobt_rec { - __be32 ir_startino; /* starting inode number */ - __be32 ir_freecount; /* count of free inodes (set bits) */ - __be64 ir_free; /* free inode mask */ -} xfs_inobt_rec_t; - -typedef struct xfs_inobt_rec_incore { - xfs_agino_t ir_startino; /* starting inode number */ - __int32_t ir_freecount; /* count of free inodes (set bits) */ - xfs_inofree_t ir_free; /* free inode mask */ -} xfs_inobt_rec_incore_t; - - -/* - * Key structure - */ -typedef struct xfs_inobt_key { - __be32 ir_startino; /* starting inode number */ -} xfs_inobt_key_t; - -/* btree pointer type */ -typedef __be32 xfs_inobt_ptr_t; - -/* - * block numbers in the AG. - */ -#define XFS_IBT_BLOCK(mp) ((xfs_agblock_t)(XFS_CNT_BLOCK(mp) + 1)) -#define XFS_PREALLOC_BLOCKS(mp) ((xfs_agblock_t)(XFS_IBT_BLOCK(mp) + 1)) - -/* * Btree block header size depends on a superblock flag. - * - * (not quite yet, but soon) */ -#define XFS_INOBT_BLOCK_LEN(mp) XFS_BTREE_SBLOCK_LEN +#define XFS_INOBT_BLOCK_LEN(mp) \ + (xfs_sb_version_hascrc(&((mp)->m_sb)) ? \ + XFS_BTREE_SBLOCK_CRC_LEN : XFS_BTREE_SBLOCK_LEN) /* * Record, key, and pointer address macros for btree blocks. @@ -106,7 +58,8 @@ ((index) - 1) * sizeof(xfs_inobt_ptr_t))) extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_mount *, - struct xfs_trans *, struct xfs_buf *, xfs_agnumber_t); + struct xfs_trans *, struct xfs_buf *, xfs_agnumber_t, + xfs_btnum_t); extern int xfs_inobt_maxrecs(struct xfs_mount *, int, int); #endif /* __XFS_IALLOC_BTREE_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_ialloc.h xfsprogs-3.2.1ubuntu1/include/xfs_ialloc.h --- xfsprogs-3.1.9ubuntu2/include/xfs_ialloc.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_ialloc.h 2014-06-19 22:42:17.000000000 +0000 @@ -23,6 +23,7 @@ struct xfs_imap; struct xfs_mount; struct xfs_trans; +struct xfs_btree_cur; /* * Allocation parameters for inode allocation. @@ -42,20 +43,11 @@ static inline struct xfs_dinode * xfs_make_iptr(struct xfs_mount *mp, struct xfs_buf *b, int o) { - return (xfs_dinode_t *) + return (struct xfs_dinode *) (xfs_buf_offset(b, o << (mp)->m_sb.sb_inodelog)); } /* - * Find a free (set) bit in the inode bitmask. - */ -static inline int xfs_ialloc_find_free(xfs_inofree_t *fp) -{ - return xfs_lowbit64(*fp); -} - - -/* * Allocate an inode on disk. * Mode is used to tell whether the new inode will need space, and whether * it is a directory. @@ -81,11 +73,9 @@ xfs_dialloc( struct xfs_trans *tp, /* transaction pointer */ xfs_ino_t parent, /* parent inode (directory) */ - mode_t mode, /* mode bits for new inode */ + umode_t mode, /* mode bits for new inode */ int okalloc, /* ok to allocate more space */ struct xfs_buf **agbp, /* buf for a.g. inode header */ - boolean_t *alloc_done, /* an allocation was done to replenish - the free inodes */ xfs_ino_t *inop); /* inode number allocated */ /* @@ -99,7 +89,7 @@ struct xfs_trans *tp, /* transaction pointer */ xfs_ino_t inode, /* inode to be freed */ struct xfs_bmap_free *flist, /* extents to free */ - int *delete, /* set if inode cluster was deleted */ + int *deleted, /* set if inode cluster was deleted */ xfs_ino_t *first_ino); /* first inode in deleted cluster */ /* @@ -158,7 +148,15 @@ /* * Get the data from the pointed-to record. */ -extern int xfs_inobt_get_rec(struct xfs_btree_cur *cur, +int xfs_inobt_get_rec(struct xfs_btree_cur *cur, xfs_inobt_rec_incore_t *rec, int *stat); +/* + * Inode chunk initialisation routine + */ +int xfs_ialloc_inode_init(struct xfs_mount *mp, struct xfs_trans *tp, + struct list_head *buffer_list, + xfs_agnumber_t agno, xfs_agblock_t agbno, + xfs_agblock_t length, unsigned int gen); + #endif /* __XFS_IALLOC_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_inode_buf.h xfsprogs-3.2.1ubuntu1/include/xfs_inode_buf.h --- xfsprogs-3.1.9ubuntu2/include/xfs_inode_buf.h 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_inode_buf.h 2014-05-02 00:09:15.000000000 +0000 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_INODE_BUF_H__ +#define __XFS_INODE_BUF_H__ + +struct xfs_inode; +struct xfs_dinode; +struct xfs_icdinode; + +/* + * Inode location information. Stored in the inode and passed to + * xfs_imap_to_bp() to get a buffer and dinode for a given inode. + */ +struct xfs_imap { + xfs_daddr_t im_blkno; /* starting BB of inode chunk */ + ushort im_len; /* length in BBs of inode chunk */ + ushort im_boffset; /* inode offset in block in bytes */ +}; + +int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *, + struct xfs_imap *, struct xfs_dinode **, + struct xfs_buf **, uint, uint); +int xfs_iread(struct xfs_mount *, struct xfs_trans *, + struct xfs_inode *, uint); +void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *); +void xfs_dinode_to_disk(struct xfs_dinode *to, struct xfs_icdinode *from); +void xfs_dinode_from_disk(struct xfs_icdinode *to, struct xfs_dinode *from); + +#if defined(DEBUG) +void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *); +#else +#define xfs_inobp_check(mp, bp) +#endif /* DEBUG */ + +#endif /* __XFS_INODE_BUF_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_inode_fork.h xfsprogs-3.2.1ubuntu1/include/xfs_inode_fork.h --- xfsprogs-3.1.9ubuntu2/include/xfs_inode_fork.h 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_inode_fork.h 2014-05-02 00:09:15.000000000 +0000 @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_INODE_FORK_H__ +#define __XFS_INODE_FORK_H__ + +struct xfs_inode_log_item; +struct xfs_dinode; + +/* + * The following xfs_ext_irec_t struct introduces a second (top) level + * to the in-core extent allocation scheme. These structs are allocated + * in a contiguous block, creating an indirection array where each entry + * (irec) contains a pointer to a buffer of in-core extent records which + * it manages. Each extent buffer is 4k in size, since 4k is the system + * page size on Linux i386 and systems with larger page sizes don't seem + * to gain much, if anything, by using their native page size as the + * extent buffer size. Also, using 4k extent buffers everywhere provides + * a consistent interface for CXFS across different platforms. + * + * There is currently no limit on the number of irec's (extent lists) + * allowed, so heavily fragmented files may require an indirection array + * which spans multiple system pages of memory. The number of extents + * which would require this amount of contiguous memory is very large + * and should not cause problems in the foreseeable future. However, + * if the memory needed for the contiguous array ever becomes a problem, + * it is possible that a third level of indirection may be required. + */ +typedef struct xfs_ext_irec { + xfs_bmbt_rec_host_t *er_extbuf; /* block of extent records */ + xfs_extnum_t er_extoff; /* extent offset in file */ + xfs_extnum_t er_extcount; /* number of extents in page/block */ +} xfs_ext_irec_t; + +/* + * File incore extent information, present for each of data & attr forks. + */ +#define XFS_IEXT_BUFSZ 4096 +#define XFS_LINEAR_EXTS (XFS_IEXT_BUFSZ / (uint)sizeof(xfs_bmbt_rec_t)) +#define XFS_INLINE_EXTS 2 +#define XFS_INLINE_DATA 32 +typedef struct xfs_ifork { + int if_bytes; /* bytes in if_u1 */ + int if_real_bytes; /* bytes allocated in if_u1 */ + struct xfs_btree_block *if_broot; /* file's incore btree root */ + short if_broot_bytes; /* bytes allocated for root */ + unsigned char if_flags; /* per-fork flags */ + union { + xfs_bmbt_rec_host_t *if_extents;/* linear map file exts */ + xfs_ext_irec_t *if_ext_irec; /* irec map file exts */ + char *if_data; /* inline file data */ + } if_u1; + union { + xfs_bmbt_rec_host_t if_inline_ext[XFS_INLINE_EXTS]; + /* very small file extents */ + char if_inline_data[XFS_INLINE_DATA]; + /* very small file data */ + xfs_dev_t if_rdev; /* dev number if special */ + uuid_t if_uuid; /* mount point value */ + } if_u2; +} xfs_ifork_t; + +/* + * Per-fork incore inode flags. + */ +#define XFS_IFINLINE 0x01 /* Inline data is read in */ +#define XFS_IFEXTENTS 0x02 /* All extent pointers are read in */ +#define XFS_IFBROOT 0x04 /* i_broot points to the bmap b-tree root */ +#define XFS_IFEXTIREC 0x08 /* Indirection array of extent blocks */ + +/* + * Fork handling. + */ + +#define XFS_IFORK_Q(ip) ((ip)->i_d.di_forkoff != 0) +#define XFS_IFORK_BOFF(ip) ((int)((ip)->i_d.di_forkoff << 3)) + +#define XFS_IFORK_PTR(ip,w) \ + ((w) == XFS_DATA_FORK ? \ + &(ip)->i_df : \ + (ip)->i_afp) +#define XFS_IFORK_DSIZE(ip) \ + (XFS_IFORK_Q(ip) ? \ + XFS_IFORK_BOFF(ip) : \ + XFS_LITINO((ip)->i_mount, (ip)->i_d.di_version)) +#define XFS_IFORK_ASIZE(ip) \ + (XFS_IFORK_Q(ip) ? \ + XFS_LITINO((ip)->i_mount, (ip)->i_d.di_version) - \ + XFS_IFORK_BOFF(ip) : \ + 0) +#define XFS_IFORK_SIZE(ip,w) \ + ((w) == XFS_DATA_FORK ? \ + XFS_IFORK_DSIZE(ip) : \ + XFS_IFORK_ASIZE(ip)) +#define XFS_IFORK_FORMAT(ip,w) \ + ((w) == XFS_DATA_FORK ? \ + (ip)->i_d.di_format : \ + (ip)->i_d.di_aformat) +#define XFS_IFORK_FMT_SET(ip,w,n) \ + ((w) == XFS_DATA_FORK ? \ + ((ip)->i_d.di_format = (n)) : \ + ((ip)->i_d.di_aformat = (n))) +#define XFS_IFORK_NEXTENTS(ip,w) \ + ((w) == XFS_DATA_FORK ? \ + (ip)->i_d.di_nextents : \ + (ip)->i_d.di_anextents) +#define XFS_IFORK_NEXT_SET(ip,w,n) \ + ((w) == XFS_DATA_FORK ? \ + ((ip)->i_d.di_nextents = (n)) : \ + ((ip)->i_d.di_anextents = (n))) +#define XFS_IFORK_MAXEXT(ip, w) \ + (XFS_IFORK_SIZE(ip, w) / sizeof(xfs_bmbt_rec_t)) + +int xfs_iformat_fork(struct xfs_inode *, struct xfs_dinode *); +void xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *, + struct xfs_inode_log_item *, int, + struct xfs_buf *); +void xfs_idestroy_fork(struct xfs_inode *, int); +void xfs_idata_realloc(struct xfs_inode *, int, int); +void xfs_iroot_realloc(struct xfs_inode *, int, int); +int xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int); +int xfs_iextents_copy(struct xfs_inode *, struct xfs_bmbt_rec *, + int); + +struct xfs_bmbt_rec_host * + xfs_iext_get_ext(struct xfs_ifork *, xfs_extnum_t); +void xfs_iext_insert(struct xfs_inode *, xfs_extnum_t, xfs_extnum_t, + struct xfs_bmbt_irec *, int); +void xfs_iext_add(struct xfs_ifork *, xfs_extnum_t, int); +void xfs_iext_add_indirect_multi(struct xfs_ifork *, int, + xfs_extnum_t, int); +void xfs_iext_remove(struct xfs_inode *, xfs_extnum_t, int, int); +void xfs_iext_remove_inline(struct xfs_ifork *, xfs_extnum_t, int); +void xfs_iext_remove_direct(struct xfs_ifork *, xfs_extnum_t, int); +void xfs_iext_remove_indirect(struct xfs_ifork *, xfs_extnum_t, int); +void xfs_iext_realloc_direct(struct xfs_ifork *, int); +void xfs_iext_direct_to_inline(struct xfs_ifork *, xfs_extnum_t); +void xfs_iext_inline_to_direct(struct xfs_ifork *, int); +void xfs_iext_destroy(struct xfs_ifork *); +struct xfs_bmbt_rec_host * + xfs_iext_bno_to_ext(struct xfs_ifork *, xfs_fileoff_t, int *); +struct xfs_ext_irec * + xfs_iext_bno_to_irec(struct xfs_ifork *, xfs_fileoff_t, int *); +struct xfs_ext_irec * + xfs_iext_idx_to_irec(struct xfs_ifork *, xfs_extnum_t *, int *, + int); +void xfs_iext_irec_init(struct xfs_ifork *); +struct xfs_ext_irec * + xfs_iext_irec_new(struct xfs_ifork *, int); +void xfs_iext_irec_remove(struct xfs_ifork *, int); +void xfs_iext_irec_compact(struct xfs_ifork *); +void xfs_iext_irec_compact_pages(struct xfs_ifork *); +void xfs_iext_irec_compact_full(struct xfs_ifork *); +void xfs_iext_irec_update_extoffs(struct xfs_ifork *, int, int); + +extern struct kmem_zone *xfs_ifork_zone; + +#endif /* __XFS_INODE_FORK_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_inode.h xfsprogs-3.2.1ubuntu1/include/xfs_inode.h --- xfsprogs-3.1.9ubuntu2/include/xfs_inode.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_inode.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,602 +0,0 @@ -/* - * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_INODE_H__ -#define __XFS_INODE_H__ - -struct posix_acl; -struct xfs_dinode; -struct xfs_inode; - -/* - * Fork identifiers. - */ -#define XFS_DATA_FORK 0 -#define XFS_ATTR_FORK 1 - -/* - * The following xfs_ext_irec_t struct introduces a second (top) level - * to the in-core extent allocation scheme. These structs are allocated - * in a contiguous block, creating an indirection array where each entry - * (irec) contains a pointer to a buffer of in-core extent records which - * it manages. Each extent buffer is 4k in size, since 4k is the system - * page size on Linux i386 and systems with larger page sizes don't seem - * to gain much, if anything, by using their native page size as the - * extent buffer size. Also, using 4k extent buffers everywhere provides - * a consistent interface for CXFS across different platforms. - * - * There is currently no limit on the number of irec's (extent lists) - * allowed, so heavily fragmented files may require an indirection array - * which spans multiple system pages of memory. The number of extents - * which would require this amount of contiguous memory is very large - * and should not cause problems in the foreseeable future. However, - * if the memory needed for the contiguous array ever becomes a problem, - * it is possible that a third level of indirection may be required. - */ -typedef struct xfs_ext_irec { - xfs_bmbt_rec_host_t *er_extbuf; /* block of extent records */ - xfs_extnum_t er_extoff; /* extent offset in file */ - xfs_extnum_t er_extcount; /* number of extents in page/block */ -} xfs_ext_irec_t; - -/* - * File incore extent information, present for each of data & attr forks. - */ -#define XFS_IEXT_BUFSZ 4096 -#define XFS_LINEAR_EXTS (XFS_IEXT_BUFSZ / (uint)sizeof(xfs_bmbt_rec_t)) -#define XFS_INLINE_EXTS 2 -#define XFS_INLINE_DATA 32 -typedef struct xfs_ifork { - int if_bytes; /* bytes in if_u1 */ - int if_real_bytes; /* bytes allocated in if_u1 */ - struct xfs_btree_block *if_broot; /* file's incore btree root */ - short if_broot_bytes; /* bytes allocated for root */ - unsigned char if_flags; /* per-fork flags */ - unsigned char if_ext_max; /* max # of extent records */ - xfs_extnum_t if_lastex; /* last if_extents used */ - union { - xfs_bmbt_rec_host_t *if_extents;/* linear map file exts */ - xfs_ext_irec_t *if_ext_irec; /* irec map file exts */ - char *if_data; /* inline file data */ - } if_u1; - union { - xfs_bmbt_rec_host_t if_inline_ext[XFS_INLINE_EXTS]; - /* very small file extents */ - char if_inline_data[XFS_INLINE_DATA]; - /* very small file data */ - xfs_dev_t if_rdev; /* dev number if special */ - uuid_t if_uuid; /* mount point value */ - } if_u2; -} xfs_ifork_t; - -/* - * Inode location information. Stored in the inode and passed to - * xfs_imap_to_bp() to get a buffer and dinode for a given inode. - */ -struct xfs_imap { - xfs_daddr_t im_blkno; /* starting BB of inode chunk */ - ushort im_len; /* length in BBs of inode chunk */ - ushort im_boffset; /* inode offset in block in bytes */ -}; - -/* - * This is the xfs in-core inode structure. - * Most of the on-disk inode is embedded in the i_d field. - * - * The extent pointers/inline file space, however, are managed - * separately. The memory for this information is pointed to by - * the if_u1 unions depending on the type of the data. - * This is used to linearize the array of extents for fast in-core - * access. This is used until the file's number of extents - * surpasses XFS_MAX_INCORE_EXTENTS, at which point all extent pointers - * are accessed through the buffer cache. - * - * Other state kept in the in-core inode is used for identification, - * locking, transactional updating, etc of the inode. - * - * Generally, we do not want to hold the i_rlock while holding the - * i_ilock. Hierarchy is i_iolock followed by i_rlock. - * - * xfs_iptr_t contains all the inode fields upto and including the - * i_mnext and i_mprev fields, it is used as a marker in the inode - * chain off the mount structure by xfs_sync calls. - */ - -typedef struct xfs_ictimestamp { - __int32_t t_sec; /* timestamp seconds */ - __int32_t t_nsec; /* timestamp nanoseconds */ -} xfs_ictimestamp_t; - -/* - * NOTE: This structure must be kept identical to struct xfs_dinode - * in xfs_dinode.h except for the endianness annotations. - */ -typedef struct xfs_icdinode { - __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ - __uint16_t di_mode; /* mode and type of file */ - __int8_t di_version; /* inode version */ - __int8_t di_format; /* format of di_c data */ - __uint16_t di_onlink; /* old number of links to file */ - __uint32_t di_uid; /* owner's user id */ - __uint32_t di_gid; /* owner's group id */ - __uint32_t di_nlink; /* number of links to file */ - __uint16_t di_projid_lo; /* lower part of owner's project id */ - __uint16_t di_projid_hi; /* higher part of owner's project id */ - __uint8_t di_pad[6]; /* unused, zeroed space */ - __uint16_t di_flushiter; /* incremented on flush */ - xfs_ictimestamp_t di_atime; /* time last accessed */ - xfs_ictimestamp_t di_mtime; /* time last modified */ - xfs_ictimestamp_t di_ctime; /* time created/inode modified */ - xfs_fsize_t di_size; /* number of bytes in file */ - xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */ - xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ - xfs_extnum_t di_nextents; /* number of extents in data fork */ - xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ - __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ - __int8_t di_aformat; /* format of attr fork's data */ - __uint32_t di_dmevmask; /* DMIG event mask */ - __uint16_t di_dmstate; /* DMIG state info */ - __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ - __uint32_t di_gen; /* generation number */ -} xfs_icdinode_t; - -/* - * Flags for xfs_ichgtime(). - */ -#define XFS_ICHGTIME_MOD 0x1 /* data fork modification timestamp */ -#define XFS_ICHGTIME_CHG 0x2 /* inode field change timestamp */ - -/* - * Per-fork incore inode flags. - */ -#define XFS_IFINLINE 0x01 /* Inline data is read in */ -#define XFS_IFEXTENTS 0x02 /* All extent pointers are read in */ -#define XFS_IFBROOT 0x04 /* i_broot points to the bmap b-tree root */ -#define XFS_IFEXTIREC 0x08 /* Indirection array of extent blocks */ - -/* - * Fork handling. - */ - -#define XFS_IFORK_Q(ip) ((ip)->i_d.di_forkoff != 0) -#define XFS_IFORK_BOFF(ip) ((int)((ip)->i_d.di_forkoff << 3)) - -#define XFS_IFORK_PTR(ip,w) \ - ((w) == XFS_DATA_FORK ? \ - &(ip)->i_df : \ - (ip)->i_afp) -#define XFS_IFORK_DSIZE(ip) \ - (XFS_IFORK_Q(ip) ? \ - XFS_IFORK_BOFF(ip) : \ - XFS_LITINO((ip)->i_mount)) -#define XFS_IFORK_ASIZE(ip) \ - (XFS_IFORK_Q(ip) ? \ - XFS_LITINO((ip)->i_mount) - XFS_IFORK_BOFF(ip) : \ - 0) -#define XFS_IFORK_SIZE(ip,w) \ - ((w) == XFS_DATA_FORK ? \ - XFS_IFORK_DSIZE(ip) : \ - XFS_IFORK_ASIZE(ip)) -#define XFS_IFORK_FORMAT(ip,w) \ - ((w) == XFS_DATA_FORK ? \ - (ip)->i_d.di_format : \ - (ip)->i_d.di_aformat) -#define XFS_IFORK_FMT_SET(ip,w,n) \ - ((w) == XFS_DATA_FORK ? \ - ((ip)->i_d.di_format = (n)) : \ - ((ip)->i_d.di_aformat = (n))) -#define XFS_IFORK_NEXTENTS(ip,w) \ - ((w) == XFS_DATA_FORK ? \ - (ip)->i_d.di_nextents : \ - (ip)->i_d.di_anextents) -#define XFS_IFORK_NEXT_SET(ip,w,n) \ - ((w) == XFS_DATA_FORK ? \ - ((ip)->i_d.di_nextents = (n)) : \ - ((ip)->i_d.di_anextents = (n))) - -/* - * Project quota id helpers (previously projid was 16bit only - * and using two 16bit values to hold new 32bit projid was choosen - * to retain compatibility with "old" filesystems). - */ -static inline __uint32_t -xfs_get_projid(struct xfs_icdinode i_d) -{ - return (__uint32_t)i_d.di_projid_hi << 16 | i_d.di_projid_lo; -} - -static inline void -xfs_set_projid(struct xfs_icdinode *i_d, - __uint32_t projid) -{ - i_d->di_projid_hi = (__uint16_t) (projid >> 16); - i_d->di_projid_lo = (__uint16_t) (projid & 0xffff); -} - -#ifdef __KERNEL__ - -struct bhv_desc; -struct xfs_buf; -struct xfs_bmap_free; -struct xfs_bmbt_irec; -struct xfs_inode_log_item; -struct xfs_mount; -struct xfs_trans; -struct xfs_dquot; - -typedef struct dm_attrs_s { - __uint32_t da_dmevmask; /* DMIG event mask */ - __uint16_t da_dmstate; /* DMIG state info */ - __uint16_t da_pad; /* DMIG extra padding */ -} dm_attrs_t; - -typedef struct xfs_inode { - /* Inode linking and identification information. */ - struct xfs_mount *i_mount; /* fs mount struct ptr */ - struct xfs_dquot *i_udquot; /* user dquot */ - struct xfs_dquot *i_gdquot; /* group dquot */ - - /* Inode location stuff */ - xfs_ino_t i_ino; /* inode number (agno/agino)*/ - struct xfs_imap i_imap; /* location for xfs_imap() */ - - /* Extent information. */ - xfs_ifork_t *i_afp; /* attribute fork pointer */ - xfs_ifork_t i_df; /* data fork */ - - /* Transaction and locking information. */ - struct xfs_trans *i_transp; /* ptr to owning transaction*/ - struct xfs_inode_log_item *i_itemp; /* logging information */ - mrlock_t i_lock; /* inode lock */ - mrlock_t i_iolock; /* inode IO lock */ - struct completion i_flush; /* inode flush completion q */ - atomic_t i_pincount; /* inode pin count */ - wait_queue_head_t i_ipin_wait; /* inode pinning wait queue */ - spinlock_t i_flags_lock; /* inode i_flags lock */ - /* Miscellaneous state. */ - unsigned short i_flags; /* see defined flags below */ - unsigned char i_update_core; /* timestamps/size is dirty */ - unsigned int i_delayed_blks; /* count of delay alloc blks */ - - xfs_icdinode_t i_d; /* most of ondisk inode */ - - xfs_fsize_t i_size; /* in-memory size */ - xfs_fsize_t i_new_size; /* size when write completes */ - atomic_t i_iocount; /* outstanding I/O count */ - - /* VFS inode */ - struct inode i_vnode; /* embedded VFS inode */ -} xfs_inode_t; - -#define XFS_ISIZE(ip) (((ip)->i_d.di_mode & S_IFMT) == S_IFREG) ? \ - (ip)->i_size : (ip)->i_d.di_size; - -/* Convert from vfs inode to xfs inode */ -static inline struct xfs_inode *XFS_I(struct inode *inode) -{ - return container_of(inode, struct xfs_inode, i_vnode); -} - -/* convert from xfs inode to vfs inode */ -static inline struct inode *VFS_I(struct xfs_inode *ip) -{ - return &ip->i_vnode; -} - -/* - * i_flags helper functions - */ -static inline void -__xfs_iflags_set(xfs_inode_t *ip, unsigned short flags) -{ - ip->i_flags |= flags; -} - -static inline void -xfs_iflags_set(xfs_inode_t *ip, unsigned short flags) -{ - spin_lock(&ip->i_flags_lock); - __xfs_iflags_set(ip, flags); - spin_unlock(&ip->i_flags_lock); -} - -static inline void -xfs_iflags_clear(xfs_inode_t *ip, unsigned short flags) -{ - spin_lock(&ip->i_flags_lock); - ip->i_flags &= ~flags; - spin_unlock(&ip->i_flags_lock); -} - -static inline int -__xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) -{ - return (ip->i_flags & flags); -} - -static inline int -xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) -{ - int ret; - spin_lock(&ip->i_flags_lock); - ret = __xfs_iflags_test(ip, flags); - spin_unlock(&ip->i_flags_lock); - return ret; -} - -static inline int -xfs_iflags_test_and_clear(xfs_inode_t *ip, unsigned short flags) -{ - int ret; - - spin_lock(&ip->i_flags_lock); - ret = ip->i_flags & flags; - if (ret) - ip->i_flags &= ~flags; - spin_unlock(&ip->i_flags_lock); - return ret; -} - -/* - * Project quota id helpers (previously projid was 16bit only - * and using two 16bit values to hold new 32bit projid was choosen - * to retain compatibility with "old" filesystems). - */ -static inline prid_t -xfs_get_projid(struct xfs_inode *ip) -{ - return (prid_t)ip->i_d.di_projid_hi << 16 | ip->i_d.di_projid_lo; -} - -static inline void -xfs_set_projid(struct xfs_inode *ip, - prid_t projid) -{ - ip->i_d.di_projid_hi = (__uint16_t) (projid >> 16); - ip->i_d.di_projid_lo = (__uint16_t) (projid & 0xffff); -} - -/* - * Manage the i_flush queue embedded in the inode. This completion - * queue synchronizes processes attempting to flush the in-core - * inode back to disk. - */ -static inline void xfs_iflock(xfs_inode_t *ip) -{ - wait_for_completion(&ip->i_flush); -} - -static inline int xfs_iflock_nowait(xfs_inode_t *ip) -{ - return try_wait_for_completion(&ip->i_flush); -} - -static inline void xfs_ifunlock(xfs_inode_t *ip) -{ - complete(&ip->i_flush); -} - -/* - * In-core inode flags. - */ -#define XFS_IRECLAIM 0x0001 /* started reclaiming this inode */ -#define XFS_ISTALE 0x0002 /* inode has been staled */ -#define XFS_IRECLAIMABLE 0x0004 /* inode can be reclaimed */ -#define XFS_INEW 0x0008 /* inode has just been allocated */ -#define XFS_IFILESTREAM 0x0010 /* inode is in a filestream directory */ -#define XFS_ITRUNCATED 0x0020 /* truncated down so flush-on-close */ -#define XFS_IDIRTY_RELEASE 0x0040 /* dirty release already seen */ - -/* - * Flags for inode locking. - * Bit ranges: 1<<1 - 1<<16-1 -- iolock/ilock modes (bitfield) - * 1<<16 - 1<<32-1 -- lockdep annotation (integers) - */ -#define XFS_IOLOCK_EXCL (1<<0) -#define XFS_IOLOCK_SHARED (1<<1) -#define XFS_ILOCK_EXCL (1<<2) -#define XFS_ILOCK_SHARED (1<<3) -#define XFS_IUNLOCK_NONOTIFY (1<<4) - -#define XFS_LOCK_MASK (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED \ - | XFS_ILOCK_EXCL | XFS_ILOCK_SHARED) - -#define XFS_LOCK_FLAGS \ - { XFS_IOLOCK_EXCL, "IOLOCK_EXCL" }, \ - { XFS_IOLOCK_SHARED, "IOLOCK_SHARED" }, \ - { XFS_ILOCK_EXCL, "ILOCK_EXCL" }, \ - { XFS_ILOCK_SHARED, "ILOCK_SHARED" }, \ - { XFS_IUNLOCK_NONOTIFY, "IUNLOCK_NONOTIFY" } - - -/* - * Flags for lockdep annotations. - * - * XFS_I[O]LOCK_PARENT - for operations that require locking two inodes - * (ie directory operations that require locking a directory inode and - * an entry inode). The first inode gets locked with this flag so it - * gets a lockdep subclass of 1 and the second lock will have a lockdep - * subclass of 0. - * - * XFS_LOCK_INUMORDER - for locking several inodes at the some time - * with xfs_lock_inodes(). This flag is used as the starting subclass - * and each subsequent lock acquired will increment the subclass by one. - * So the first lock acquired will have a lockdep subclass of 2, the - * second lock will have a lockdep subclass of 3, and so on. It is - * the responsibility of the class builder to shift this to the correct - * portion of the lock_mode lockdep mask. - */ -#define XFS_LOCK_PARENT 1 -#define XFS_LOCK_INUMORDER 2 - -#define XFS_IOLOCK_SHIFT 16 -#define XFS_IOLOCK_PARENT (XFS_LOCK_PARENT << XFS_IOLOCK_SHIFT) - -#define XFS_ILOCK_SHIFT 24 -#define XFS_ILOCK_PARENT (XFS_LOCK_PARENT << XFS_ILOCK_SHIFT) - -#define XFS_IOLOCK_DEP_MASK 0x00ff0000 -#define XFS_ILOCK_DEP_MASK 0xff000000 -#define XFS_LOCK_DEP_MASK (XFS_IOLOCK_DEP_MASK | XFS_ILOCK_DEP_MASK) - -#define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT) -#define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT) - -extern struct lock_class_key xfs_iolock_reclaimable; - -/* - * Flags for xfs_itruncate_start(). - */ -#define XFS_ITRUNC_DEFINITE 0x1 -#define XFS_ITRUNC_MAYBE 0x2 - -#define XFS_ITRUNC_FLAGS \ - { XFS_ITRUNC_DEFINITE, "DEFINITE" }, \ - { XFS_ITRUNC_MAYBE, "MAYBE" } - -/* - * For multiple groups support: if S_ISGID bit is set in the parent - * directory, group of new file is set to that of the parent, and - * new subdirectory gets S_ISGID bit from parent. - */ -#define XFS_INHERIT_GID(pip) \ - (((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \ - ((pip)->i_d.di_mode & S_ISGID)) - -/* - * xfs_iget.c prototypes. - */ -int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, - uint, uint, xfs_inode_t **); -void xfs_ilock(xfs_inode_t *, uint); -int xfs_ilock_nowait(xfs_inode_t *, uint); -void xfs_iunlock(xfs_inode_t *, uint); -void xfs_ilock_demote(xfs_inode_t *, uint); -int xfs_isilocked(xfs_inode_t *, uint); -uint xfs_ilock_map_shared(xfs_inode_t *); -void xfs_iunlock_map_shared(xfs_inode_t *, uint); -void xfs_inode_free(struct xfs_inode *ip); - -/* - * xfs_inode.c prototypes. - */ -int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, - xfs_nlink_t, xfs_dev_t, prid_t, int, - struct xfs_buf **, boolean_t *, xfs_inode_t **); - -uint xfs_ip2xflags(struct xfs_inode *); -uint xfs_dic2xflags(struct xfs_dinode *); -int xfs_ifree(struct xfs_trans *, xfs_inode_t *, - struct xfs_bmap_free *); -int xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t); -int xfs_itruncate_finish(struct xfs_trans **, xfs_inode_t *, - xfs_fsize_t, int, int); -int xfs_iunlink(struct xfs_trans *, xfs_inode_t *); - -void xfs_iext_realloc(xfs_inode_t *, int, int); -void xfs_iunpin_wait(xfs_inode_t *); -int xfs_iflush(xfs_inode_t *, uint); -void xfs_lock_inodes(xfs_inode_t **, int, uint); -void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint); - -void xfs_synchronize_times(xfs_inode_t *); -void xfs_mark_inode_dirty(xfs_inode_t *); -void xfs_mark_inode_dirty_sync(xfs_inode_t *); - -#define IHOLD(ip) \ -do { \ - ASSERT(atomic_read(&VFS_I(ip)->i_count) > 0) ; \ - ihold(VFS_I(ip)); \ - trace_xfs_ihold(ip, _THIS_IP_); \ -} while (0) - -#define IRELE(ip) \ -do { \ - trace_xfs_irele(ip, _THIS_IP_); \ - iput(VFS_I(ip)); \ -} while (0) - -#endif /* __KERNEL__ */ - -/* - * Flags for xfs_iget() - */ -#define XFS_IGET_CREATE 0x1 -#define XFS_IGET_UNTRUSTED 0x2 - -int xfs_inotobp(struct xfs_mount *, struct xfs_trans *, - xfs_ino_t, struct xfs_dinode **, - struct xfs_buf **, int *, uint); -int xfs_itobp(struct xfs_mount *, struct xfs_trans *, - struct xfs_inode *, struct xfs_dinode **, - struct xfs_buf **, uint); -int xfs_iread(struct xfs_mount *, struct xfs_trans *, - struct xfs_inode *, uint); -void xfs_dinode_to_disk(struct xfs_dinode *, - struct xfs_icdinode *); -void xfs_dinode_from_disk(struct xfs_icdinode *, - struct xfs_dinode *); -void xfs_idestroy_fork(struct xfs_inode *, int); -void xfs_idata_realloc(struct xfs_inode *, int, int); -void xfs_iroot_realloc(struct xfs_inode *, int, int); -int xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int); -int xfs_iextents_copy(struct xfs_inode *, xfs_bmbt_rec_t *, int); - -xfs_bmbt_rec_host_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t); -void xfs_iext_insert(struct xfs_inode *, xfs_extnum_t, xfs_extnum_t, - xfs_bmbt_irec_t *, int); -void xfs_iext_add(xfs_ifork_t *, xfs_extnum_t, int); -void xfs_iext_add_indirect_multi(xfs_ifork_t *, int, xfs_extnum_t, int); -void xfs_iext_remove(struct xfs_inode *, xfs_extnum_t, int, int); -void xfs_iext_remove_inline(xfs_ifork_t *, xfs_extnum_t, int); -void xfs_iext_remove_direct(xfs_ifork_t *, xfs_extnum_t, int); -void xfs_iext_remove_indirect(xfs_ifork_t *, xfs_extnum_t, int); -void xfs_iext_realloc_direct(xfs_ifork_t *, int); -void xfs_iext_direct_to_inline(xfs_ifork_t *, xfs_extnum_t); -void xfs_iext_inline_to_direct(xfs_ifork_t *, int); -void xfs_iext_destroy(xfs_ifork_t *); -xfs_bmbt_rec_host_t *xfs_iext_bno_to_ext(xfs_ifork_t *, xfs_fileoff_t, int *); -xfs_ext_irec_t *xfs_iext_bno_to_irec(xfs_ifork_t *, xfs_fileoff_t, int *); -xfs_ext_irec_t *xfs_iext_idx_to_irec(xfs_ifork_t *, xfs_extnum_t *, int *, int); -void xfs_iext_irec_init(xfs_ifork_t *); -xfs_ext_irec_t *xfs_iext_irec_new(xfs_ifork_t *, int); -void xfs_iext_irec_remove(xfs_ifork_t *, int); -void xfs_iext_irec_compact(xfs_ifork_t *); -void xfs_iext_irec_compact_pages(xfs_ifork_t *); -void xfs_iext_irec_compact_full(xfs_ifork_t *); -void xfs_iext_irec_update_extoffs(xfs_ifork_t *, int, int); - -#define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount)) - -#ifdef DEBUG -void xfs_isize_check(struct xfs_mount *, struct xfs_inode *, - xfs_fsize_t); -#else /* DEBUG */ -#define xfs_isize_check(mp, ip, isize) -#endif /* DEBUG */ - -#if defined(DEBUG) -void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *); -#else -#define xfs_inobp_check(mp, bp) -#endif /* DEBUG */ - -extern struct kmem_zone *xfs_ifork_zone; -extern struct kmem_zone *xfs_inode_zone; -extern struct kmem_zone *xfs_ili_zone; - -#endif /* __XFS_INODE_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_inode_item.h xfsprogs-3.2.1ubuntu1/include/xfs_inode_item.h --- xfsprogs-3.1.9ubuntu2/include/xfs_inode_item.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_inode_item.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2000,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_INODE_ITEM_H__ -#define __XFS_INODE_ITEM_H__ - -/* - * This is the structure used to lay out an inode log item in the - * log. The size of the inline data/extents/b-tree root to be logged - * (if any) is indicated in the ilf_dsize field. Changes to this structure - * must be added on to the end. - */ -typedef struct xfs_inode_log_format { - __uint16_t ilf_type; /* inode log item type */ - __uint16_t ilf_size; /* size of this item */ - __uint32_t ilf_fields; /* flags for fields logged */ - __uint16_t ilf_asize; /* size of attr d/ext/root */ - __uint16_t ilf_dsize; /* size of data/ext/root */ - __uint64_t ilf_ino; /* inode number */ - union { - __uint32_t ilfu_rdev; /* rdev value for dev inode*/ - uuid_t ilfu_uuid; /* mount point value */ - } ilf_u; - __int64_t ilf_blkno; /* blkno of inode buffer */ - __int32_t ilf_len; /* len of inode buffer */ - __int32_t ilf_boffset; /* off of inode in buffer */ -} xfs_inode_log_format_t; - -typedef struct xfs_inode_log_format_32 { - __uint16_t ilf_type; /* inode log item type */ - __uint16_t ilf_size; /* size of this item */ - __uint32_t ilf_fields; /* flags for fields logged */ - __uint16_t ilf_asize; /* size of attr d/ext/root */ - __uint16_t ilf_dsize; /* size of data/ext/root */ - __uint64_t ilf_ino; /* inode number */ - union { - __uint32_t ilfu_rdev; /* rdev value for dev inode*/ - uuid_t ilfu_uuid; /* mount point value */ - } ilf_u; - __int64_t ilf_blkno; /* blkno of inode buffer */ - __int32_t ilf_len; /* len of inode buffer */ - __int32_t ilf_boffset; /* off of inode in buffer */ -} __attribute__((packed)) xfs_inode_log_format_32_t; - -typedef struct xfs_inode_log_format_64 { - __uint16_t ilf_type; /* inode log item type */ - __uint16_t ilf_size; /* size of this item */ - __uint32_t ilf_fields; /* flags for fields logged */ - __uint16_t ilf_asize; /* size of attr d/ext/root */ - __uint16_t ilf_dsize; /* size of data/ext/root */ - __uint32_t ilf_pad; /* pad for 64 bit boundary */ - __uint64_t ilf_ino; /* inode number */ - union { - __uint32_t ilfu_rdev; /* rdev value for dev inode*/ - uuid_t ilfu_uuid; /* mount point value */ - } ilf_u; - __int64_t ilf_blkno; /* blkno of inode buffer */ - __int32_t ilf_len; /* len of inode buffer */ - __int32_t ilf_boffset; /* off of inode in buffer */ -} xfs_inode_log_format_64_t; - -/* - * Flags for xfs_trans_log_inode flags field. - */ -#define XFS_ILOG_CORE 0x001 /* log standard inode fields */ -#define XFS_ILOG_DDATA 0x002 /* log i_df.if_data */ -#define XFS_ILOG_DEXT 0x004 /* log i_df.if_extents */ -#define XFS_ILOG_DBROOT 0x008 /* log i_df.i_broot */ -#define XFS_ILOG_DEV 0x010 /* log the dev field */ -#define XFS_ILOG_UUID 0x020 /* log the uuid field */ -#define XFS_ILOG_ADATA 0x040 /* log i_af.if_data */ -#define XFS_ILOG_AEXT 0x080 /* log i_af.if_extents */ -#define XFS_ILOG_ABROOT 0x100 /* log i_af.i_broot */ - -#define XFS_ILOG_NONCORE (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \ - XFS_ILOG_DBROOT | XFS_ILOG_DEV | \ - XFS_ILOG_UUID | XFS_ILOG_ADATA | \ - XFS_ILOG_AEXT | XFS_ILOG_ABROOT) - -#define XFS_ILOG_DFORK (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \ - XFS_ILOG_DBROOT) - -#define XFS_ILOG_AFORK (XFS_ILOG_ADATA | XFS_ILOG_AEXT | \ - XFS_ILOG_ABROOT) - -#define XFS_ILOG_ALL (XFS_ILOG_CORE | XFS_ILOG_DDATA | \ - XFS_ILOG_DEXT | XFS_ILOG_DBROOT | \ - XFS_ILOG_DEV | XFS_ILOG_UUID | \ - XFS_ILOG_ADATA | XFS_ILOG_AEXT | \ - XFS_ILOG_ABROOT) - -static inline int xfs_ilog_fbroot(int w) -{ - return (w == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT); -} - -static inline int xfs_ilog_fext(int w) -{ - return (w == XFS_DATA_FORK ? XFS_ILOG_DEXT : XFS_ILOG_AEXT); -} - -static inline int xfs_ilog_fdata(int w) -{ - return (w == XFS_DATA_FORK ? XFS_ILOG_DDATA : XFS_ILOG_ADATA); -} - -#ifdef __KERNEL__ - -struct xfs_buf; -struct xfs_bmbt_rec; -struct xfs_inode; -struct xfs_mount; - - -typedef struct xfs_inode_log_item { - xfs_log_item_t ili_item; /* common portion */ - struct xfs_inode *ili_inode; /* inode ptr */ - xfs_lsn_t ili_flush_lsn; /* lsn at last flush */ - xfs_lsn_t ili_last_lsn; /* lsn at last transaction */ - unsigned short ili_lock_flags; /* lock flags */ - unsigned short ili_logged; /* flushed logged data */ - unsigned int ili_last_fields; /* fields when flushed */ - struct xfs_bmbt_rec *ili_extents_buf; /* array of logged - data exts */ - struct xfs_bmbt_rec *ili_aextents_buf; /* array of logged - attr exts */ -#ifdef XFS_TRANS_DEBUG - int ili_root_size; - char *ili_orig_root; -#endif - xfs_inode_log_format_t ili_format; /* logged structure */ -} xfs_inode_log_item_t; - - -static inline int xfs_inode_clean(xfs_inode_t *ip) -{ - return (!ip->i_itemp || - !(ip->i_itemp->ili_format.ilf_fields & XFS_ILOG_ALL)) && - !ip->i_update_core; -} - -extern void xfs_inode_item_init(struct xfs_inode *, struct xfs_mount *); -extern void xfs_inode_item_destroy(struct xfs_inode *); -extern void xfs_iflush_done(struct xfs_buf *, struct xfs_log_item *); -extern void xfs_istale_done(struct xfs_buf *, struct xfs_log_item *); -extern void xfs_iflush_abort(struct xfs_inode *); -extern int xfs_inode_item_format_convert(xfs_log_iovec_t *, - xfs_inode_log_format_t *); - -#endif /* __KERNEL__ */ - -#endif /* __XFS_INODE_ITEM_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_inum.h xfsprogs-3.2.1ubuntu1/include/xfs_inum.h --- xfsprogs-3.1.9ubuntu2/include/xfs_inum.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_inum.h 2013-06-06 22:52:59.000000000 +0000 @@ -26,22 +26,6 @@ * high agno_log-agblklog-inopblog bits - 0 */ -typedef __uint32_t xfs_agino_t; /* within allocation grp inode number */ - -/* - * Useful inode bits for this kernel. - * Used in some places where having 64-bits in the 32-bit kernels - * costs too much. - */ -#if XFS_BIG_INUMS -typedef xfs_ino_t xfs_intino_t; -#else -typedef __uint32_t xfs_intino_t; -#endif - -#define NULLFSINO ((xfs_ino_t)-1) -#define NULLAGINO ((xfs_agino_t)-1) - struct xfs_mount; #define XFS_INO_MASK(k) (__uint32_t)((1ULL << (k)) - 1) diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_log_format.h xfsprogs-3.2.1ubuntu1/include/xfs_log_format.h --- xfsprogs-3.1.9ubuntu2/include/xfs_log_format.h 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_log_format.h 2014-05-02 00:09:15.000000000 +0000 @@ -0,0 +1,679 @@ +/* + * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_LOG_FORMAT_H__ +#define __XFS_LOG_FORMAT_H__ + +struct xfs_mount; +struct xfs_trans_res; + +/* + * On-disk Log Format definitions. + * + * This file contains all the on-disk format definitions used within the log. It + * includes the physical log structure itself, as well as all the log item + * format structures that are written into the log and intepreted by log + * recovery. We start with the physical log format definitions, and then work + * through all the log items definitions and everything they encode into the + * log. + */ +typedef __uint32_t xlog_tid_t; + +#define XLOG_MIN_ICLOGS 2 +#define XLOG_MAX_ICLOGS 8 +#define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe /* Invalid cycle number */ +#define XLOG_VERSION_1 1 +#define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */ +#define XLOG_VERSION_OKBITS (XLOG_VERSION_1 | XLOG_VERSION_2) +#define XLOG_MIN_RECORD_BSIZE (16*1024) /* eventually 32k */ +#define XLOG_BIG_RECORD_BSIZE (32*1024) /* 32k buffers */ +#define XLOG_MAX_RECORD_BSIZE (256*1024) +#define XLOG_HEADER_CYCLE_SIZE (32*1024) /* cycle data in header */ +#define XLOG_MIN_RECORD_BSHIFT 14 /* 16384 == 1 << 14 */ +#define XLOG_BIG_RECORD_BSHIFT 15 /* 32k == 1 << 15 */ +#define XLOG_MAX_RECORD_BSHIFT 18 /* 256k == 1 << 18 */ +#define XLOG_BTOLSUNIT(log, b) (((b)+(log)->l_mp->m_sb.sb_logsunit-1) / \ + (log)->l_mp->m_sb.sb_logsunit) +#define XLOG_LSUNITTOB(log, su) ((su) * (log)->l_mp->m_sb.sb_logsunit) + +#define XLOG_HEADER_SIZE 512 + +/* Minimum number of transactions that must fit in the log (defined by mkfs) */ +#define XFS_MIN_LOG_FACTOR 3 + +#define XLOG_REC_SHIFT(log) \ + BTOBB(1 << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \ + XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) +#define XLOG_TOTAL_REC_SHIFT(log) \ + BTOBB(XLOG_MAX_ICLOGS << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \ + XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) + +/* get lsn fields */ +#define CYCLE_LSN(lsn) ((uint)((lsn)>>32)) +#define BLOCK_LSN(lsn) ((uint)(lsn)) + +/* this is used in a spot where we might otherwise double-endian-flip */ +#define CYCLE_LSN_DISK(lsn) (((__be32 *)&(lsn))[0]) + +static inline xfs_lsn_t xlog_assign_lsn(uint cycle, uint block) +{ + return ((xfs_lsn_t)cycle << 32) | block; +} + +static inline uint xlog_get_cycle(char *ptr) +{ + if (be32_to_cpu(*(__be32 *)ptr) == XLOG_HEADER_MAGIC_NUM) + return be32_to_cpu(*((__be32 *)ptr + 1)); + else + return be32_to_cpu(*(__be32 *)ptr); +} + +/* Log Clients */ +#define XFS_TRANSACTION 0x69 +#define XFS_VOLUME 0x2 +#define XFS_LOG 0xaa + +#define XLOG_UNMOUNT_TYPE 0x556e /* Un for Unmount */ + +/* Region types for iovec's i_type */ +#define XLOG_REG_TYPE_BFORMAT 1 +#define XLOG_REG_TYPE_BCHUNK 2 +#define XLOG_REG_TYPE_EFI_FORMAT 3 +#define XLOG_REG_TYPE_EFD_FORMAT 4 +#define XLOG_REG_TYPE_IFORMAT 5 +#define XLOG_REG_TYPE_ICORE 6 +#define XLOG_REG_TYPE_IEXT 7 +#define XLOG_REG_TYPE_IBROOT 8 +#define XLOG_REG_TYPE_ILOCAL 9 +#define XLOG_REG_TYPE_IATTR_EXT 10 +#define XLOG_REG_TYPE_IATTR_BROOT 11 +#define XLOG_REG_TYPE_IATTR_LOCAL 12 +#define XLOG_REG_TYPE_QFORMAT 13 +#define XLOG_REG_TYPE_DQUOT 14 +#define XLOG_REG_TYPE_QUOTAOFF 15 +#define XLOG_REG_TYPE_LRHEADER 16 +#define XLOG_REG_TYPE_UNMOUNT 17 +#define XLOG_REG_TYPE_COMMIT 18 +#define XLOG_REG_TYPE_TRANSHDR 19 +#define XLOG_REG_TYPE_ICREATE 20 +#define XLOG_REG_TYPE_MAX 20 + +/* + * Flags to log operation header + * + * The first write of a new transaction will be preceded with a start + * record, XLOG_START_TRANS. Once a transaction is committed, a commit + * record is written, XLOG_COMMIT_TRANS. If a single region can not fit into + * the remainder of the current active in-core log, it is split up into + * multiple regions. Each partial region will be marked with a + * XLOG_CONTINUE_TRANS until the last one, which gets marked with XLOG_END_TRANS. + * + */ +#define XLOG_START_TRANS 0x01 /* Start a new transaction */ +#define XLOG_COMMIT_TRANS 0x02 /* Commit this transaction */ +#define XLOG_CONTINUE_TRANS 0x04 /* Cont this trans into new region */ +#define XLOG_WAS_CONT_TRANS 0x08 /* Cont this trans into new region */ +#define XLOG_END_TRANS 0x10 /* End a continued transaction */ +#define XLOG_UNMOUNT_TRANS 0x20 /* Unmount a filesystem transaction */ + + +typedef struct xlog_op_header { + __be32 oh_tid; /* transaction id of operation : 4 b */ + __be32 oh_len; /* bytes in data region : 4 b */ + __u8 oh_clientid; /* who sent me this : 1 b */ + __u8 oh_flags; /* : 1 b */ + __u16 oh_res2; /* 32 bit align : 2 b */ +} xlog_op_header_t; + +/* valid values for h_fmt */ +#define XLOG_FMT_UNKNOWN 0 +#define XLOG_FMT_LINUX_LE 1 +#define XLOG_FMT_LINUX_BE 2 +#define XLOG_FMT_IRIX_BE 3 + +/* our fmt */ +#ifdef XFS_NATIVE_HOST +#define XLOG_FMT XLOG_FMT_LINUX_BE +#else +#define XLOG_FMT XLOG_FMT_LINUX_LE +#endif + +typedef struct xlog_rec_header { + __be32 h_magicno; /* log record (LR) identifier : 4 */ + __be32 h_cycle; /* write cycle of log : 4 */ + __be32 h_version; /* LR version : 4 */ + __be32 h_len; /* len in bytes; should be 64-bit aligned: 4 */ + __be64 h_lsn; /* lsn of this LR : 8 */ + __be64 h_tail_lsn; /* lsn of 1st LR w/ buffers not committed: 8 */ + __le32 h_crc; /* crc of log record : 4 */ + __be32 h_prev_block; /* block number to previous LR : 4 */ + __be32 h_num_logops; /* number of log operations in this LR : 4 */ + __be32 h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; + /* new fields */ + __be32 h_fmt; /* format of log record : 4 */ + uuid_t h_fs_uuid; /* uuid of FS : 16 */ + __be32 h_size; /* iclog size : 4 */ +} xlog_rec_header_t; + +typedef struct xlog_rec_ext_header { + __be32 xh_cycle; /* write cycle of log : 4 */ + __be32 xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /* : 256 */ +} xlog_rec_ext_header_t; + +/* + * Quite misnamed, because this union lays out the actual on-disk log buffer. + */ +typedef union xlog_in_core2 { + xlog_rec_header_t hic_header; + xlog_rec_ext_header_t hic_xheader; + char hic_sector[XLOG_HEADER_SIZE]; +} xlog_in_core_2_t; + +/* not an on-disk structure, but needed by log recovery in userspace */ +typedef struct xfs_log_iovec { + void *i_addr; /* beginning address of region */ + int i_len; /* length in bytes of region */ + uint i_type; /* type of region */ +} xfs_log_iovec_t; + + +/* + * Transaction Header definitions. + * + * This is the structure written in the log at the head of every transaction. It + * identifies the type and id of the transaction, and contains the number of + * items logged by the transaction so we know how many to expect during + * recovery. + * + * Do not change the below structure without redoing the code in + * xlog_recover_add_to_trans() and xlog_recover_add_to_cont_trans(). + */ +typedef struct xfs_trans_header { + uint th_magic; /* magic number */ + uint th_type; /* transaction type */ + __int32_t th_tid; /* transaction id (unused) */ + uint th_num_items; /* num items logged by trans */ +} xfs_trans_header_t; + +#define XFS_TRANS_HEADER_MAGIC 0x5452414e /* TRAN */ + +/* + * Log item types. + */ +#define XFS_LI_EFI 0x1236 +#define XFS_LI_EFD 0x1237 +#define XFS_LI_IUNLINK 0x1238 +#define XFS_LI_INODE 0x123b /* aligned ino chunks, var-size ibufs */ +#define XFS_LI_BUF 0x123c /* v2 bufs, variable sized inode bufs */ +#define XFS_LI_DQUOT 0x123d +#define XFS_LI_QUOTAOFF 0x123e +#define XFS_LI_ICREATE 0x123f + +#define XFS_LI_TYPE_DESC \ + { XFS_LI_EFI, "XFS_LI_EFI" }, \ + { XFS_LI_EFD, "XFS_LI_EFD" }, \ + { XFS_LI_IUNLINK, "XFS_LI_IUNLINK" }, \ + { XFS_LI_INODE, "XFS_LI_INODE" }, \ + { XFS_LI_BUF, "XFS_LI_BUF" }, \ + { XFS_LI_DQUOT, "XFS_LI_DQUOT" }, \ + { XFS_LI_QUOTAOFF, "XFS_LI_QUOTAOFF" }, \ + { XFS_LI_ICREATE, "XFS_LI_ICREATE" } + +/* + * Inode Log Item Format definitions. + * + * This is the structure used to lay out an inode log item in the + * log. The size of the inline data/extents/b-tree root to be logged + * (if any) is indicated in the ilf_dsize field. Changes to this structure + * must be added on to the end. + */ +typedef struct xfs_inode_log_format { + __uint16_t ilf_type; /* inode log item type */ + __uint16_t ilf_size; /* size of this item */ + __uint32_t ilf_fields; /* flags for fields logged */ + __uint16_t ilf_asize; /* size of attr d/ext/root */ + __uint16_t ilf_dsize; /* size of data/ext/root */ + __uint64_t ilf_ino; /* inode number */ + union { + __uint32_t ilfu_rdev; /* rdev value for dev inode*/ + uuid_t ilfu_uuid; /* mount point value */ + } ilf_u; + __int64_t ilf_blkno; /* blkno of inode buffer */ + __int32_t ilf_len; /* len of inode buffer */ + __int32_t ilf_boffset; /* off of inode in buffer */ +} xfs_inode_log_format_t; + +typedef struct xfs_inode_log_format_32 { + __uint16_t ilf_type; /* inode log item type */ + __uint16_t ilf_size; /* size of this item */ + __uint32_t ilf_fields; /* flags for fields logged */ + __uint16_t ilf_asize; /* size of attr d/ext/root */ + __uint16_t ilf_dsize; /* size of data/ext/root */ + __uint64_t ilf_ino; /* inode number */ + union { + __uint32_t ilfu_rdev; /* rdev value for dev inode*/ + uuid_t ilfu_uuid; /* mount point value */ + } ilf_u; + __int64_t ilf_blkno; /* blkno of inode buffer */ + __int32_t ilf_len; /* len of inode buffer */ + __int32_t ilf_boffset; /* off of inode in buffer */ +} __attribute__((packed)) xfs_inode_log_format_32_t; + +typedef struct xfs_inode_log_format_64 { + __uint16_t ilf_type; /* inode log item type */ + __uint16_t ilf_size; /* size of this item */ + __uint32_t ilf_fields; /* flags for fields logged */ + __uint16_t ilf_asize; /* size of attr d/ext/root */ + __uint16_t ilf_dsize; /* size of data/ext/root */ + __uint32_t ilf_pad; /* pad for 64 bit boundary */ + __uint64_t ilf_ino; /* inode number */ + union { + __uint32_t ilfu_rdev; /* rdev value for dev inode*/ + uuid_t ilfu_uuid; /* mount point value */ + } ilf_u; + __int64_t ilf_blkno; /* blkno of inode buffer */ + __int32_t ilf_len; /* len of inode buffer */ + __int32_t ilf_boffset; /* off of inode in buffer */ +} xfs_inode_log_format_64_t; + +/* + * Flags for xfs_trans_log_inode flags field. + */ +#define XFS_ILOG_CORE 0x001 /* log standard inode fields */ +#define XFS_ILOG_DDATA 0x002 /* log i_df.if_data */ +#define XFS_ILOG_DEXT 0x004 /* log i_df.if_extents */ +#define XFS_ILOG_DBROOT 0x008 /* log i_df.i_broot */ +#define XFS_ILOG_DEV 0x010 /* log the dev field */ +#define XFS_ILOG_UUID 0x020 /* log the uuid field */ +#define XFS_ILOG_ADATA 0x040 /* log i_af.if_data */ +#define XFS_ILOG_AEXT 0x080 /* log i_af.if_extents */ +#define XFS_ILOG_ABROOT 0x100 /* log i_af.i_broot */ +#define XFS_ILOG_DOWNER 0x200 /* change the data fork owner on replay */ +#define XFS_ILOG_AOWNER 0x400 /* change the attr fork owner on replay */ + + +/* + * The timestamps are dirty, but not necessarily anything else in the inode + * core. Unlike the other fields above this one must never make it to disk + * in the ilf_fields of the inode_log_format, but is purely store in-memory in + * ili_fields in the inode_log_item. + */ +#define XFS_ILOG_TIMESTAMP 0x4000 + +#define XFS_ILOG_NONCORE (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \ + XFS_ILOG_DBROOT | XFS_ILOG_DEV | \ + XFS_ILOG_UUID | XFS_ILOG_ADATA | \ + XFS_ILOG_AEXT | XFS_ILOG_ABROOT | \ + XFS_ILOG_DOWNER | XFS_ILOG_AOWNER) + +#define XFS_ILOG_DFORK (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \ + XFS_ILOG_DBROOT) + +#define XFS_ILOG_AFORK (XFS_ILOG_ADATA | XFS_ILOG_AEXT | \ + XFS_ILOG_ABROOT) + +#define XFS_ILOG_ALL (XFS_ILOG_CORE | XFS_ILOG_DDATA | \ + XFS_ILOG_DEXT | XFS_ILOG_DBROOT | \ + XFS_ILOG_DEV | XFS_ILOG_UUID | \ + XFS_ILOG_ADATA | XFS_ILOG_AEXT | \ + XFS_ILOG_ABROOT | XFS_ILOG_TIMESTAMP | \ + XFS_ILOG_DOWNER | XFS_ILOG_AOWNER) + +static inline int xfs_ilog_fbroot(int w) +{ + return (w == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT); +} + +static inline int xfs_ilog_fext(int w) +{ + return (w == XFS_DATA_FORK ? XFS_ILOG_DEXT : XFS_ILOG_AEXT); +} + +static inline int xfs_ilog_fdata(int w) +{ + return (w == XFS_DATA_FORK ? XFS_ILOG_DDATA : XFS_ILOG_ADATA); +} + +/* + * Incore version of the on-disk inode core structures. We log this directly + * into the journal in host CPU format (for better or worse) and as such + * directly mirrors the xfs_dinode structure as it must contain all the same + * information. + */ +typedef struct xfs_ictimestamp { + __int32_t t_sec; /* timestamp seconds */ + __int32_t t_nsec; /* timestamp nanoseconds */ +} xfs_ictimestamp_t; + +/* + * NOTE: This structure must be kept identical to struct xfs_dinode + * in xfs_dinode.h except for the endianness annotations. + */ +typedef struct xfs_icdinode { + __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ + __uint16_t di_mode; /* mode and type of file */ + __int8_t di_version; /* inode version */ + __int8_t di_format; /* format of di_c data */ + __uint16_t di_onlink; /* old number of links to file */ + __uint32_t di_uid; /* owner's user id */ + __uint32_t di_gid; /* owner's group id */ + __uint32_t di_nlink; /* number of links to file */ + __uint16_t di_projid_lo; /* lower part of owner's project id */ + __uint16_t di_projid_hi; /* higher part of owner's project id */ + __uint8_t di_pad[6]; /* unused, zeroed space */ + __uint16_t di_flushiter; /* incremented on flush */ + xfs_ictimestamp_t di_atime; /* time last accessed */ + xfs_ictimestamp_t di_mtime; /* time last modified */ + xfs_ictimestamp_t di_ctime; /* time created/inode modified */ + xfs_fsize_t di_size; /* number of bytes in file */ + xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */ + xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ + xfs_extnum_t di_nextents; /* number of extents in data fork */ + xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ + __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ + __int8_t di_aformat; /* format of attr fork's data */ + __uint32_t di_dmevmask; /* DMIG event mask */ + __uint16_t di_dmstate; /* DMIG state info */ + __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ + __uint32_t di_gen; /* generation number */ + + /* di_next_unlinked is the only non-core field in the old dinode */ + xfs_agino_t di_next_unlinked;/* agi unlinked list ptr */ + + /* start of the extended dinode, writable fields */ + __uint32_t di_crc; /* CRC of the inode */ + __uint64_t di_changecount; /* number of attribute changes */ + xfs_lsn_t di_lsn; /* flush sequence */ + __uint64_t di_flags2; /* more random flags */ + __uint8_t di_pad2[16]; /* more padding for future expansion */ + + /* fields only written to during inode creation */ + xfs_ictimestamp_t di_crtime; /* time created */ + xfs_ino_t di_ino; /* inode number */ + uuid_t di_uuid; /* UUID of the filesystem */ + + /* structure must be padded to 64 bit alignment */ +} xfs_icdinode_t; + +static inline uint xfs_icdinode_size(int version) +{ + if (version == 3) + return sizeof(struct xfs_icdinode); + return offsetof(struct xfs_icdinode, di_next_unlinked); +} + +/* + * Buffer Log Format defintions + * + * These are the physical dirty bitmap defintions for the log format structure. + */ +#define XFS_BLF_CHUNK 128 +#define XFS_BLF_SHIFT 7 +#define BIT_TO_WORD_SHIFT 5 +#define NBWORD (NBBY * sizeof(unsigned int)) + +/* + * This flag indicates that the buffer contains on disk inodes + * and requires special recovery handling. + */ +#define XFS_BLF_INODE_BUF (1<<0) + +/* + * This flag indicates that the buffer should not be replayed + * during recovery because its blocks are being freed. + */ +#define XFS_BLF_CANCEL (1<<1) + +/* + * This flag indicates that the buffer contains on disk + * user or group dquots and may require special recovery handling. + */ +#define XFS_BLF_UDQUOT_BUF (1<<2) +#define XFS_BLF_PDQUOT_BUF (1<<3) +#define XFS_BLF_GDQUOT_BUF (1<<4) + +/* + * This is the structure used to lay out a buf log item in the + * log. The data map describes which 128 byte chunks of the buffer + * have been logged. + */ +#define XFS_BLF_DATAMAP_SIZE ((XFS_MAX_BLOCKSIZE / XFS_BLF_CHUNK) / NBWORD) + +typedef struct xfs_buf_log_format { + unsigned short blf_type; /* buf log item type indicator */ + unsigned short blf_size; /* size of this item */ + ushort blf_flags; /* misc state */ + ushort blf_len; /* number of blocks in this buf */ + __int64_t blf_blkno; /* starting blkno of this buf */ + unsigned int blf_map_size; /* used size of data bitmap in words */ + unsigned int blf_data_map[XFS_BLF_DATAMAP_SIZE]; /* dirty bitmap */ +} xfs_buf_log_format_t; + +/* + * All buffers now need to tell recovery where the magic number + * is so that it can verify and calculate the CRCs on the buffer correctly + * once the changes have been replayed into the buffer. + * + * The type value is held in the upper 5 bits of the blf_flags field, which is + * an unsigned 16 bit field. Hence we need to shift it 11 bits up and down. + */ +#define XFS_BLFT_BITS 5 +#define XFS_BLFT_SHIFT 11 +#define XFS_BLFT_MASK (((1 << XFS_BLFT_BITS) - 1) << XFS_BLFT_SHIFT) + +enum xfs_blft { + XFS_BLFT_UNKNOWN_BUF = 0, + XFS_BLFT_UDQUOT_BUF, + XFS_BLFT_PDQUOT_BUF, + XFS_BLFT_GDQUOT_BUF, + XFS_BLFT_BTREE_BUF, + XFS_BLFT_AGF_BUF, + XFS_BLFT_AGFL_BUF, + XFS_BLFT_AGI_BUF, + XFS_BLFT_DINO_BUF, + XFS_BLFT_SYMLINK_BUF, + XFS_BLFT_DIR_BLOCK_BUF, + XFS_BLFT_DIR_DATA_BUF, + XFS_BLFT_DIR_FREE_BUF, + XFS_BLFT_DIR_LEAF1_BUF, + XFS_BLFT_DIR_LEAFN_BUF, + XFS_BLFT_DA_NODE_BUF, + XFS_BLFT_ATTR_LEAF_BUF, + XFS_BLFT_ATTR_RMT_BUF, + XFS_BLFT_SB_BUF, + XFS_BLFT_MAX_BUF = (1 << XFS_BLFT_BITS), +}; + +static inline void +xfs_blft_to_flags(struct xfs_buf_log_format *blf, enum xfs_blft type) +{ + ASSERT(type > XFS_BLFT_UNKNOWN_BUF && type < XFS_BLFT_MAX_BUF); + blf->blf_flags &= ~XFS_BLFT_MASK; + blf->blf_flags |= ((type << XFS_BLFT_SHIFT) & XFS_BLFT_MASK); +} + +static inline __uint16_t +xfs_blft_from_flags(struct xfs_buf_log_format *blf) +{ + return (blf->blf_flags & XFS_BLFT_MASK) >> XFS_BLFT_SHIFT; +} + +/* + * EFI/EFD log format definitions + */ +typedef struct xfs_extent { + xfs_dfsbno_t ext_start; + xfs_extlen_t ext_len; +} xfs_extent_t; + +/* + * Since an xfs_extent_t has types (start:64, len: 32) + * there are different alignments on 32 bit and 64 bit kernels. + * So we provide the different variants for use by a + * conversion routine. + */ +typedef struct xfs_extent_32 { + __uint64_t ext_start; + __uint32_t ext_len; +} __attribute__((packed)) xfs_extent_32_t; + +typedef struct xfs_extent_64 { + __uint64_t ext_start; + __uint32_t ext_len; + __uint32_t ext_pad; +} xfs_extent_64_t; + +/* + * This is the structure used to lay out an efi log item in the + * log. The efi_extents field is a variable size array whose + * size is given by efi_nextents. + */ +typedef struct xfs_efi_log_format { + __uint16_t efi_type; /* efi log item type */ + __uint16_t efi_size; /* size of this item */ + __uint32_t efi_nextents; /* # extents to free */ + __uint64_t efi_id; /* efi identifier */ + xfs_extent_t efi_extents[1]; /* array of extents to free */ +} xfs_efi_log_format_t; + +typedef struct xfs_efi_log_format_32 { + __uint16_t efi_type; /* efi log item type */ + __uint16_t efi_size; /* size of this item */ + __uint32_t efi_nextents; /* # extents to free */ + __uint64_t efi_id; /* efi identifier */ + xfs_extent_32_t efi_extents[1]; /* array of extents to free */ +} __attribute__((packed)) xfs_efi_log_format_32_t; + +typedef struct xfs_efi_log_format_64 { + __uint16_t efi_type; /* efi log item type */ + __uint16_t efi_size; /* size of this item */ + __uint32_t efi_nextents; /* # extents to free */ + __uint64_t efi_id; /* efi identifier */ + xfs_extent_64_t efi_extents[1]; /* array of extents to free */ +} xfs_efi_log_format_64_t; + +/* + * This is the structure used to lay out an efd log item in the + * log. The efd_extents array is a variable size array whose + * size is given by efd_nextents; + */ +typedef struct xfs_efd_log_format { + __uint16_t efd_type; /* efd log item type */ + __uint16_t efd_size; /* size of this item */ + __uint32_t efd_nextents; /* # of extents freed */ + __uint64_t efd_efi_id; /* id of corresponding efi */ + xfs_extent_t efd_extents[1]; /* array of extents freed */ +} xfs_efd_log_format_t; + +typedef struct xfs_efd_log_format_32 { + __uint16_t efd_type; /* efd log item type */ + __uint16_t efd_size; /* size of this item */ + __uint32_t efd_nextents; /* # of extents freed */ + __uint64_t efd_efi_id; /* id of corresponding efi */ + xfs_extent_32_t efd_extents[1]; /* array of extents freed */ +} __attribute__((packed)) xfs_efd_log_format_32_t; + +typedef struct xfs_efd_log_format_64 { + __uint16_t efd_type; /* efd log item type */ + __uint16_t efd_size; /* size of this item */ + __uint32_t efd_nextents; /* # of extents freed */ + __uint64_t efd_efi_id; /* id of corresponding efi */ + xfs_extent_64_t efd_extents[1]; /* array of extents freed */ +} xfs_efd_log_format_64_t; + +/* + * Dquot Log format definitions. + * + * The first two fields must be the type and size fitting into + * 32 bits : log_recovery code assumes that. + */ +typedef struct xfs_dq_logformat { + __uint16_t qlf_type; /* dquot log item type */ + __uint16_t qlf_size; /* size of this item */ + xfs_dqid_t qlf_id; /* usr/grp/proj id : 32 bits */ + __int64_t qlf_blkno; /* blkno of dquot buffer */ + __int32_t qlf_len; /* len of dquot buffer */ + __uint32_t qlf_boffset; /* off of dquot in buffer */ +} xfs_dq_logformat_t; + +/* + * log format struct for QUOTAOFF records. + * The first two fields must be the type and size fitting into + * 32 bits : log_recovery code assumes that. + * We write two LI_QUOTAOFF logitems per quotaoff, the last one keeps a pointer + * to the first and ensures that the first logitem is taken out of the AIL + * only when the last one is securely committed. + */ +typedef struct xfs_qoff_logformat { + unsigned short qf_type; /* quotaoff log item type */ + unsigned short qf_size; /* size of this item */ + unsigned int qf_flags; /* USR and/or GRP */ + char qf_pad[12]; /* padding for future */ +} xfs_qoff_logformat_t; + +/* + * Disk quotas status in m_qflags, and also sb_qflags. 16 bits. + */ +#define XFS_UQUOTA_ACCT 0x0001 /* user quota accounting ON */ +#define XFS_UQUOTA_ENFD 0x0002 /* user quota limits enforced */ +#define XFS_UQUOTA_CHKD 0x0004 /* quotacheck run on usr quotas */ +#define XFS_PQUOTA_ACCT 0x0008 /* project quota accounting ON */ +#define XFS_OQUOTA_ENFD 0x0010 /* other (grp/prj) quota limits enforced */ +#define XFS_OQUOTA_CHKD 0x0020 /* quotacheck run on other (grp/prj) quotas */ +#define XFS_GQUOTA_ACCT 0x0040 /* group quota accounting ON */ + +/* + * Conversion to and from the combined OQUOTA flag (if necessary) + * is done only in xfs_sb_qflags_to_disk() and xfs_sb_qflags_from_disk() + */ +#define XFS_GQUOTA_ENFD 0x0080 /* group quota limits enforced */ +#define XFS_GQUOTA_CHKD 0x0100 /* quotacheck run on group quotas */ +#define XFS_PQUOTA_ENFD 0x0200 /* project quota limits enforced */ +#define XFS_PQUOTA_CHKD 0x0400 /* quotacheck run on project quotas */ + +#define XFS_ALL_QUOTA_ACCT \ + (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT) +#define XFS_ALL_QUOTA_ENFD \ + (XFS_UQUOTA_ENFD | XFS_GQUOTA_ENFD | XFS_PQUOTA_ENFD) +#define XFS_ALL_QUOTA_CHKD \ + (XFS_UQUOTA_CHKD | XFS_GQUOTA_CHKD | XFS_PQUOTA_CHKD) + +#define XFS_MOUNT_QUOTA_ALL (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ + XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\ + XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD|\ + XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD|\ + XFS_PQUOTA_CHKD) + +/* + * Inode create log item structure + * + * Log recovery assumes the first two entries are the type and size and they fit + * in 32 bits. Also in host order (ugh) so they have to be 32 bit aligned so + * decoding can be done correctly. + */ +struct xfs_icreate_log { + __uint16_t icl_type; /* type of log format structure */ + __uint16_t icl_size; /* size of log format structure */ + __be32 icl_ag; /* ag being allocated in */ + __be32 icl_agbno; /* start block of inode range */ + __be32 icl_count; /* number of inodes to initialise */ + __be32 icl_isize; /* size of inodes */ + __be32 icl_length; /* length of extent to initialise */ + __be32 icl_gen; /* inode generation number to use */ +}; + +#endif /* __XFS_LOG_FORMAT_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_log.h xfsprogs-3.2.1ubuntu1/include/xfs_log.h --- xfsprogs-3.1.9ubuntu2/include/xfs_log.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_log.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_LOG_H__ -#define __XFS_LOG_H__ - -/* get lsn fields */ -#define CYCLE_LSN(lsn) ((uint)((lsn)>>32)) -#define BLOCK_LSN(lsn) ((uint)(lsn)) - -/* this is used in a spot where we might otherwise double-endian-flip */ -#define CYCLE_LSN_DISK(lsn) (((__be32 *)&(lsn))[0]) - -#ifdef __KERNEL__ -/* - * By comparing each component, we don't have to worry about extra - * endian issues in treating two 32 bit numbers as one 64 bit number - */ -static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) -{ - if (CYCLE_LSN(lsn1) != CYCLE_LSN(lsn2)) - return (CYCLE_LSN(lsn1)l_mp->m_sb.sb_logsunit-1) / \ - (log)->l_mp->m_sb.sb_logsunit) -#define XLOG_LSUNITTOB(log, su) ((su) * (log)->l_mp->m_sb.sb_logsunit) - -#define XLOG_HEADER_SIZE 512 - -#define XLOG_REC_SHIFT(log) \ - BTOBB(1 << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \ - XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) -#define XLOG_TOTAL_REC_SHIFT(log) \ - BTOBB(XLOG_MAX_ICLOGS << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \ - XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) - -static inline xfs_lsn_t xlog_assign_lsn(uint cycle, uint block) -{ - return ((xfs_lsn_t)cycle << 32) | block; -} - -static inline uint xlog_get_cycle(char *ptr) -{ - if (be32_to_cpu(*(__be32 *)ptr) == XLOG_HEADER_MAGIC_NUM) - return be32_to_cpu(*((__be32 *)ptr + 1)); - else - return be32_to_cpu(*(__be32 *)ptr); -} - -#define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1) - -#ifdef __KERNEL__ - -/* - * get client id from packed copy. - * - * this hack is here because the xlog_pack code copies four bytes - * of xlog_op_header containing the fields oh_clientid, oh_flags - * and oh_res2 into the packed copy. - * - * later on this four byte chunk is treated as an int and the - * client id is pulled out. - * - * this has endian issues, of course. - */ -static inline uint xlog_get_client_id(__be32 i) -{ - return be32_to_cpu(i) >> 24; -} - -#define xlog_panic(args...) cmn_err(CE_PANIC, ## args) -#define xlog_exit(args...) cmn_err(CE_PANIC, ## args) -#define xlog_warn(args...) cmn_err(CE_WARN, ## args) - -/* - * In core log state - */ -#define XLOG_STATE_ACTIVE 0x0001 /* Current IC log being written to */ -#define XLOG_STATE_WANT_SYNC 0x0002 /* Want to sync this iclog; no more writes */ -#define XLOG_STATE_SYNCING 0x0004 /* This IC log is syncing */ -#define XLOG_STATE_DONE_SYNC 0x0008 /* Done syncing to disk */ -#define XLOG_STATE_DO_CALLBACK \ - 0x0010 /* Process callback functions */ -#define XLOG_STATE_CALLBACK 0x0020 /* Callback functions now */ -#define XLOG_STATE_DIRTY 0x0040 /* Dirty IC log, not ready for ACTIVE status*/ -#define XLOG_STATE_IOERROR 0x0080 /* IO error happened in sync'ing log */ -#define XLOG_STATE_ALL 0x7FFF /* All possible valid flags */ -#define XLOG_STATE_NOTUSED 0x8000 /* This IC log not being used */ -#endif /* __KERNEL__ */ - -/* - * Flags to log operation header - * - * The first write of a new transaction will be preceded with a start - * record, XLOG_START_TRANS. Once a transaction is committed, a commit - * record is written, XLOG_COMMIT_TRANS. If a single region can not fit into - * the remainder of the current active in-core log, it is split up into - * multiple regions. Each partial region will be marked with a - * XLOG_CONTINUE_TRANS until the last one, which gets marked with XLOG_END_TRANS. - * - */ -#define XLOG_START_TRANS 0x01 /* Start a new transaction */ -#define XLOG_COMMIT_TRANS 0x02 /* Commit this transaction */ -#define XLOG_CONTINUE_TRANS 0x04 /* Cont this trans into new region */ -#define XLOG_WAS_CONT_TRANS 0x08 /* Cont this trans into new region */ -#define XLOG_END_TRANS 0x10 /* End a continued transaction */ -#define XLOG_UNMOUNT_TRANS 0x20 /* Unmount a filesystem transaction */ - -#ifdef __KERNEL__ -/* - * Flags to log ticket - */ -#define XLOG_TIC_INITED 0x1 /* has been initialized */ -#define XLOG_TIC_PERM_RESERV 0x2 /* permanent reservation */ - -#define XLOG_TIC_FLAGS \ - { XLOG_TIC_INITED, "XLOG_TIC_INITED" }, \ - { XLOG_TIC_PERM_RESERV, "XLOG_TIC_PERM_RESERV" } - -#endif /* __KERNEL__ */ - -#define XLOG_UNMOUNT_TYPE 0x556e /* Un for Unmount */ - -/* - * Flags for log structure - */ -#define XLOG_CHKSUM_MISMATCH 0x1 /* used only during recovery */ -#define XLOG_ACTIVE_RECOVERY 0x2 /* in the middle of recovery */ -#define XLOG_RECOVERY_NEEDED 0x4 /* log was recovered */ -#define XLOG_IO_ERROR 0x8 /* log hit an I/O error, and being - shutdown */ - -#ifdef __KERNEL__ -/* - * Below are states for covering allocation transactions. - * By covering, we mean changing the h_tail_lsn in the last on-disk - * log write such that no allocation transactions will be re-done during - * recovery after a system crash. Recovery starts at the last on-disk - * log write. - * - * These states are used to insert dummy log entries to cover - * space allocation transactions which can undo non-transactional changes - * after a crash. Writes to a file with space - * already allocated do not result in any transactions. Allocations - * might include space beyond the EOF. So if we just push the EOF a - * little, the last transaction for the file could contain the wrong - * size. If there is no file system activity, after an allocation - * transaction, and the system crashes, the allocation transaction - * will get replayed and the file will be truncated. This could - * be hours/days/... after the allocation occurred. - * - * The fix for this is to do two dummy transactions when the - * system is idle. We need two dummy transaction because the h_tail_lsn - * in the log record header needs to point beyond the last possible - * non-dummy transaction. The first dummy changes the h_tail_lsn to - * the first transaction before the dummy. The second dummy causes - * h_tail_lsn to point to the first dummy. Recovery starts at h_tail_lsn. - * - * These dummy transactions get committed when everything - * is idle (after there has been some activity). - * - * There are 5 states used to control this. - * - * IDLE -- no logging has been done on the file system or - * we are done covering previous transactions. - * NEED -- logging has occurred and we need a dummy transaction - * when the log becomes idle. - * DONE -- we were in the NEED state and have committed a dummy - * transaction. - * NEED2 -- we detected that a dummy transaction has gone to the - * on disk log with no other transactions. - * DONE2 -- we committed a dummy transaction when in the NEED2 state. - * - * There are two places where we switch states: - * - * 1.) In xfs_sync, when we detect an idle log and are in NEED or NEED2. - * We commit the dummy transaction and switch to DONE or DONE2, - * respectively. In all other states, we don't do anything. - * - * 2.) When we finish writing the on-disk log (xlog_state_clean_log). - * - * No matter what state we are in, if this isn't the dummy - * transaction going out, the next state is NEED. - * So, if we aren't in the DONE or DONE2 states, the next state - * is NEED. We can't be finishing a write of the dummy record - * unless it was committed and the state switched to DONE or DONE2. - * - * If we are in the DONE state and this was a write of the - * dummy transaction, we move to NEED2. - * - * If we are in the DONE2 state and this was a write of the - * dummy transaction, we move to IDLE. - * - * - * Writing only one dummy transaction can get appended to - * one file space allocation. When this happens, the log recovery - * code replays the space allocation and a file could be truncated. - * This is why we have the NEED2 and DONE2 states before going idle. - */ - -#define XLOG_STATE_COVER_IDLE 0 -#define XLOG_STATE_COVER_NEED 1 -#define XLOG_STATE_COVER_DONE 2 -#define XLOG_STATE_COVER_NEED2 3 -#define XLOG_STATE_COVER_DONE2 4 - -#define XLOG_COVER_OPS 5 - - -/* Ticket reservation region accounting */ -#define XLOG_TIC_LEN_MAX 15 - -/* - * Reservation region - * As would be stored in xfs_log_iovec but without the i_addr which - * we don't care about. - */ -typedef struct xlog_res { - uint r_len; /* region length :4 */ - uint r_type; /* region's transaction type :4 */ -} xlog_res_t; - -typedef struct xlog_ticket { - wait_queue_head_t t_wait; /* ticket wait queue */ - struct list_head t_queue; /* reserve/write queue */ - xlog_tid_t t_tid; /* transaction identifier : 4 */ - atomic_t t_ref; /* ticket reference count : 4 */ - int t_curr_res; /* current reservation in bytes : 4 */ - int t_unit_res; /* unit reservation in bytes : 4 */ - char t_ocnt; /* original count : 1 */ - char t_cnt; /* current count : 1 */ - char t_clientid; /* who does this belong to; : 1 */ - char t_flags; /* properties of reservation : 1 */ - uint t_trans_type; /* transaction type : 4 */ - - /* reservation array fields */ - uint t_res_num; /* num in array : 4 */ - uint t_res_num_ophdrs; /* num op hdrs : 4 */ - uint t_res_arr_sum; /* array sum : 4 */ - uint t_res_o_flow; /* sum overflow : 4 */ - xlog_res_t t_res_arr[XLOG_TIC_LEN_MAX]; /* array of res : 8 * 15 */ -} xlog_ticket_t; - -#endif - - -typedef struct xlog_op_header { - __be32 oh_tid; /* transaction id of operation : 4 b */ - __be32 oh_len; /* bytes in data region : 4 b */ - __u8 oh_clientid; /* who sent me this : 1 b */ - __u8 oh_flags; /* : 1 b */ - __u16 oh_res2; /* 32 bit align : 2 b */ -} xlog_op_header_t; - - -/* valid values for h_fmt */ -#define XLOG_FMT_UNKNOWN 0 -#define XLOG_FMT_LINUX_LE 1 -#define XLOG_FMT_LINUX_BE 2 -#define XLOG_FMT_IRIX_BE 3 - -/* our fmt */ -#ifdef XFS_NATIVE_HOST -#define XLOG_FMT XLOG_FMT_LINUX_BE -#else -#define XLOG_FMT XLOG_FMT_LINUX_LE -#endif - -typedef struct xlog_rec_header { - __be32 h_magicno; /* log record (LR) identifier : 4 */ - __be32 h_cycle; /* write cycle of log : 4 */ - __be32 h_version; /* LR version : 4 */ - __be32 h_len; /* len in bytes; should be 64-bit aligned: 4 */ - __be64 h_lsn; /* lsn of this LR : 8 */ - __be64 h_tail_lsn; /* lsn of 1st LR w/ buffers not committed: 8 */ - __be32 h_chksum; /* may not be used; non-zero if used : 4 */ - __be32 h_prev_block; /* block number to previous LR : 4 */ - __be32 h_num_logops; /* number of log operations in this LR : 4 */ - __be32 h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; - /* new fields */ - __be32 h_fmt; /* format of log record : 4 */ - uuid_t h_fs_uuid; /* uuid of FS : 16 */ - __be32 h_size; /* iclog size : 4 */ -} xlog_rec_header_t; - -typedef struct xlog_rec_ext_header { - __be32 xh_cycle; /* write cycle of log : 4 */ - __be32 xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /* : 256 */ -} xlog_rec_ext_header_t; - -#ifdef __KERNEL__ - -/* - * Quite misnamed, because this union lays out the actual on-disk log buffer. - */ -typedef union xlog_in_core2 { - xlog_rec_header_t hic_header; - xlog_rec_ext_header_t hic_xheader; - char hic_sector[XLOG_HEADER_SIZE]; -} xlog_in_core_2_t; - -/* - * - A log record header is 512 bytes. There is plenty of room to grow the - * xlog_rec_header_t into the reserved space. - * - ic_data follows, so a write to disk can start at the beginning of - * the iclog. - * - ic_forcewait is used to implement synchronous forcing of the iclog to disk. - * - ic_next is the pointer to the next iclog in the ring. - * - ic_bp is a pointer to the buffer used to write this incore log to disk. - * - ic_log is a pointer back to the global log structure. - * - ic_callback is a linked list of callback function/argument pairs to be - * called after an iclog finishes writing. - * - ic_size is the full size of the header plus data. - * - ic_offset is the current number of bytes written to in this iclog. - * - ic_refcnt is bumped when someone is writing to the log. - * - ic_state is the state of the iclog. - * - * Because of cacheline contention on large machines, we need to separate - * various resources onto different cachelines. To start with, make the - * structure cacheline aligned. The following fields can be contended on - * by independent processes: - * - * - ic_callback_* - * - ic_refcnt - * - fields protected by the global l_icloglock - * - * so we need to ensure that these fields are located in separate cachelines. - * We'll put all the read-only and l_icloglock fields in the first cacheline, - * and move everything else out to subsequent cachelines. - */ -typedef struct xlog_in_core { - wait_queue_head_t ic_force_wait; - wait_queue_head_t ic_write_wait; - struct xlog_in_core *ic_next; - struct xlog_in_core *ic_prev; - struct xfs_buf *ic_bp; - struct log *ic_log; - int ic_size; - int ic_offset; - int ic_bwritecnt; - unsigned short ic_state; - char *ic_datap; /* pointer to iclog data */ - - /* Callback structures need their own cacheline */ - spinlock_t ic_callback_lock ____cacheline_aligned_in_smp; - xfs_log_callback_t *ic_callback; - xfs_log_callback_t **ic_callback_tail; - - /* reference counts need their own cacheline */ - atomic_t ic_refcnt ____cacheline_aligned_in_smp; - xlog_in_core_2_t *ic_data; -#define ic_header ic_data->hic_header -} xlog_in_core_t; - -/* - * The CIL context is used to aggregate per-transaction details as well be - * passed to the iclog for checkpoint post-commit processing. After being - * passed to the iclog, another context needs to be allocated for tracking the - * next set of transactions to be aggregated into a checkpoint. - */ -struct xfs_cil; - -struct xfs_cil_ctx { - struct xfs_cil *cil; - xfs_lsn_t sequence; /* chkpt sequence # */ - xfs_lsn_t start_lsn; /* first LSN of chkpt commit */ - xfs_lsn_t commit_lsn; /* chkpt commit record lsn */ - struct xlog_ticket *ticket; /* chkpt ticket */ - int nvecs; /* number of regions */ - int space_used; /* aggregate size of regions */ - struct list_head busy_extents; /* busy extents in chkpt */ - struct xfs_log_vec *lv_chain; /* logvecs being pushed */ - xfs_log_callback_t log_cb; /* completion callback hook. */ - struct list_head committing; /* ctx committing list */ -}; - -/* - * Committed Item List structure - * - * This structure is used to track log items that have been committed but not - * yet written into the log. It is used only when the delayed logging mount - * option is enabled. - * - * This structure tracks the list of committing checkpoint contexts so - * we can avoid the problem of having to hold out new transactions during a - * flush until we have a the commit record LSN of the checkpoint. We can - * traverse the list of committing contexts in xlog_cil_push_lsn() to find a - * sequence match and extract the commit LSN directly from there. If the - * checkpoint is still in the process of committing, we can block waiting for - * the commit LSN to be determined as well. This should make synchronous - * operations almost as efficient as the old logging methods. - */ -struct xfs_cil { - struct log *xc_log; - struct list_head xc_cil; - spinlock_t xc_cil_lock; - struct xfs_cil_ctx *xc_ctx; - struct rw_semaphore xc_ctx_lock; - struct list_head xc_committing; - wait_queue_head_t xc_commit_wait; - xfs_lsn_t xc_current_sequence; -}; - -/* - * The amount of log space we allow the CIL to aggregate is difficult to size. - * Whatever we choose, we have to make sure we can get a reservation for the - * log space effectively, that it is large enough to capture sufficient - * relogging to reduce log buffer IO significantly, but it is not too large for - * the log or induces too much latency when writing out through the iclogs. We - * track both space consumed and the number of vectors in the checkpoint - * context, so we need to decide which to use for limiting. - * - * Every log buffer we write out during a push needs a header reserved, which - * is at least one sector and more for v2 logs. Hence we need a reservation of - * at least 512 bytes per 32k of log space just for the LR headers. That means - * 16KB of reservation per megabyte of delayed logging space we will consume, - * plus various headers. The number of headers will vary based on the num of - * io vectors, so limiting on a specific number of vectors is going to result - * in transactions of varying size. IOWs, it is more consistent to track and - * limit space consumed in the log rather than by the number of objects being - * logged in order to prevent checkpoint ticket overruns. - * - * Further, use of static reservations through the log grant mechanism is - * problematic. It introduces a lot of complexity (e.g. reserve grant vs write - * grant) and a significant deadlock potential because regranting write space - * can block on log pushes. Hence if we have to regrant log space during a log - * push, we can deadlock. - * - * However, we can avoid this by use of a dynamic "reservation stealing" - * technique during transaction commit whereby unused reservation space in the - * transaction ticket is transferred to the CIL ctx commit ticket to cover the - * space needed by the checkpoint transaction. This means that we never need to - * specifically reserve space for the CIL checkpoint transaction, nor do we - * need to regrant space once the checkpoint completes. This also means the - * checkpoint transaction ticket is specific to the checkpoint context, rather - * than the CIL itself. - * - * With dynamic reservations, we can effectively make up arbitrary limits for - * the checkpoint size so long as they don't violate any other size rules. - * Recovery imposes a rule that no transaction exceed half the log, so we are - * limited by that. Furthermore, the log transaction reservation subsystem - * tries to keep 25% of the log free, so we need to keep below that limit or we - * risk running out of free log space to start any new transactions. - * - * In order to keep background CIL push efficient, we will set a lower - * threshold at which background pushing is attempted without blocking current - * transaction commits. A separate, higher bound defines when CIL pushes are - * enforced to ensure we stay within our maximum checkpoint size bounds. - * threshold, yet give us plenty of space for aggregation on large logs. - */ -#define XLOG_CIL_SPACE_LIMIT(log) (log->l_logsize >> 3) -#define XLOG_CIL_HARD_SPACE_LIMIT(log) (3 * (log->l_logsize >> 4)) - -/* - * The reservation head lsn is not made up of a cycle number and block number. - * Instead, it uses a cycle number and byte number. Logs don't expect to - * overflow 31 bits worth of byte offset, so using a byte number will mean - * that round off problems won't occur when releasing partial reservations. - */ -typedef struct log { - /* The following fields don't need locking */ - struct xfs_mount *l_mp; /* mount point */ - struct xfs_ail *l_ailp; /* AIL log is working with */ - struct xfs_cil *l_cilp; /* CIL log is working with */ - struct xfs_buf *l_xbuf; /* extra buffer for log - * wrapping */ - struct xfs_buftarg *l_targ; /* buftarg of log */ - uint l_flags; - uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */ - struct list_head *l_buf_cancel_table; - int l_iclog_hsize; /* size of iclog header */ - int l_iclog_heads; /* # of iclog header sectors */ - uint l_sectBBsize; /* sector size in BBs (2^n) */ - int l_iclog_size; /* size of log in bytes */ - int l_iclog_size_log; /* log power size of log */ - int l_iclog_bufs; /* number of iclog buffers */ - xfs_daddr_t l_logBBstart; /* start block of log */ - int l_logsize; /* size of log in bytes */ - int l_logBBsize; /* size of log in BB chunks */ - - /* The following block of fields are changed while holding icloglock */ - wait_queue_head_t l_flush_wait ____cacheline_aligned_in_smp; - /* waiting for iclog flush */ - int l_covered_state;/* state of "covering disk - * log entries" */ - xlog_in_core_t *l_iclog; /* head log queue */ - spinlock_t l_icloglock; /* grab to change iclog state */ - int l_curr_cycle; /* Cycle number of log writes */ - int l_prev_cycle; /* Cycle number before last - * block increment */ - int l_curr_block; /* current logical log block */ - int l_prev_block; /* previous logical log block */ - - /* - * l_last_sync_lsn and l_tail_lsn are atomics so they can be set and - * read without needing to hold specific locks. To avoid operations - * contending with other hot objects, place each of them on a separate - * cacheline. - */ - /* lsn of last LR on disk */ - atomic64_t l_last_sync_lsn ____cacheline_aligned_in_smp; - /* lsn of 1st LR with unflushed * buffers */ - atomic64_t l_tail_lsn ____cacheline_aligned_in_smp; - - /* - * ticket grant locks, queues and accounting have their own cachlines - * as these are quite hot and can be operated on concurrently. - */ - spinlock_t l_grant_reserve_lock ____cacheline_aligned_in_smp; - struct list_head l_reserveq; - atomic64_t l_grant_reserve_head; - - spinlock_t l_grant_write_lock ____cacheline_aligned_in_smp; - struct list_head l_writeq; - atomic64_t l_grant_write_head; - - /* The following field are used for debugging; need to hold icloglock */ -#ifdef DEBUG - char *l_iclog_bak[XLOG_MAX_ICLOGS]; -#endif - -} xlog_t; - -#define XLOG_BUF_CANCEL_BUCKET(log, blkno) \ - ((log)->l_buf_cancel_table + ((__uint64_t)blkno % XLOG_BC_TABLE_SIZE)) - -#define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR) - -/* common routines */ -extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp); -extern int xlog_recover(xlog_t *log); -extern int xlog_recover_finish(xlog_t *log); -extern void xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog, int); - -extern kmem_zone_t *xfs_log_ticket_zone; -struct xlog_ticket *xlog_ticket_alloc(struct log *log, int unit_bytes, - int count, char client, uint xflags, - int alloc_flags); - - -static inline void -xlog_write_adv_cnt(void **ptr, int *len, int *off, size_t bytes) -{ - *ptr += bytes; - *len -= bytes; - *off += bytes; -} - -void xlog_print_tic_res(struct xfs_mount *mp, struct xlog_ticket *ticket); -int xlog_write(struct log *log, struct xfs_log_vec *log_vector, - struct xlog_ticket *tic, xfs_lsn_t *start_lsn, - xlog_in_core_t **commit_iclog, uint flags); - -/* - * When we crack an atomic LSN, we sample it first so that the value will not - * change while we are cracking it into the component values. This means we - * will always get consistent component values to work from. This should always - * be used to smaple and crack LSNs taht are stored and updated in atomic - * variables. - */ -static inline void -xlog_crack_atomic_lsn(atomic64_t *lsn, uint *cycle, uint *block) -{ - xfs_lsn_t val = atomic64_read(lsn); - - *cycle = CYCLE_LSN(val); - *block = BLOCK_LSN(val); -} - -/* - * Calculate and assign a value to an atomic LSN variable from component pieces. - */ -static inline void -xlog_assign_atomic_lsn(atomic64_t *lsn, uint cycle, uint block) -{ - atomic64_set(lsn, xlog_assign_lsn(cycle, block)); -} - -/* - * When we crack the grant head, we sample it first so that the value will not - * change while we are cracking it into the component values. This means we - * will always get consistent component values to work from. - */ -static inline void -xlog_crack_grant_head_val(int64_t val, int *cycle, int *space) -{ - *cycle = val >> 32; - *space = val & 0xffffffff; -} - -static inline void -xlog_crack_grant_head(atomic64_t *head, int *cycle, int *space) -{ - xlog_crack_grant_head_val(atomic64_read(head), cycle, space); -} - -static inline int64_t -xlog_assign_grant_head_val(int cycle, int space) -{ - return ((int64_t)cycle << 32) | space; -} - -static inline void -xlog_assign_grant_head(atomic64_t *head, int cycle, int space) -{ - atomic64_set(head, xlog_assign_grant_head_val(cycle, space)); -} - -/* - * Committed Item List interfaces - */ -int xlog_cil_init(struct log *log); -void xlog_cil_init_post_recovery(struct log *log); -void xlog_cil_destroy(struct log *log); - -/* - * CIL force routines - */ -xfs_lsn_t xlog_cil_force_lsn(struct log *log, xfs_lsn_t sequence); - -static inline void -xlog_cil_force(struct log *log) -{ - xlog_cil_force_lsn(log, log->l_cilp->xc_current_sequence); -} - -/* - * Unmount record type is used as a pseudo transaction type for the ticket. - * It's value must be outside the range of XFS_TRANS_* values. - */ -#define XLOG_UNMOUNT_REC_TYPE (-1U) - -/* - * Wrapper function for waiting on a wait queue serialised against wakeups - * by a spinlock. This matches the semantics of all the wait queues used in the - * log code. - */ -static inline void xlog_wait(wait_queue_head_t *wq, spinlock_t *lock) -{ - DECLARE_WAITQUEUE(wait, current); - - add_wait_queue_exclusive(wq, &wait); - __set_current_state(TASK_UNINTERRUPTIBLE); - spin_unlock(lock); - schedule(); - remove_wait_queue(wq, &wait); -} -#endif /* __KERNEL__ */ - -#endif /* __XFS_LOG_PRIV_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_mount.h xfsprogs-3.2.1ubuntu1/include/xfs_mount.h --- xfsprogs-3.1.9ubuntu2/include/xfs_mount.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_mount.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -/* - * Copyright (c) 2000-2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_MOUNT_H__ -#define __XFS_MOUNT_H__ - -typedef struct xfs_trans_reservations { - uint tr_write; /* extent alloc trans */ - uint tr_itruncate; /* truncate trans */ - uint tr_rename; /* rename trans */ - uint tr_link; /* link trans */ - uint tr_remove; /* unlink trans */ - uint tr_symlink; /* symlink trans */ - uint tr_create; /* create trans */ - uint tr_mkdir; /* mkdir trans */ - uint tr_ifree; /* inode free trans */ - uint tr_ichange; /* inode update trans */ - uint tr_growdata; /* fs data section grow trans */ - uint tr_swrite; /* sync write inode trans */ - uint tr_addafork; /* cvt inode to attributed trans */ - uint tr_writeid; /* write setuid/setgid file */ - uint tr_attrinval; /* attr fork buffer invalidation */ - uint tr_attrset; /* set/create an attribute */ - uint tr_attrrm; /* remove an attribute */ - uint tr_clearagi; /* clear bad agi unlinked ino bucket */ - uint tr_growrtalloc; /* grow realtime allocations */ - uint tr_growrtzero; /* grow realtime zeroing */ - uint tr_growrtfree; /* grow realtime freeing */ -} xfs_trans_reservations_t; - -#ifndef __KERNEL__ - -#define xfs_daddr_to_agno(mp,d) \ - ((xfs_agnumber_t)(XFS_BB_TO_FSBT(mp, d) / (mp)->m_sb.sb_agblocks)) -#define xfs_daddr_to_agbno(mp,d) \ - ((xfs_agblock_t)(XFS_BB_TO_FSBT(mp, d) % (mp)->m_sb.sb_agblocks)) - -#else /* __KERNEL__ */ - -#include "xfs_sync.h" - -struct log; -struct xfs_mount_args; -struct xfs_inode; -struct xfs_bmbt_irec; -struct xfs_bmap_free; -struct xfs_extdelta; -struct xfs_swapext; -struct xfs_mru_cache; -struct xfs_nameops; -struct xfs_ail; -struct xfs_quotainfo; - -#ifdef HAVE_PERCPU_SB - -/* - * Valid per-cpu incore superblock counters. Note that if you add new counters, - * you may need to define new counter disabled bit field descriptors as there - * are more possible fields in the superblock that can fit in a bitfield on a - * 32 bit platform. The XFS_SBS_* values for the current current counters just - * fit. - */ -typedef struct xfs_icsb_cnts { - uint64_t icsb_fdblocks; - uint64_t icsb_ifree; - uint64_t icsb_icount; - unsigned long icsb_flags; -} xfs_icsb_cnts_t; - -#define XFS_ICSB_FLAG_LOCK (1 << 0) /* counter lock bit */ - -#define XFS_ICSB_LAZY_COUNT (1 << 1) /* accuracy not needed */ - -extern int xfs_icsb_init_counters(struct xfs_mount *); -extern void xfs_icsb_reinit_counters(struct xfs_mount *); -extern void xfs_icsb_destroy_counters(struct xfs_mount *); -extern void xfs_icsb_sync_counters(struct xfs_mount *, int); -extern void xfs_icsb_sync_counters_locked(struct xfs_mount *, int); -extern int xfs_icsb_modify_counters(struct xfs_mount *, xfs_sb_field_t, - int64_t, int); - -#else -#define xfs_icsb_init_counters(mp) (0) -#define xfs_icsb_destroy_counters(mp) do { } while (0) -#define xfs_icsb_reinit_counters(mp) do { } while (0) -#define xfs_icsb_sync_counters(mp, flags) do { } while (0) -#define xfs_icsb_sync_counters_locked(mp, flags) do { } while (0) -#define xfs_icsb_modify_counters(mp, field, delta, rsvd) \ - xfs_mod_incore_sb(mp, field, delta, rsvd) -#endif - -/* dynamic preallocation free space thresholds, 5% down to 1% */ -enum { - XFS_LOWSP_1_PCNT = 0, - XFS_LOWSP_2_PCNT, - XFS_LOWSP_3_PCNT, - XFS_LOWSP_4_PCNT, - XFS_LOWSP_5_PCNT, - XFS_LOWSP_MAX, -}; - -typedef struct xfs_mount { - struct super_block *m_super; - xfs_tid_t m_tid; /* next unused tid for fs */ - struct xfs_ail *m_ail; /* fs active log item list */ - xfs_sb_t m_sb; /* copy of fs superblock */ - spinlock_t m_sb_lock; /* sb counter lock */ - struct xfs_buf *m_sb_bp; /* buffer for superblock */ - char *m_fsname; /* filesystem name */ - int m_fsname_len; /* strlen of fs name */ - char *m_rtname; /* realtime device name */ - char *m_logname; /* external log device name */ - int m_bsize; /* fs logical block size */ - xfs_agnumber_t m_agfrotor; /* last ag where space found */ - xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ - spinlock_t m_agirotor_lock;/* .. and lock protecting it */ - xfs_agnumber_t m_maxagi; /* highest inode alloc group */ - uint m_readio_log; /* min read size log bytes */ - uint m_readio_blocks; /* min read size blocks */ - uint m_writeio_log; /* min write size log bytes */ - uint m_writeio_blocks; /* min write size blocks */ - struct log *m_log; /* log specific stuff */ - int m_logbufs; /* number of log buffers */ - int m_logbsize; /* size of each log buffer */ - uint m_rsumlevels; /* rt summary levels */ - uint m_rsumsize; /* size of rt summary, bytes */ - struct xfs_inode *m_rbmip; /* pointer to bitmap inode */ - struct xfs_inode *m_rsumip; /* pointer to summary inode */ - struct xfs_inode *m_rootip; /* pointer to root directory */ - struct xfs_quotainfo *m_quotainfo; /* disk quota information */ - xfs_buftarg_t *m_ddev_targp; /* saves taking the address */ - xfs_buftarg_t *m_logdev_targp;/* ptr to log device */ - xfs_buftarg_t *m_rtdev_targp; /* ptr to rt device */ - __uint8_t m_blkbit_log; /* blocklog + NBBY */ - __uint8_t m_blkbb_log; /* blocklog - BBSHIFT */ - __uint8_t m_agno_log; /* log #ag's */ - __uint8_t m_agino_log; /* #bits for agino in inum */ - __uint16_t m_inode_cluster_size;/* min inode buf size */ - uint m_blockmask; /* sb_blocksize-1 */ - uint m_blockwsize; /* sb_blocksize in words */ - uint m_blockwmask; /* blockwsize-1 */ - uint m_alloc_mxr[2]; /* max alloc btree records */ - uint m_alloc_mnr[2]; /* min alloc btree records */ - uint m_bmap_dmxr[2]; /* max bmap btree records */ - uint m_bmap_dmnr[2]; /* min bmap btree records */ - uint m_inobt_mxr[2]; /* max inobt btree records */ - uint m_inobt_mnr[2]; /* min inobt btree records */ - uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */ - uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */ - uint m_in_maxlevels; /* max inobt btree levels. */ - struct radix_tree_root m_perag_tree; /* per-ag accounting info */ - spinlock_t m_perag_lock; /* lock for m_perag_tree */ - struct mutex m_growlock; /* growfs mutex */ - int m_fixedfsid[2]; /* unchanged for life of FS */ - uint m_dmevmask; /* DMI events for this FS */ - __uint64_t m_flags; /* global mount flags */ - uint m_dir_node_ents; /* #entries in a dir danode */ - uint m_attr_node_ents; /* #entries in attr danode */ - int m_ialloc_inos; /* inodes in inode allocation */ - int m_ialloc_blks; /* blocks in inode allocation */ - int m_inoalign_mask;/* mask sb_inoalignmt if used */ - uint m_qflags; /* quota status flags */ - xfs_trans_reservations_t m_reservations;/* precomputed res values */ - __uint64_t m_maxicount; /* maximum inode count */ - __uint64_t m_maxioffset; /* maximum inode offset */ - __uint64_t m_resblks; /* total reserved blocks */ - __uint64_t m_resblks_avail;/* available reserved blocks */ - __uint64_t m_resblks_save; /* reserved blks @ remount,ro */ - int m_dalign; /* stripe unit */ - int m_swidth; /* stripe width */ - int m_sinoalign; /* stripe unit inode alignment */ - int m_attr_magicpct;/* 37% of the blocksize */ - int m_dir_magicpct; /* 37% of the dir blocksize */ - __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ - const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */ - int m_dirblksize; /* directory block sz--bytes */ - int m_dirblkfsbs; /* directory block sz--fsbs */ - xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ - xfs_dablk_t m_dirleafblk; /* blockno of dir non-data v2 */ - xfs_dablk_t m_dirfreeblk; /* blockno of dirfreeindex v2 */ - uint m_chsize; /* size of next field */ - struct xfs_chash *m_chash; /* fs private inode per-cluster - * hash table */ - atomic_t m_active_trans; /* number trans frozen */ -#ifdef HAVE_PERCPU_SB - xfs_icsb_cnts_t __percpu *m_sb_cnts; /* per-cpu superblock counters */ - unsigned long m_icsb_counters; /* disabled per-cpu counters */ - struct notifier_block m_icsb_notifier; /* hotplug cpu notifier */ - struct mutex m_icsb_mutex; /* balancer sync lock */ -#endif - struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ - struct task_struct *m_sync_task; /* generalised sync thread */ - xfs_sync_work_t m_sync_work; /* work item for VFS_SYNC */ - struct list_head m_sync_list; /* sync thread work item list */ - spinlock_t m_sync_lock; /* work item list lock */ - int m_sync_seq; /* sync thread generation no. */ - wait_queue_head_t m_wait_single_sync_task; - __int64_t m_update_flags; /* sb flags we need to update - on the next remount,rw */ - struct shrinker m_inode_shrink; /* inode reclaim shrinker */ - int64_t m_low_space[XFS_LOWSP_MAX]; - /* low free space thresholds */ -} xfs_mount_t; - -/* - * Flags for m_flags. - */ -#define XFS_MOUNT_WSYNC (1ULL << 0) /* for nfs - all metadata ops - must be synchronous except - for space allocations */ -#define XFS_MOUNT_DELAYLOG (1ULL << 1) /* delayed logging is enabled */ -#define XFS_MOUNT_WAS_CLEAN (1ULL << 3) -#define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem - operations, typically for - disk errors in metadata */ -#define XFS_MOUNT_RETERR (1ULL << 6) /* return alignment errors to - user */ -#define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment - allocations */ -#define XFS_MOUNT_ATTR2 (1ULL << 8) /* allow use of attr2 format */ -#define XFS_MOUNT_GRPID (1ULL << 9) /* group-ID assigned from directory */ -#define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */ -#define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */ -#define XFS_MOUNT_32BITINODES (1ULL << 14) /* do not create inodes above - * 32 bits in size */ -#define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */ -#define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ -#define XFS_MOUNT_BARRIER (1ULL << 17) -#define XFS_MOUNT_IKEEP (1ULL << 18) /* keep empty inode clusters*/ -#define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width - * allocation */ -#define XFS_MOUNT_RDONLY (1ULL << 20) /* read-only fs */ -#define XFS_MOUNT_DIRSYNC (1ULL << 21) /* synchronous directory ops */ -#define XFS_MOUNT_COMPAT_IOSIZE (1ULL << 22) /* don't report large preferred - * I/O size in stat() */ -#define XFS_MOUNT_FILESTREAMS (1ULL << 24) /* enable the filestreams - allocator */ -#define XFS_MOUNT_NOATTR2 (1ULL << 25) /* disable use of attr2 format */ - - -/* - * Default minimum read and write sizes. - */ -#define XFS_READIO_LOG_LARGE 16 -#define XFS_WRITEIO_LOG_LARGE 16 - -/* - * Max and min values for mount-option defined I/O - * preallocation sizes. - */ -#define XFS_MAX_IO_LOG 30 /* 1G */ -#define XFS_MIN_IO_LOG PAGE_SHIFT - -/* - * Synchronous read and write sizes. This should be - * better for NFSv2 wsync filesystems. - */ -#define XFS_WSYNC_READIO_LOG 15 /* 32k */ -#define XFS_WSYNC_WRITEIO_LOG 14 /* 16k */ - -/* - * Allow large block sizes to be reported to userspace programs if the - * "largeio" mount option is used. - * - * If compatibility mode is specified, simply return the basic unit of caching - * so that we don't get inefficient read/modify/write I/O from user apps. - * Otherwise.... - * - * If the underlying volume is a stripe, then return the stripe width in bytes - * as the recommended I/O size. It is not a stripe and we've set a default - * buffered I/O size, return that, otherwise return the compat default. - */ -static inline unsigned long -xfs_preferred_iosize(xfs_mount_t *mp) -{ - if (mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE) - return PAGE_CACHE_SIZE; - return (mp->m_swidth ? - (mp->m_swidth << mp->m_sb.sb_blocklog) : - ((mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) ? - (1 << (int)MAX(mp->m_readio_log, mp->m_writeio_log)) : - PAGE_CACHE_SIZE)); -} - -#define XFS_MAXIOFFSET(mp) ((mp)->m_maxioffset) - -#define XFS_LAST_UNMOUNT_WAS_CLEAN(mp) \ - ((mp)->m_flags & XFS_MOUNT_WAS_CLEAN) -#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) -void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, - int lnnum); -#define xfs_force_shutdown(m,f) \ - xfs_do_force_shutdown(m, f, __FILE__, __LINE__) - -#define SHUTDOWN_META_IO_ERROR 0x0001 /* write attempt to metadata failed */ -#define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */ -#define SHUTDOWN_FORCE_UMOUNT 0x0004 /* shutdown from a forced unmount */ -#define SHUTDOWN_CORRUPT_INCORE 0x0008 /* corrupt in-memory data structures */ -#define SHUTDOWN_REMOTE_REQ 0x0010 /* shutdown came from remote cell */ -#define SHUTDOWN_DEVICE_REQ 0x0020 /* failed all paths to the device */ - -#define xfs_test_for_freeze(mp) ((mp)->m_super->s_frozen) -#define xfs_wait_for_freeze(mp,l) vfs_check_frozen((mp)->m_super, (l)) - -/* - * Flags for xfs_mountfs - */ -#define XFS_MFSI_QUIET 0x40 /* Be silent if mount errors found */ - -static inline xfs_agnumber_t -xfs_daddr_to_agno(struct xfs_mount *mp, xfs_daddr_t d) -{ - xfs_daddr_t ld = XFS_BB_TO_FSBT(mp, d); - do_div(ld, mp->m_sb.sb_agblocks); - return (xfs_agnumber_t) ld; -} - -static inline xfs_agblock_t -xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d) -{ - xfs_daddr_t ld = XFS_BB_TO_FSBT(mp, d); - return (xfs_agblock_t) do_div(ld, mp->m_sb.sb_agblocks); -} - -/* - * Per-cpu superblock locking functions - */ -#ifdef HAVE_PERCPU_SB -static inline void -xfs_icsb_lock(xfs_mount_t *mp) -{ - mutex_lock(&mp->m_icsb_mutex); -} - -static inline void -xfs_icsb_unlock(xfs_mount_t *mp) -{ - mutex_unlock(&mp->m_icsb_mutex); -} -#else -#define xfs_icsb_lock(mp) -#define xfs_icsb_unlock(mp) -#endif - -/* - * This structure is for use by the xfs_mod_incore_sb_batch() routine. - * xfs_growfs can specify a few fields which are more than int limit - */ -typedef struct xfs_mod_sb { - xfs_sb_field_t msb_field; /* Field to modify, see below */ - int64_t msb_delta; /* Change to make to specified field */ -} xfs_mod_sb_t; - -extern int xfs_log_sbcount(xfs_mount_t *, uint); -extern __uint64_t xfs_default_resblks(xfs_mount_t *mp); -extern int xfs_mountfs(xfs_mount_t *mp); - -extern void xfs_unmountfs(xfs_mount_t *); -extern int xfs_unmountfs_writesb(xfs_mount_t *); -extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int); -extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *, - uint, int); -extern int xfs_mount_log_sb(xfs_mount_t *, __int64_t); -extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); -extern int xfs_readsb(xfs_mount_t *, int); -extern void xfs_freesb(xfs_mount_t *); -extern int xfs_fs_writable(xfs_mount_t *); -extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); - -extern int xfs_dev_is_read_only(struct xfs_mount *, char *); - -extern void xfs_set_low_space_thresholds(struct xfs_mount *); - -#endif /* __KERNEL__ */ - -/* - * perag get/put wrappers for ref counting - */ -struct xfs_perag *xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno); -struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *mp, xfs_agnumber_t agno, - int tag); -void xfs_perag_put(struct xfs_perag *pag); - -extern void xfs_mod_sb(struct xfs_trans *, __int64_t); -extern int xfs_initialize_perag(struct xfs_mount *, xfs_agnumber_t, - xfs_agnumber_t *); -extern void xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *); -extern void xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t); - -#endif /* __XFS_MOUNT_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_quota_defs.h xfsprogs-3.2.1ubuntu1/include/xfs_quota_defs.h --- xfsprogs-3.1.9ubuntu2/include/xfs_quota_defs.h 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_quota_defs.h 2014-05-02 00:09:15.000000000 +0000 @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_QUOTA_DEFS_H__ +#define __XFS_QUOTA_DEFS_H__ + +/* + * Quota definitions shared between user and kernel source trees. + */ + +/* + * Even though users may not have quota limits occupying all 64-bits, + * they may need 64-bit accounting. Hence, 64-bit quota-counters, + * and quota-limits. This is a waste in the common case, but hey ... + */ +typedef __uint64_t xfs_qcnt_t; +typedef __uint16_t xfs_qwarncnt_t; + +/* + * flags for q_flags field in the dquot. + */ +#define XFS_DQ_USER 0x0001 /* a user quota */ +#define XFS_DQ_PROJ 0x0002 /* project quota */ +#define XFS_DQ_GROUP 0x0004 /* a group quota */ +#define XFS_DQ_DIRTY 0x0008 /* dquot is dirty */ +#define XFS_DQ_FREEING 0x0010 /* dquot is beeing torn down */ + +#define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP) + +#define XFS_DQ_FLAGS \ + { XFS_DQ_USER, "USER" }, \ + { XFS_DQ_PROJ, "PROJ" }, \ + { XFS_DQ_GROUP, "GROUP" }, \ + { XFS_DQ_DIRTY, "DIRTY" }, \ + { XFS_DQ_FREEING, "FREEING" } + +/* + * We have the possibility of all three quota types being active at once, and + * hence free space modification requires modification of all three current + * dquots in a single transaction. For this case we need to have a reservation + * of at least 3 dquots. + * + * However, a chmod operation can change both UID and GID in a single + * transaction, resulting in requiring {old, new} x {uid, gid} dquots to be + * modified. Hence for this case we need to reserve space for at least 4 dquots. + * + * And in the worst case, there's a rename operation that can be modifying up to + * 4 inodes with dquots attached to them. In reality, the only inodes that can + * have their dquots modified are the source and destination directory inodes + * due to directory name creation and removal. That can require space allocation + * and/or freeing on both directory inodes, and hence all three dquots on each + * inode can be modified. And if the directories are world writeable, all the + * dquots can be unique and so 6 dquots can be modified.... + * + * And, of course, we also need to take into account the dquot log format item + * used to describe each dquot. + */ +#define XFS_DQUOT_LOGRES(mp) \ + ((sizeof(struct xfs_dq_logformat) + sizeof(struct xfs_disk_dquot)) * 6) + +#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT) +#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT) +#define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT) +#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT) +#define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD) +#define XFS_IS_GQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_GQUOTA_ENFD) +#define XFS_IS_PQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_PQUOTA_ENFD) + +/* + * Incore only flags for quotaoff - these bits get cleared when quota(s) + * are in the process of getting turned off. These flags are in m_qflags but + * never in sb_qflags. + */ +#define XFS_UQUOTA_ACTIVE 0x1000 /* uquotas are being turned off */ +#define XFS_GQUOTA_ACTIVE 0x2000 /* gquotas are being turned off */ +#define XFS_PQUOTA_ACTIVE 0x4000 /* pquotas are being turned off */ +#define XFS_ALL_QUOTA_ACTIVE \ + (XFS_UQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE) + +/* + * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees + * quota will be not be switched off as long as that inode lock is held. + */ +#define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \ + XFS_GQUOTA_ACTIVE | \ + XFS_PQUOTA_ACTIVE)) +#define XFS_IS_OQUOTA_ON(mp) ((mp)->m_qflags & (XFS_GQUOTA_ACTIVE | \ + XFS_PQUOTA_ACTIVE)) +#define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE) +#define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACTIVE) +#define XFS_IS_PQUOTA_ON(mp) ((mp)->m_qflags & XFS_PQUOTA_ACTIVE) + +/* + * Flags to tell various functions what to do. Not all of these are meaningful + * to a single function. None of these XFS_QMOPT_* flags are meant to have + * persistent values (ie. their values can and will change between versions) + */ +#define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */ +#define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */ +#define XFS_QMOPT_PQUOTA 0x0000008 /* project dquot requested */ +#define XFS_QMOPT_FORCE_RES 0x0000010 /* ignore quota limits */ +#define XFS_QMOPT_SBVERSION 0x0000040 /* change superblock version num */ +#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if needed */ +#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */ +#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */ +#define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */ + +/* + * flags to xfs_trans_mod_dquot to indicate which field needs to be + * modified. + */ +#define XFS_QMOPT_RES_REGBLKS 0x0010000 +#define XFS_QMOPT_RES_RTBLKS 0x0020000 +#define XFS_QMOPT_BCOUNT 0x0040000 +#define XFS_QMOPT_ICOUNT 0x0080000 +#define XFS_QMOPT_RTBCOUNT 0x0100000 +#define XFS_QMOPT_DELBCOUNT 0x0200000 +#define XFS_QMOPT_DELRTBCOUNT 0x0400000 +#define XFS_QMOPT_RES_INOS 0x0800000 + +/* + * flags for dqalloc. + */ +#define XFS_QMOPT_INHERIT 0x1000000 + +/* + * flags to xfs_trans_mod_dquot. + */ +#define XFS_TRANS_DQ_RES_BLKS XFS_QMOPT_RES_REGBLKS +#define XFS_TRANS_DQ_RES_RTBLKS XFS_QMOPT_RES_RTBLKS +#define XFS_TRANS_DQ_RES_INOS XFS_QMOPT_RES_INOS +#define XFS_TRANS_DQ_BCOUNT XFS_QMOPT_BCOUNT +#define XFS_TRANS_DQ_DELBCOUNT XFS_QMOPT_DELBCOUNT +#define XFS_TRANS_DQ_ICOUNT XFS_QMOPT_ICOUNT +#define XFS_TRANS_DQ_RTBCOUNT XFS_QMOPT_RTBCOUNT +#define XFS_TRANS_DQ_DELRTBCOUNT XFS_QMOPT_DELRTBCOUNT + + +#define XFS_QMOPT_QUOTALL \ + (XFS_QMOPT_UQUOTA | XFS_QMOPT_PQUOTA | XFS_QMOPT_GQUOTA) +#define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS) + +extern int xfs_dqcheck(struct xfs_mount *mp, xfs_disk_dquot_t *ddq, + xfs_dqid_t id, uint type, uint flags, char *str); +extern int xfs_calc_dquots_per_chunk(struct xfs_mount *mp, unsigned int nbblks); + +#endif /* __XFS_QUOTA_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_quota.h xfsprogs-3.2.1ubuntu1/include/xfs_quota.h --- xfsprogs-3.1.9ubuntu2/include/xfs_quota.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_quota.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,375 +0,0 @@ -/* - * Copyright (c) 2000-2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_QUOTA_H__ -#define __XFS_QUOTA_H__ - -struct xfs_trans; - -/* - * The ondisk form of a dquot structure. - */ -#define XFS_DQUOT_MAGIC 0x4451 /* 'DQ' */ -#define XFS_DQUOT_VERSION (u_int8_t)0x01 /* latest version number */ - -/* - * uid_t and gid_t are hard-coded to 32 bits in the inode. - * Hence, an 'id' in a dquot is 32 bits.. - */ -typedef __uint32_t xfs_dqid_t; - -/* - * Even though users may not have quota limits occupying all 64-bits, - * they may need 64-bit accounting. Hence, 64-bit quota-counters, - * and quota-limits. This is a waste in the common case, but hey ... - */ -typedef __uint64_t xfs_qcnt_t; -typedef __uint16_t xfs_qwarncnt_t; - -/* - * This is the main portion of the on-disk representation of quota - * information for a user. This is the q_core of the xfs_dquot_t that - * is kept in kernel memory. We pad this with some more expansion room - * to construct the on disk structure. - */ -typedef struct xfs_disk_dquot { - __be16 d_magic; /* dquot magic = XFS_DQUOT_MAGIC */ - __u8 d_version; /* dquot version */ - __u8 d_flags; /* XFS_DQ_USER/PROJ/GROUP */ - __be32 d_id; /* user,project,group id */ - __be64 d_blk_hardlimit;/* absolute limit on disk blks */ - __be64 d_blk_softlimit;/* preferred limit on disk blks */ - __be64 d_ino_hardlimit;/* maximum # allocated inodes */ - __be64 d_ino_softlimit;/* preferred inode limit */ - __be64 d_bcount; /* disk blocks owned by the user */ - __be64 d_icount; /* inodes owned by the user */ - __be32 d_itimer; /* zero if within inode limits if not, - this is when we refuse service */ - __be32 d_btimer; /* similar to above; for disk blocks */ - __be16 d_iwarns; /* warnings issued wrt num inodes */ - __be16 d_bwarns; /* warnings issued wrt disk blocks */ - __be32 d_pad0; /* 64 bit align */ - __be64 d_rtb_hardlimit;/* absolute limit on realtime blks */ - __be64 d_rtb_softlimit;/* preferred limit on RT disk blks */ - __be64 d_rtbcount; /* realtime blocks owned */ - __be32 d_rtbtimer; /* similar to above; for RT disk blocks */ - __be16 d_rtbwarns; /* warnings issued wrt RT disk blocks */ - __be16 d_pad; -} xfs_disk_dquot_t; - -/* - * This is what goes on disk. This is separated from the xfs_disk_dquot because - * carrying the unnecessary padding would be a waste of memory. - */ -typedef struct xfs_dqblk { - xfs_disk_dquot_t dd_diskdq; /* portion that lives incore as well */ - char dd_fill[32]; /* filling for posterity */ -} xfs_dqblk_t; - -/* - * flags for q_flags field in the dquot. - */ -#define XFS_DQ_USER 0x0001 /* a user quota */ -#define XFS_DQ_PROJ 0x0002 /* project quota */ -#define XFS_DQ_GROUP 0x0004 /* a group quota */ -#define XFS_DQ_DIRTY 0x0008 /* dquot is dirty */ -#define XFS_DQ_WANT 0x0010 /* for lookup/reclaim race */ -#define XFS_DQ_INACTIVE 0x0020 /* dq off mplist & hashlist */ - -#define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP) - -#define XFS_DQ_FLAGS \ - { XFS_DQ_USER, "USER" }, \ - { XFS_DQ_PROJ, "PROJ" }, \ - { XFS_DQ_GROUP, "GROUP" }, \ - { XFS_DQ_DIRTY, "DIRTY" }, \ - { XFS_DQ_WANT, "WANT" }, \ - { XFS_DQ_INACTIVE, "INACTIVE" } - -/* - * In the worst case, when both user and group quotas are on, - * we can have a max of three dquots changing in a single transaction. - */ -#define XFS_DQUOT_LOGRES(mp) (sizeof(xfs_disk_dquot_t) * 3) - - -/* - * These are the structures used to lay out dquots and quotaoff - * records on the log. Quite similar to those of inodes. - */ - -/* - * log format struct for dquots. - * The first two fields must be the type and size fitting into - * 32 bits : log_recovery code assumes that. - */ -typedef struct xfs_dq_logformat { - __uint16_t qlf_type; /* dquot log item type */ - __uint16_t qlf_size; /* size of this item */ - xfs_dqid_t qlf_id; /* usr/grp/proj id : 32 bits */ - __int64_t qlf_blkno; /* blkno of dquot buffer */ - __int32_t qlf_len; /* len of dquot buffer */ - __uint32_t qlf_boffset; /* off of dquot in buffer */ -} xfs_dq_logformat_t; - -/* - * log format struct for QUOTAOFF records. - * The first two fields must be the type and size fitting into - * 32 bits : log_recovery code assumes that. - * We write two LI_QUOTAOFF logitems per quotaoff, the last one keeps a pointer - * to the first and ensures that the first logitem is taken out of the AIL - * only when the last one is securely committed. - */ -typedef struct xfs_qoff_logformat { - unsigned short qf_type; /* quotaoff log item type */ - unsigned short qf_size; /* size of this item */ - unsigned int qf_flags; /* USR and/or GRP */ - char qf_pad[12]; /* padding for future */ -} xfs_qoff_logformat_t; - - -/* - * Disk quotas status in m_qflags, and also sb_qflags. 16 bits. - */ -#define XFS_UQUOTA_ACCT 0x0001 /* user quota accounting ON */ -#define XFS_UQUOTA_ENFD 0x0002 /* user quota limits enforced */ -#define XFS_UQUOTA_CHKD 0x0004 /* quotacheck run on usr quotas */ -#define XFS_PQUOTA_ACCT 0x0008 /* project quota accounting ON */ -#define XFS_OQUOTA_ENFD 0x0010 /* other (grp/prj) quota limits enforced */ -#define XFS_OQUOTA_CHKD 0x0020 /* quotacheck run on other (grp/prj) quotas */ -#define XFS_GQUOTA_ACCT 0x0040 /* group quota accounting ON */ - -/* - * Quota Accounting/Enforcement flags - */ -#define XFS_ALL_QUOTA_ACCT \ - (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT) -#define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD) -#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD) - -#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT) -#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT) -#define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT) -#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT) -#define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD) -#define XFS_IS_OQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_OQUOTA_ENFD) - -/* - * Incore only flags for quotaoff - these bits get cleared when quota(s) - * are in the process of getting turned off. These flags are in m_qflags but - * never in sb_qflags. - */ -#define XFS_UQUOTA_ACTIVE 0x0100 /* uquotas are being turned off */ -#define XFS_PQUOTA_ACTIVE 0x0200 /* pquotas are being turned off */ -#define XFS_GQUOTA_ACTIVE 0x0400 /* gquotas are being turned off */ - -/* - * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees - * quota will be not be switched off as long as that inode lock is held. - */ -#define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \ - XFS_GQUOTA_ACTIVE | \ - XFS_PQUOTA_ACTIVE)) -#define XFS_IS_OQUOTA_ON(mp) ((mp)->m_qflags & (XFS_GQUOTA_ACTIVE | \ - XFS_PQUOTA_ACTIVE)) -#define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE) -#define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACTIVE) -#define XFS_IS_PQUOTA_ON(mp) ((mp)->m_qflags & XFS_PQUOTA_ACTIVE) - -/* - * Flags to tell various functions what to do. Not all of these are meaningful - * to a single function. None of these XFS_QMOPT_* flags are meant to have - * persistent values (ie. their values can and will change between versions) - */ -#define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */ -#define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */ -#define XFS_QMOPT_PQUOTA 0x0000008 /* project dquot requested */ -#define XFS_QMOPT_FORCE_RES 0x0000010 /* ignore quota limits */ -#define XFS_QMOPT_DQSUSER 0x0000020 /* don't cache super users dquot */ -#define XFS_QMOPT_SBVERSION 0x0000040 /* change superblock version num */ -#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if needed */ -#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */ -#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */ -#define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */ - -/* - * flags to xfs_trans_mod_dquot to indicate which field needs to be - * modified. - */ -#define XFS_QMOPT_RES_REGBLKS 0x0010000 -#define XFS_QMOPT_RES_RTBLKS 0x0020000 -#define XFS_QMOPT_BCOUNT 0x0040000 -#define XFS_QMOPT_ICOUNT 0x0080000 -#define XFS_QMOPT_RTBCOUNT 0x0100000 -#define XFS_QMOPT_DELBCOUNT 0x0200000 -#define XFS_QMOPT_DELRTBCOUNT 0x0400000 -#define XFS_QMOPT_RES_INOS 0x0800000 - -/* - * flags for dqalloc. - */ -#define XFS_QMOPT_INHERIT 0x1000000 - -/* - * flags to xfs_trans_mod_dquot. - */ -#define XFS_TRANS_DQ_RES_BLKS XFS_QMOPT_RES_REGBLKS -#define XFS_TRANS_DQ_RES_RTBLKS XFS_QMOPT_RES_RTBLKS -#define XFS_TRANS_DQ_RES_INOS XFS_QMOPT_RES_INOS -#define XFS_TRANS_DQ_BCOUNT XFS_QMOPT_BCOUNT -#define XFS_TRANS_DQ_DELBCOUNT XFS_QMOPT_DELBCOUNT -#define XFS_TRANS_DQ_ICOUNT XFS_QMOPT_ICOUNT -#define XFS_TRANS_DQ_RTBCOUNT XFS_QMOPT_RTBCOUNT -#define XFS_TRANS_DQ_DELRTBCOUNT XFS_QMOPT_DELRTBCOUNT - - -#define XFS_QMOPT_QUOTALL \ - (XFS_QMOPT_UQUOTA | XFS_QMOPT_PQUOTA | XFS_QMOPT_GQUOTA) -#define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS) - -#ifdef __KERNEL__ -/* - * This check is done typically without holding the inode lock; - * that may seem racy, but it is harmless in the context that it is used. - * The inode cannot go inactive as long a reference is kept, and - * therefore if dquot(s) were attached, they'll stay consistent. - * If, for example, the ownership of the inode changes while - * we didn't have the inode locked, the appropriate dquot(s) will be - * attached atomically. - */ -#define XFS_NOT_DQATTACHED(mp, ip) ((XFS_IS_UQUOTA_ON(mp) &&\ - (ip)->i_udquot == NULL) || \ - (XFS_IS_OQUOTA_ON(mp) && \ - (ip)->i_gdquot == NULL)) - -#define XFS_QM_NEED_QUOTACHECK(mp) \ - ((XFS_IS_UQUOTA_ON(mp) && \ - (mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD) == 0) || \ - (XFS_IS_GQUOTA_ON(mp) && \ - ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \ - (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT))) || \ - (XFS_IS_PQUOTA_ON(mp) && \ - ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \ - (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT)))) - -#define XFS_MOUNT_QUOTA_SET1 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ - XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\ - XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD) - -#define XFS_MOUNT_QUOTA_SET2 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ - XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\ - XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD) - -#define XFS_MOUNT_QUOTA_ALL (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ - XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\ - XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\ - XFS_GQUOTA_ACCT) - - -/* - * The structure kept inside the xfs_trans_t keep track of dquot changes - * within a transaction and apply them later. - */ -typedef struct xfs_dqtrx { - struct xfs_dquot *qt_dquot; /* the dquot this refers to */ - ulong qt_blk_res; /* blks reserved on a dquot */ - ulong qt_blk_res_used; /* blks used from the reservation */ - ulong qt_ino_res; /* inode reserved on a dquot */ - ulong qt_ino_res_used; /* inodes used from the reservation */ - long qt_bcount_delta; /* dquot blk count changes */ - long qt_delbcnt_delta; /* delayed dquot blk count changes */ - long qt_icount_delta; /* dquot inode count changes */ - ulong qt_rtblk_res; /* # blks reserved on a dquot */ - ulong qt_rtblk_res_used;/* # blks used from reservation */ - long qt_rtbcount_delta;/* dquot realtime blk changes */ - long qt_delrtb_delta; /* delayed RT blk count changes */ -} xfs_dqtrx_t; - -extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *); -extern int xfs_mount_reset_sbqflags(struct xfs_mount *); - -#endif /* __KERNEL__ */ - -#ifdef CONFIG_XFS_QUOTA -extern void xfs_trans_dup_dqinfo(struct xfs_trans *, struct xfs_trans *); -extern void xfs_trans_free_dqinfo(struct xfs_trans *); -extern void xfs_trans_mod_dquot_byino(struct xfs_trans *, struct xfs_inode *, - uint, long); -extern void xfs_trans_apply_dquot_deltas(struct xfs_trans *); -extern void xfs_trans_unreserve_and_mod_dquots(struct xfs_trans *); -extern int xfs_trans_reserve_quota_nblks(struct xfs_trans *, - struct xfs_inode *, long, long, uint); -extern int xfs_trans_reserve_quota_bydquots(struct xfs_trans *, - struct xfs_mount *, struct xfs_dquot *, - struct xfs_dquot *, long, long, uint); - -extern int xfs_qm_vop_dqalloc(struct xfs_inode *, uid_t, gid_t, prid_t, uint, - struct xfs_dquot **, struct xfs_dquot **); -extern void xfs_qm_vop_create_dqattach(struct xfs_trans *, struct xfs_inode *, - struct xfs_dquot *, struct xfs_dquot *); -extern int xfs_qm_vop_rename_dqattach(struct xfs_inode **); -extern struct xfs_dquot *xfs_qm_vop_chown(struct xfs_trans *, - struct xfs_inode *, struct xfs_dquot **, struct xfs_dquot *); -extern int xfs_qm_vop_chown_reserve(struct xfs_trans *, struct xfs_inode *, - struct xfs_dquot *, struct xfs_dquot *, uint); -extern int xfs_qm_dqattach(struct xfs_inode *, uint); -extern int xfs_qm_dqattach_locked(struct xfs_inode *, uint); -extern void xfs_qm_dqdetach(struct xfs_inode *); -extern void xfs_qm_dqrele(struct xfs_dquot *); -extern void xfs_qm_statvfs(struct xfs_inode *, struct kstatfs *); -extern int xfs_qm_sync(struct xfs_mount *, int); -extern int xfs_qm_newmount(struct xfs_mount *, uint *, uint *); -extern void xfs_qm_mount_quotas(struct xfs_mount *); -extern void xfs_qm_unmount(struct xfs_mount *); -extern void xfs_qm_unmount_quotas(struct xfs_mount *); - -#else -#define xfs_qm_vop_dqalloc(ip, uid, gid, prid, flags, udqp, gdqp) ({ \ - *(udqp) = NULL; \ - *(gdqp) = NULL; \ - 0; \ -}) -#define xfs_trans_dup_dqinfo(tp, tp2) -#define xfs_trans_free_dqinfo(tp) -#define xfs_trans_mod_dquot_byino(tp, ip, fields, delta) -#define xfs_trans_apply_dquot_deltas(tp) -#define xfs_trans_unreserve_and_mod_dquots(tp) -#define xfs_trans_reserve_quota_nblks(tp, ip, blks, inos, flg) (0) -#define xfs_trans_reserve_quota_bydquots(tp, mp, uqp, gqp, blks, inos, flg) (0) -#define xfs_qm_vop_create_dqattach(tp, ip, u, g) -#define xfs_qm_vop_rename_dqattach(it) (0) -#define xfs_qm_vop_chown(tp, ip, old, new) (NULL) -#define xfs_qm_vop_chown_reserve(tp, ip, u, g, fl) (0) -#define xfs_qm_dqattach(ip, fl) (0) -#define xfs_qm_dqattach_locked(ip, fl) (0) -#define xfs_qm_dqdetach(ip) -#define xfs_qm_dqrele(d) -#define xfs_qm_statvfs(ip, s) -#define xfs_qm_sync(mp, flags) (0) -#define xfs_qm_newmount(mp, a, b) (0) -#define xfs_qm_mount_quotas(mp) -#define xfs_qm_unmount(mp) -#define xfs_qm_unmount_quotas(mp) -#endif /* CONFIG_XFS_QUOTA */ - -#define xfs_trans_unreserve_quota_nblks(tp, ip, nblks, ninos, flags) \ - xfs_trans_reserve_quota_nblks(tp, ip, -(nblks), -(ninos), flags) -#define xfs_trans_reserve_quota(tp, mp, ud, gd, nb, ni, f) \ - xfs_trans_reserve_quota_bydquots(tp, mp, ud, gd, nb, ni, \ - f | XFS_QMOPT_RES_REGBLKS) - -#endif /* __XFS_QUOTA_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_rtalloc.h xfsprogs-3.2.1ubuntu1/include/xfs_rtalloc.h --- xfsprogs-3.1.9ubuntu2/include/xfs_rtalloc.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_rtalloc.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_RTALLOC_H__ -#define __XFS_RTALLOC_H__ - -struct xfs_mount; -struct xfs_trans; - -/* Min and max rt extent sizes, specified in bytes */ -#define XFS_MAX_RTEXTSIZE (1024 * 1024 * 1024) /* 1GB */ -#define XFS_DFL_RTEXTSIZE (64 * 1024) /* 64kB */ -#define XFS_MIN_RTEXTSIZE (4 * 1024) /* 4kB */ - -/* - * Constants for bit manipulations. - */ -#define XFS_NBBYLOG 3 /* log2(NBBY) */ -#define XFS_WORDLOG 2 /* log2(sizeof(xfs_rtword_t)) */ -#define XFS_NBWORDLOG (XFS_NBBYLOG + XFS_WORDLOG) -#define XFS_NBWORD (1 << XFS_NBWORDLOG) -#define XFS_WORDMASK ((1 << XFS_WORDLOG) - 1) - -#define XFS_BLOCKSIZE(mp) ((mp)->m_sb.sb_blocksize) -#define XFS_BLOCKMASK(mp) ((mp)->m_blockmask) -#define XFS_BLOCKWSIZE(mp) ((mp)->m_blockwsize) -#define XFS_BLOCKWMASK(mp) ((mp)->m_blockwmask) - -/* - * Summary and bit manipulation macros. - */ -#define XFS_SUMOFFS(mp,ls,bb) ((int)((ls) * (mp)->m_sb.sb_rbmblocks + (bb))) -#define XFS_SUMOFFSTOBLOCK(mp,s) \ - (((s) * (uint)sizeof(xfs_suminfo_t)) >> (mp)->m_sb.sb_blocklog) -#define XFS_SUMPTR(mp,bp,so) \ - ((xfs_suminfo_t *)((char *)XFS_BUF_PTR(bp) + \ - (((so) * (uint)sizeof(xfs_suminfo_t)) & XFS_BLOCKMASK(mp)))) - -#define XFS_BITTOBLOCK(mp,bi) ((bi) >> (mp)->m_blkbit_log) -#define XFS_BLOCKTOBIT(mp,bb) ((bb) << (mp)->m_blkbit_log) -#define XFS_BITTOWORD(mp,bi) \ - ((int)(((bi) >> XFS_NBWORDLOG) & XFS_BLOCKWMASK(mp))) - -#define XFS_RTMIN(a,b) ((a) < (b) ? (a) : (b)) -#define XFS_RTMAX(a,b) ((a) > (b) ? (a) : (b)) - -#define XFS_RTLOBIT(w) xfs_lowbit32(w) -#define XFS_RTHIBIT(w) xfs_highbit32(w) - -#if XFS_BIG_BLKNOS -#define XFS_RTBLOCKLOG(b) xfs_highbit64(b) -#else -#define XFS_RTBLOCKLOG(b) xfs_highbit32(b) -#endif - - -#ifdef __KERNEL__ - -#ifdef CONFIG_XFS_RT -/* - * Function prototypes for exported functions. - */ - -/* - * Allocate an extent in the realtime subvolume, with the usual allocation - * parameters. The length units are all in realtime extents, as is the - * result block number. - */ -int /* error */ -xfs_rtallocate_extent( - struct xfs_trans *tp, /* transaction pointer */ - xfs_rtblock_t bno, /* starting block number to allocate */ - xfs_extlen_t minlen, /* minimum length to allocate */ - xfs_extlen_t maxlen, /* maximum length to allocate */ - xfs_extlen_t *len, /* out: actual length allocated */ - xfs_alloctype_t type, /* allocation type XFS_ALLOCTYPE... */ - int wasdel, /* was a delayed allocation extent */ - xfs_extlen_t prod, /* extent product factor */ - xfs_rtblock_t *rtblock); /* out: start block allocated */ - -/* - * Free an extent in the realtime subvolume. Length is expressed in - * realtime extents, as is the block number. - */ -int /* error */ -xfs_rtfree_extent( - struct xfs_trans *tp, /* transaction pointer */ - xfs_rtblock_t bno, /* starting block number to free */ - xfs_extlen_t len); /* length of extent freed */ - -/* - * Initialize realtime fields in the mount structure. - */ -int /* error */ -xfs_rtmount_init( - struct xfs_mount *mp); /* file system mount structure */ -void -xfs_rtunmount_inodes( - struct xfs_mount *mp); - -/* - * Get the bitmap and summary inodes into the mount structure - * at mount time. - */ -int /* error */ -xfs_rtmount_inodes( - struct xfs_mount *mp); /* file system mount structure */ - -/* - * Pick an extent for allocation at the start of a new realtime file. - * Use the sequence number stored in the atime field of the bitmap inode. - * Translate this to a fraction of the rtextents, and return the product - * of rtextents and the fraction. - * The fraction sequence is 0, 1/2, 1/4, 3/4, 1/8, ..., 7/8, 1/16, ... - */ -int /* error */ -xfs_rtpick_extent( - struct xfs_mount *mp, /* file system mount point */ - struct xfs_trans *tp, /* transaction pointer */ - xfs_extlen_t len, /* allocation length (rtextents) */ - xfs_rtblock_t *pick); /* result rt extent */ - -/* - * Grow the realtime area of the filesystem. - */ -int -xfs_growfs_rt( - struct xfs_mount *mp, /* file system mount structure */ - xfs_growfs_rt_t *in); /* user supplied growfs struct */ - -#else -# define xfs_rtallocate_extent(t,b,min,max,l,a,f,p,rb) (ENOSYS) -# define xfs_rtfree_extent(t,b,l) (ENOSYS) -# define xfs_rtpick_extent(m,t,l,rb) (ENOSYS) -# define xfs_growfs_rt(mp,in) (ENOSYS) -static inline int /* error */ -xfs_rtmount_init( - xfs_mount_t *mp) /* file system mount structure */ -{ - if (mp->m_sb.sb_rblocks == 0) - return 0; - - cmn_err(CE_WARN, "XFS: Not built with CONFIG_XFS_RT"); - return ENOSYS; -} -# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS)) -# define xfs_rtunmount_inodes(m) -#endif /* CONFIG_XFS_RT */ - -#endif /* __KERNEL__ */ - -#endif /* __XFS_RTALLOC_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_sb.h xfsprogs-3.2.1ubuntu1/include/xfs_sb.h --- xfsprogs-3.1.9ubuntu2/include/xfs_sb.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_sb.h 2014-06-19 22:42:17.000000000 +0000 @@ -26,12 +26,14 @@ struct xfs_buf; struct xfs_mount; +struct xfs_trans; #define XFS_SB_MAGIC 0x58465342 /* 'XFSB' */ #define XFS_SB_VERSION_1 1 /* 5.3, 6.0.1, 6.1 */ #define XFS_SB_VERSION_2 2 /* 6.2 - attributes */ #define XFS_SB_VERSION_3 3 /* 6.2 - new inode version */ #define XFS_SB_VERSION_4 4 /* 6.2+ - bitmask version */ +#define XFS_SB_VERSION_5 5 /* CRC enabled filesystem */ #define XFS_SB_VERSION_NUMBITS 0x000f #define XFS_SB_VERSION_ALLFBITS 0xfff0 #define XFS_SB_VERSION_SASHFBITS 0xf000 @@ -81,11 +83,14 @@ #define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */ #define XFS_SB_VERSION2_PARENTBIT 0x00000010 /* parent pointers */ #define XFS_SB_VERSION2_PROJID32BIT 0x00000080 /* 32 bit project id */ +#define XFS_SB_VERSION2_CRCBIT 0x00000100 /* metadata CRCs */ +#define XFS_SB_VERSION2_FTYPE 0x00000200 /* inode type in dir */ #define XFS_SB_VERSION2_OKREALFBITS \ (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \ XFS_SB_VERSION2_ATTR2BIT | \ - XFS_SB_VERSION2_PROJID32BIT) + XFS_SB_VERSION2_PROJID32BIT | \ + XFS_SB_VERSION2_FTYPE) #define XFS_SB_VERSION2_OKSASHFBITS \ (0) #define XFS_SB_VERSION2_OKREALBITS \ @@ -160,9 +165,25 @@ */ __uint32_t sb_bad_features2; + /* version 5 superblock fields start here */ + + /* feature masks */ + __uint32_t sb_features_compat; + __uint32_t sb_features_ro_compat; + __uint32_t sb_features_incompat; + __uint32_t sb_features_log_incompat; + + __uint32_t sb_crc; /* superblock crc */ + __uint32_t sb_pad; + + xfs_ino_t sb_pquotino; /* project quota inode */ + xfs_lsn_t sb_lsn; /* last write sequence */ + /* must be padded to 64 bit alignment */ } xfs_sb_t; +#define XFS_SB_CRC_OFF offsetof(struct xfs_sb, sb_crc) + /* * Superblock - on disk version. Must match the in core version above. * Must be padded to 64 bit alignment. @@ -228,7 +249,21 @@ * for features2 bits. Easiest just to mark it bad and not use * it for anything else. */ - __be32 sb_bad_features2; + __be32 sb_bad_features2; + + /* version 5 superblock fields start here */ + + /* feature masks */ + __be32 sb_features_compat; + __be32 sb_features_ro_compat; + __be32 sb_features_incompat; + __be32 sb_features_log_incompat; + + __le32 sb_crc; /* superblock crc */ + __be32 sb_pad; + + __be64 sb_pquotino; /* project quota inode */ + __be64 sb_lsn; /* last write sequence */ /* must be padded to 64 bit alignment */ } xfs_dsb_t; @@ -249,7 +284,10 @@ XFS_SBS_GQUOTINO, XFS_SBS_QFLAGS, XFS_SBS_FLAGS, XFS_SBS_SHARED_VN, XFS_SBS_INOALIGNMT, XFS_SBS_UNIT, XFS_SBS_WIDTH, XFS_SBS_DIRBLKLOG, XFS_SBS_LOGSECTLOG, XFS_SBS_LOGSECTSIZE, XFS_SBS_LOGSUNIT, - XFS_SBS_FEATURES2, XFS_SBS_BAD_FEATURES2, + XFS_SBS_FEATURES2, XFS_SBS_BAD_FEATURES2, XFS_SBS_FEATURES_COMPAT, + XFS_SBS_FEATURES_RO_COMPAT, XFS_SBS_FEATURES_INCOMPAT, + XFS_SBS_FEATURES_LOG_INCOMPAT, XFS_SBS_CRC, XFS_SBS_PAD, + XFS_SBS_PQUOTINO, XFS_SBS_LSN, XFS_SBS_FIELDCOUNT } xfs_sb_field_t; @@ -275,6 +313,12 @@ #define XFS_SB_FDBLOCKS XFS_SB_MVAL(FDBLOCKS) #define XFS_SB_FEATURES2 XFS_SB_MVAL(FEATURES2) #define XFS_SB_BAD_FEATURES2 XFS_SB_MVAL(BAD_FEATURES2) +#define XFS_SB_FEATURES_COMPAT XFS_SB_MVAL(FEATURES_COMPAT) +#define XFS_SB_FEATURES_RO_COMPAT XFS_SB_MVAL(FEATURES_RO_COMPAT) +#define XFS_SB_FEATURES_INCOMPAT XFS_SB_MVAL(FEATURES_INCOMPAT) +#define XFS_SB_FEATURES_LOG_INCOMPAT XFS_SB_MVAL(FEATURES_LOG_INCOMPAT) +#define XFS_SB_CRC XFS_SB_MVAL(CRC) +#define XFS_SB_PQUOTINO XFS_SB_MVAL(PQUOTINO) #define XFS_SB_NUM_BITS ((int)XFS_SBS_FIELDCOUNT) #define XFS_SB_ALL_BITS ((1LL << XFS_SB_NUM_BITS) - 1) #define XFS_SB_MOD_BITS \ @@ -282,7 +326,9 @@ XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \ XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \ XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2 | \ - XFS_SB_BAD_FEATURES2) + XFS_SB_BAD_FEATURES2 | XFS_SB_FEATURES_COMPAT | \ + XFS_SB_FEATURES_RO_COMPAT | XFS_SB_FEATURES_INCOMPAT | \ + XFS_SB_FEATURES_LOG_INCOMPAT | XFS_SB_PQUOTINO) /* @@ -313,17 +359,12 @@ (sbp->sb_features2 & ~XFS_SB_VERSION2_OKREALBITS))) return 0; -#ifdef __KERNEL__ if (sbp->sb_shared_vn > XFS_SB_MAX_SHARED_VN) return 0; -#else - if ((sbp->sb_versionnum & XFS_SB_VERSION_SHAREDBIT) && - sbp->sb_shared_vn > XFS_SB_MAX_SHARED_VN) - return 0; -#endif - return 1; } + if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) + return 1; return 0; } @@ -364,7 +405,7 @@ { return sbp->sb_versionnum == XFS_SB_VERSION_2 || sbp->sb_versionnum == XFS_SB_VERSION_3 || - (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && + (XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_ATTRBIT)); } @@ -372,7 +413,7 @@ { if (sbp->sb_versionnum == XFS_SB_VERSION_1) sbp->sb_versionnum = XFS_SB_VERSION_2; - else if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) + else if (XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4) sbp->sb_versionnum |= XFS_SB_VERSION_ATTRBIT; else sbp->sb_versionnum = XFS_SB_VERSION_4 | XFS_SB_VERSION_ATTRBIT; @@ -381,7 +422,7 @@ static inline int xfs_sb_version_hasnlink(xfs_sb_t *sbp) { return sbp->sb_versionnum == XFS_SB_VERSION_3 || - (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && + (XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_NLINKBIT)); } @@ -395,13 +436,13 @@ static inline int xfs_sb_version_hasquota(xfs_sb_t *sbp) { - return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && + return XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_QUOTABIT); } static inline void xfs_sb_version_addquota(xfs_sb_t *sbp) { - if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) + if (XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4) sbp->sb_versionnum |= XFS_SB_VERSION_QUOTABIT; else sbp->sb_versionnum = xfs_sb_version_tonew(sbp->sb_versionnum) | @@ -410,13 +451,14 @@ static inline int xfs_sb_version_hasalign(xfs_sb_t *sbp) { - return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && - (sbp->sb_versionnum & XFS_SB_VERSION_ALIGNBIT); + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) || + (XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4 && + (sbp->sb_versionnum & XFS_SB_VERSION_ALIGNBIT)); } static inline int xfs_sb_version_hasdalign(xfs_sb_t *sbp) { - return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && + return XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_DALIGNBIT); } @@ -428,38 +470,42 @@ static inline int xfs_sb_version_hasdirv2(xfs_sb_t *sbp) { - return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && - (sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT); + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) || + (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && + (sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT)); } static inline int xfs_sb_version_haslogv2(xfs_sb_t *sbp) { - return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && - (sbp->sb_versionnum & XFS_SB_VERSION_LOGV2BIT); + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) || + (XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4 && + (sbp->sb_versionnum & XFS_SB_VERSION_LOGV2BIT)); } static inline int xfs_sb_version_hasextflgbit(xfs_sb_t *sbp) { - return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && - (sbp->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT); + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) || + (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && + (sbp->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT)); } static inline int xfs_sb_version_hassector(xfs_sb_t *sbp) { - return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && + return XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_SECTORBIT); } static inline int xfs_sb_version_hasasciici(xfs_sb_t *sbp) { - return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && + return XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_BORGBIT); } static inline int xfs_sb_version_hasmorebits(xfs_sb_t *sbp) { - return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && - (sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT); + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) || + (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && + (sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT)); } /* @@ -474,14 +520,16 @@ static inline int xfs_sb_version_haslazysbcount(xfs_sb_t *sbp) { - return xfs_sb_version_hasmorebits(sbp) && - (sbp->sb_features2 & XFS_SB_VERSION2_LAZYSBCOUNTBIT); + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) || + (xfs_sb_version_hasmorebits(sbp) && + (sbp->sb_features2 & XFS_SB_VERSION2_LAZYSBCOUNTBIT)); } static inline int xfs_sb_version_hasattr2(xfs_sb_t *sbp) { - return xfs_sb_version_hasmorebits(sbp) && - (sbp->sb_features2 & XFS_SB_VERSION2_ATTR2BIT); + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) || + (xfs_sb_version_hasmorebits(sbp) && + (sbp->sb_features2 & XFS_SB_VERSION2_ATTR2BIT)); } static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp) @@ -499,8 +547,9 @@ static inline int xfs_sb_version_hasprojid32bit(xfs_sb_t *sbp) { - return xfs_sb_version_hasmorebits(sbp) && - (sbp->sb_features2 & XFS_SB_VERSION2_PROJID32BIT); + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) || + (xfs_sb_version_hasmorebits(sbp) && + (sbp->sb_features2 & XFS_SB_VERSION2_PROJID32BIT)); } static inline void xfs_sb_version_addprojid32bit(xfs_sb_t *sbp) @@ -511,12 +560,110 @@ } /* + * Extended v5 superblock feature masks. These are to be used for new v5 + * superblock features only. + * + * Compat features are new features that old kernels will not notice or affect + * and so can mount read-write without issues. + * + * RO-Compat (read only) are features that old kernels can read but will break + * if they write. Hence only read-only mounts of such filesystems are allowed on + * kernels that don't support the feature bit. + * + * InCompat features are features which old kernels will not understand and so + * must not mount. + * + * Log-InCompat features are for changes to log formats or new transactions that + * can't be replayed on older kernels. The fields are set when the filesystem is + * mounted, and a clean unmount clears the fields. + */ +#define XFS_SB_FEAT_COMPAT_ALL 0 +#define XFS_SB_FEAT_COMPAT_UNKNOWN ~XFS_SB_FEAT_COMPAT_ALL +static inline bool +xfs_sb_has_compat_feature( + struct xfs_sb *sbp, + __uint32_t feature) +{ + return (sbp->sb_features_compat & feature) != 0; +} + +#define XFS_SB_FEAT_RO_COMPAT_FINOBT (1 << 0) /* free inode btree */ +#define XFS_SB_FEAT_RO_COMPAT_ALL \ + (XFS_SB_FEAT_RO_COMPAT_FINOBT) +#define XFS_SB_FEAT_RO_COMPAT_UNKNOWN ~XFS_SB_FEAT_RO_COMPAT_ALL +static inline bool +xfs_sb_has_ro_compat_feature( + struct xfs_sb *sbp, + __uint32_t feature) +{ + return (sbp->sb_features_ro_compat & feature) != 0; +} + +#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ +#define XFS_SB_FEAT_INCOMPAT_ALL \ + (XFS_SB_FEAT_INCOMPAT_FTYPE) + +#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL +static inline bool +xfs_sb_has_incompat_feature( + struct xfs_sb *sbp, + __uint32_t feature) +{ + return (sbp->sb_features_incompat & feature) != 0; +} + +#define XFS_SB_FEAT_INCOMPAT_LOG_ALL 0 +#define XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_LOG_ALL +static inline bool +xfs_sb_has_incompat_log_feature( + struct xfs_sb *sbp, + __uint32_t feature) +{ + return (sbp->sb_features_log_incompat & feature) != 0; +} + +/* + * V5 superblock specific feature checks + */ +static inline int xfs_sb_version_hascrc(xfs_sb_t *sbp) +{ + return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5; +} + +static inline int xfs_sb_version_has_pquotino(xfs_sb_t *sbp) +{ + return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5; +} + +static inline int xfs_sb_version_hasftype(struct xfs_sb *sbp) +{ + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 && + xfs_sb_has_incompat_feature(sbp, XFS_SB_FEAT_INCOMPAT_FTYPE)) || + (xfs_sb_version_hasmorebits(sbp) && + (sbp->sb_features2 & XFS_SB_VERSION2_FTYPE)); +} + +static inline int xfs_sb_version_hasfinobt(xfs_sb_t *sbp) +{ + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) && + (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_FINOBT); +} + +/* * end of superblock version macros */ +static inline bool +xfs_is_quota_inode(struct xfs_sb *sbp, xfs_ino_t ino) +{ + return (ino == sbp->sb_uquotino || + ino == sbp->sb_gquotino || + ino == sbp->sb_pquotino); +} + #define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */ #define XFS_SB_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_SB_DADDR) -#define XFS_BUF_TO_SBP(bp) ((xfs_dsb_t *)XFS_BUF_PTR(bp)) +#define XFS_BUF_TO_SBP(bp) ((xfs_dsb_t *)((bp)->b_addr)) #define XFS_HDR_BLOCK(mp,d) ((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d)) #define XFS_DADDR_TO_FSB(mp,d) XFS_AGB_TO_FSB(mp, \ @@ -536,7 +683,6 @@ #define XFS_BB_TO_FSB(mp,bb) \ (((bb) + (XFS_FSB_TO_BB(mp,1) - 1)) >> (mp)->m_blkbb_log) #define XFS_BB_TO_FSBT(mp,bb) ((bb) >> (mp)->m_blkbb_log) -#define XFS_BB_FSB_OFFSET(mp,bb) ((bb) & ((mp)->m_bsize - 1)) /* * File system block to byte conversions. @@ -547,4 +693,20 @@ #define XFS_B_TO_FSBT(mp,b) (((__uint64_t)(b)) >> (mp)->m_sb.sb_blocklog) #define XFS_B_FSB_OFFSET(mp,b) ((b) & (mp)->m_blockmask) +/* + * perag get/put wrappers for ref counting + */ +extern struct xfs_perag *xfs_perag_get(struct xfs_mount *, xfs_agnumber_t); +extern struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *, xfs_agnumber_t, + int tag); +extern void xfs_perag_put(struct xfs_perag *pag); +extern int xfs_initialize_perag_data(struct xfs_mount *, xfs_agnumber_t); + +extern void xfs_sb_calc_crc(struct xfs_buf *); +extern void xfs_mod_sb(struct xfs_trans *, __int64_t); +extern void xfs_sb_mount_common(struct xfs_mount *, struct xfs_sb *); +extern void xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *); +extern void xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t); +extern void xfs_sb_quota_from_disk(struct xfs_sb *sbp); + #endif /* __XFS_SB_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_shared.h xfsprogs-3.2.1ubuntu1/include/xfs_shared.h --- xfsprogs-3.1.9ubuntu2/include/xfs_shared.h 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_shared.h 2014-05-02 00:09:15.000000000 +0000 @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * Copyright (c) 2013 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_SHARED_H__ +#define __XFS_SHARED_H__ + +/* + * Definitions shared between kernel and userspace that don't fit into any other + * header file that is shared with userspace. + */ +struct xfs_ifork; +struct xfs_buf; +struct xfs_buf_ops; +struct xfs_mount; +struct xfs_trans; +struct xfs_inode; + +/* + * Buffer verifier operations are widely used, including userspace tools + */ +extern const struct xfs_buf_ops xfs_agf_buf_ops; +extern const struct xfs_buf_ops xfs_agi_buf_ops; +extern const struct xfs_buf_ops xfs_agf_buf_ops; +extern const struct xfs_buf_ops xfs_agfl_buf_ops; +extern const struct xfs_buf_ops xfs_allocbt_buf_ops; +extern const struct xfs_buf_ops xfs_attr3_leaf_buf_ops; +extern const struct xfs_buf_ops xfs_attr3_rmt_buf_ops; +extern const struct xfs_buf_ops xfs_bmbt_buf_ops; +extern const struct xfs_buf_ops xfs_da3_node_buf_ops; +extern const struct xfs_buf_ops xfs_dquot_buf_ops; +extern const struct xfs_buf_ops xfs_symlink_buf_ops; +extern const struct xfs_buf_ops xfs_agi_buf_ops; +extern const struct xfs_buf_ops xfs_inobt_buf_ops; +extern const struct xfs_buf_ops xfs_inode_buf_ops; +extern const struct xfs_buf_ops xfs_inode_buf_ra_ops; +extern const struct xfs_buf_ops xfs_dquot_buf_ops; +extern const struct xfs_buf_ops xfs_sb_buf_ops; +extern const struct xfs_buf_ops xfs_sb_quiet_buf_ops; +extern const struct xfs_buf_ops xfs_symlink_buf_ops; + +/* + * Transaction types. Used to distinguish types of buffers. These never reach + * the log. + */ +#define XFS_TRANS_SETATTR_NOT_SIZE 1 +#define XFS_TRANS_SETATTR_SIZE 2 +#define XFS_TRANS_INACTIVE 3 +#define XFS_TRANS_CREATE 4 +#define XFS_TRANS_CREATE_TRUNC 5 +#define XFS_TRANS_TRUNCATE_FILE 6 +#define XFS_TRANS_REMOVE 7 +#define XFS_TRANS_LINK 8 +#define XFS_TRANS_RENAME 9 +#define XFS_TRANS_MKDIR 10 +#define XFS_TRANS_RMDIR 11 +#define XFS_TRANS_SYMLINK 12 +#define XFS_TRANS_SET_DMATTRS 13 +#define XFS_TRANS_GROWFS 14 +#define XFS_TRANS_STRAT_WRITE 15 +#define XFS_TRANS_DIOSTRAT 16 +/* 17 was XFS_TRANS_WRITE_SYNC */ +#define XFS_TRANS_WRITEID 18 +#define XFS_TRANS_ADDAFORK 19 +#define XFS_TRANS_ATTRINVAL 20 +#define XFS_TRANS_ATRUNCATE 21 +#define XFS_TRANS_ATTR_SET 22 +#define XFS_TRANS_ATTR_RM 23 +#define XFS_TRANS_ATTR_FLAG 24 +#define XFS_TRANS_CLEAR_AGI_BUCKET 25 +#define XFS_TRANS_QM_SBCHANGE 26 +/* + * Dummy entries since we use the transaction type to index into the + * trans_type[] in xlog_recover_print_trans_head() + */ +#define XFS_TRANS_DUMMY1 27 +#define XFS_TRANS_DUMMY2 28 +#define XFS_TRANS_QM_QUOTAOFF 29 +#define XFS_TRANS_QM_DQALLOC 30 +#define XFS_TRANS_QM_SETQLIM 31 +#define XFS_TRANS_QM_DQCLUSTER 32 +#define XFS_TRANS_QM_QINOCREATE 33 +#define XFS_TRANS_QM_QUOTAOFF_END 34 +#define XFS_TRANS_SB_UNIT 35 +#define XFS_TRANS_FSYNC_TS 36 +#define XFS_TRANS_GROWFSRT_ALLOC 37 +#define XFS_TRANS_GROWFSRT_ZERO 38 +#define XFS_TRANS_GROWFSRT_FREE 39 +#define XFS_TRANS_SWAPEXT 40 +#define XFS_TRANS_SB_COUNT 41 +#define XFS_TRANS_CHECKPOINT 42 +#define XFS_TRANS_ICREATE 43 +#define XFS_TRANS_TYPE_MAX 43 +/* new transaction types need to be reflected in xfs_logprint(8) */ + +#define XFS_TRANS_TYPES \ + { XFS_TRANS_SETATTR_NOT_SIZE, "SETATTR_NOT_SIZE" }, \ + { XFS_TRANS_SETATTR_SIZE, "SETATTR_SIZE" }, \ + { XFS_TRANS_INACTIVE, "INACTIVE" }, \ + { XFS_TRANS_CREATE, "CREATE" }, \ + { XFS_TRANS_CREATE_TRUNC, "CREATE_TRUNC" }, \ + { XFS_TRANS_TRUNCATE_FILE, "TRUNCATE_FILE" }, \ + { XFS_TRANS_REMOVE, "REMOVE" }, \ + { XFS_TRANS_LINK, "LINK" }, \ + { XFS_TRANS_RENAME, "RENAME" }, \ + { XFS_TRANS_MKDIR, "MKDIR" }, \ + { XFS_TRANS_RMDIR, "RMDIR" }, \ + { XFS_TRANS_SYMLINK, "SYMLINK" }, \ + { XFS_TRANS_SET_DMATTRS, "SET_DMATTRS" }, \ + { XFS_TRANS_GROWFS, "GROWFS" }, \ + { XFS_TRANS_STRAT_WRITE, "STRAT_WRITE" }, \ + { XFS_TRANS_DIOSTRAT, "DIOSTRAT" }, \ + { XFS_TRANS_WRITEID, "WRITEID" }, \ + { XFS_TRANS_ADDAFORK, "ADDAFORK" }, \ + { XFS_TRANS_ATTRINVAL, "ATTRINVAL" }, \ + { XFS_TRANS_ATRUNCATE, "ATRUNCATE" }, \ + { XFS_TRANS_ATTR_SET, "ATTR_SET" }, \ + { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \ + { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \ + { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \ + { XFS_TRANS_QM_SBCHANGE, "QM_SBCHANGE" }, \ + { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \ + { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \ + { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \ + { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \ + { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \ + { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \ + { XFS_TRANS_SB_UNIT, "SB_UNIT" }, \ + { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \ + { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \ + { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \ + { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \ + { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \ + { XFS_TRANS_SB_COUNT, "SB_COUNT" }, \ + { XFS_TRANS_CHECKPOINT, "CHECKPOINT" }, \ + { XFS_TRANS_DUMMY1, "DUMMY1" }, \ + { XFS_TRANS_DUMMY2, "DUMMY2" }, \ + { XLOG_UNMOUNT_REC_TYPE, "UNMOUNT" } + +/* + * This structure is used to track log items associated with + * a transaction. It points to the log item and keeps some + * flags to track the state of the log item. It also tracks + * the amount of space needed to log the item it describes + * once we get to commit processing (see xfs_trans_commit()). + */ +struct xfs_log_item_desc { + struct xfs_log_item *lid_item; + struct list_head lid_trans; + unsigned char lid_flags; +}; + +#define XFS_LID_DIRTY 0x1 + +/* log size calculation functions */ +int xfs_log_calc_unit_res(struct xfs_mount *mp, int unit_bytes); +int xfs_log_calc_minimum_size(struct xfs_mount *); + + +/* + * Values for t_flags. + */ +#define XFS_TRANS_DIRTY 0x01 /* something needs to be logged */ +#define XFS_TRANS_SB_DIRTY 0x02 /* superblock is modified */ +#define XFS_TRANS_PERM_LOG_RES 0x04 /* xact took a permanent log res */ +#define XFS_TRANS_SYNC 0x08 /* make commit synchronous */ +#define XFS_TRANS_DQ_DIRTY 0x10 /* at least one dquot in trx dirty */ +#define XFS_TRANS_RESERVE 0x20 /* OK to use reserved data blocks */ +#define XFS_TRANS_FREEZE_PROT 0x40 /* Transaction has elevated writer + count in superblock */ +/* + * Values for call flags parameter. + */ +#define XFS_TRANS_RELEASE_LOG_RES 0x4 +#define XFS_TRANS_ABORT 0x8 + +/* + * Field values for xfs_trans_mod_sb. + */ +#define XFS_TRANS_SB_ICOUNT 0x00000001 +#define XFS_TRANS_SB_IFREE 0x00000002 +#define XFS_TRANS_SB_FDBLOCKS 0x00000004 +#define XFS_TRANS_SB_RES_FDBLOCKS 0x00000008 +#define XFS_TRANS_SB_FREXTENTS 0x00000010 +#define XFS_TRANS_SB_RES_FREXTENTS 0x00000020 +#define XFS_TRANS_SB_DBLOCKS 0x00000040 +#define XFS_TRANS_SB_AGCOUNT 0x00000080 +#define XFS_TRANS_SB_IMAXPCT 0x00000100 +#define XFS_TRANS_SB_REXTSIZE 0x00000200 +#define XFS_TRANS_SB_RBMBLOCKS 0x00000400 +#define XFS_TRANS_SB_RBLOCKS 0x00000800 +#define XFS_TRANS_SB_REXTENTS 0x00001000 +#define XFS_TRANS_SB_REXTSLOG 0x00002000 + +/* + * Here we centralize the specification of XFS meta-data buffer reference count + * values. This determine how hard the buffer cache tries to hold onto the + * buffer. + */ +#define XFS_AGF_REF 4 +#define XFS_AGI_REF 4 +#define XFS_AGFL_REF 3 +#define XFS_INO_BTREE_REF 3 +#define XFS_ALLOC_BTREE_REF 2 +#define XFS_BMAP_BTREE_REF 2 +#define XFS_DIR_BTREE_REF 2 +#define XFS_INO_REF 2 +#define XFS_ATTR_BTREE_REF 1 +#define XFS_DQUOT_REF 1 + +/* + * Flags for xfs_trans_ichgtime(). + */ +#define XFS_ICHGTIME_MOD 0x1 /* data fork modification timestamp */ +#define XFS_ICHGTIME_CHG 0x2 /* inode field change timestamp */ +#define XFS_ICHGTIME_CREATE 0x4 /* inode create timestamp */ + + +/* + * Symlink decoding/encoding functions + */ +int xfs_symlink_blocks(struct xfs_mount *mp, int pathlen); +int xfs_symlink_hdr_set(struct xfs_mount *mp, xfs_ino_t ino, uint32_t offset, + uint32_t size, struct xfs_buf *bp); +bool xfs_symlink_hdr_ok(struct xfs_mount *mp, xfs_ino_t ino, uint32_t offset, + uint32_t size, struct xfs_buf *bp); +void xfs_symlink_local_to_remote(struct xfs_trans *tp, struct xfs_buf *bp, + struct xfs_inode *ip, struct xfs_ifork *ifp); + +#endif /* __XFS_SHARED_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_trace.h xfsprogs-3.2.1ubuntu1/include/xfs_trace.h --- xfsprogs-3.1.9ubuntu2/include/xfs_trace.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_trace.h 2013-10-10 21:07:17.000000000 +0000 @@ -26,11 +26,14 @@ #define trace_xfs_alloc_near_greater(a) ((void) 0) #define trace_xfs_alloc_near_lesser(a) ((void) 0) #define trace_xfs_alloc_near_error(a) ((void) 0) +#define trace_xfs_alloc_near_noentry(a) ((void) 0) +#define trace_xfs_alloc_near_busy(a) ((void) 0) #define trace_xfs_alloc_size_neither(a) ((void) 0) #define trace_xfs_alloc_size_noentry(a) ((void) 0) #define trace_xfs_alloc_size_nominleft(a) ((void) 0) #define trace_xfs_alloc_size_done(a) ((void) 0) #define trace_xfs_alloc_size_error(a) ((void) 0) +#define trace_xfs_alloc_size_busy(a) ((void) 0) #define trace_xfs_alloc_small_freelist(a) ((void) 0) #define trace_xfs_alloc_small_notenough(a) ((void) 0) #define trace_xfs_alloc_small_done(a) ((void) 0) @@ -91,12 +94,75 @@ #define trace_xfs_dir2_sf_toino4(a) ((void) 0) #define trace_xfs_dir2_sf_toino8(a) ((void) 0) +#define trace_xfs_da_node_create(a) ((void) 0) +#define trace_xfs_da_split(a) ((void) 0) +#define trace_xfs_attr_leaf_split_before(a) ((void) 0) +#define trace_xfs_attr_leaf_split_after(a) ((void) 0) +#define trace_xfs_da_root_split(a) ((void) 0) +#define trace_xfs_da_node_split(a) ((void) 0) +#define trace_xfs_da_node_rebalance(a) ((void) 0) +#define trace_xfs_da_node_add(a) ((void) 0) +#define trace_xfs_da_join(a) ((void) 0) +#define trace_xfs_da_root_join(a) ((void) 0) +#define trace_xfs_da_node_toosmall(a) ((void) 0) +#define trace_xfs_da_fixhashpath(a) ((void) 0) +#define trace_xfs_da_node_remove(a) ((void) 0) +#define trace_xfs_da_node_unbalance(a) ((void) 0) +#define trace_xfs_da_link_before(a) ((void) 0) +#define trace_xfs_da_link_after(a) ((void) 0) +#define trace_xfs_da_unlink_back(a) ((void) 0) +#define trace_xfs_da_unlink_forward(a) ((void) 0) +#define trace_xfs_da_path_shift(a) ((void) 0) +#define trace_xfs_da_grow_inode(a) ((void) 0) +#define trace_xfs_da_swap_lastblock(a) ((void) 0) +#define trace_xfs_da_shrink_inode(a) ((void) 0) + +#define trace_xfs_attr_sf_create(a) ((void) 0) +#define trace_xfs_attr_sf_add(a) ((void) 0) +#define trace_xfs_attr_sf_remove(a) ((void) 0) +#define trace_xfs_attr_sf_lookup(a) ((void) 0) +#define trace_xfs_attr_sf_to_leaf(a) ((void) 0) +#define trace_xfs_attr_leaf_to_sf(a) ((void) 0) +#define trace_xfs_attr_leaf_to_node(a) ((void) 0) +#define trace_xfs_attr_leaf_create(a) ((void) 0) +#define trace_xfs_attr_leaf_split(a) ((void) 0) +#define trace_xfs_attr_leaf_add_old(a) ((void) 0) +#define trace_xfs_attr_leaf_add_new(a) ((void) 0) +#define trace_xfs_attr_leaf_add(a) ((void) 0) +#define trace_xfs_attr_leaf_add_work(a) ((void) 0) +#define trace_xfs_attr_leaf_compact(a) ((void) 0) +#define trace_xfs_attr_leaf_rebalance(a) ((void) 0) +#define trace_xfs_attr_leaf_toosmall(a) ((void) 0) +#define trace_xfs_attr_leaf_remove(a) ((void) 0) +#define trace_xfs_attr_leaf_unbalance(a) ((void) 0) +#define trace_xfs_attr_leaf_lookup(a) ((void) 0) +#define trace_xfs_attr_leaf_clearflag(a) ((void) 0) +#define trace_xfs_attr_leaf_setflag(a) ((void) 0) +#define trace_xfs_attr_leaf_flipflags(a) ((void) 0) + +#define trace_xfs_attr_sf_addname(a) ((void) 0) +#define trace_xfs_attr_leaf_addname(a) ((void) 0) +#define trace_xfs_attr_leaf_replace(a) ((void) 0) +#define trace_xfs_attr_leaf_removename(a) ((void) 0) +#define trace_xfs_attr_leaf_get(a) ((void) 0) +#define trace_xfs_attr_node_addname(a) ((void) 0) +#define trace_xfs_attr_node_replace(a) ((void) 0) +#define trace_xfs_attr_node_removename(a) ((void) 0) +#define trace_xfs_attr_fillstate(a) ((void) 0) +#define trace_xfs_attr_refillstate(a) ((void) 0) +#define trace_xfs_attr_node_get(a) ((void) 0) +#define trace_xfs_attr_rmtval_get(a) ((void) 0) +#define trace_xfs_attr_rmtval_set(a) ((void) 0) +#define trace_xfs_attr_rmtval_remove(a) ((void) 0) + #define trace_xfs_bmap_pre_update(a,b,c,d) ((void) 0) #define trace_xfs_bmap_post_update(a,b,c,d) ((void) 0) #define trace_xfs_extlist(a,b,c,d) ((void) 0) #define trace_xfs_bunmap(a,b,c,d,e) ((void) 0) -#define trace_xfs_perag_get(a,b,c,d) ((void) 0) -#define trace_xfs_perag_put(a,b,c,d) ((void) 0) +/* set c = c to avoid unused var warnings */ +#define trace_xfs_perag_get(a,b,c,d) ((c) = (c)) +#define trace_xfs_perag_get_tag(a,b,c,d) ((c) = (c)) +#define trace_xfs_perag_put(a,b,c,d) ((c) = (c)) #endif /* __TRACE_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_trans.h xfsprogs-3.2.1ubuntu1/include/xfs_trans.h --- xfsprogs-3.1.9ubuntu2/include/xfs_trans.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_trans.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,508 +0,0 @@ -/* - * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_TRANS_H__ -#define __XFS_TRANS_H__ - -struct xfs_log_item; - -/* - * This is the structure written in the log at the head of - * every transaction. It identifies the type and id of the - * transaction, and contains the number of items logged by - * the transaction so we know how many to expect during recovery. - * - * Do not change the below structure without redoing the code in - * xlog_recover_add_to_trans() and xlog_recover_add_to_cont_trans(). - */ -typedef struct xfs_trans_header { - uint th_magic; /* magic number */ - uint th_type; /* transaction type */ - __int32_t th_tid; /* transaction id (unused) */ - uint th_num_items; /* num items logged by trans */ -} xfs_trans_header_t; - -#define XFS_TRANS_HEADER_MAGIC 0x5452414e /* TRAN */ - -/* - * Log item types. - */ -#define XFS_LI_EFI 0x1236 -#define XFS_LI_EFD 0x1237 -#define XFS_LI_IUNLINK 0x1238 -#define XFS_LI_INODE 0x123b /* aligned ino chunks, var-size ibufs */ -#define XFS_LI_BUF 0x123c /* v2 bufs, variable sized inode bufs */ -#define XFS_LI_DQUOT 0x123d -#define XFS_LI_QUOTAOFF 0x123e - -#define XFS_LI_TYPE_DESC \ - { XFS_LI_EFI, "XFS_LI_EFI" }, \ - { XFS_LI_EFD, "XFS_LI_EFD" }, \ - { XFS_LI_IUNLINK, "XFS_LI_IUNLINK" }, \ - { XFS_LI_INODE, "XFS_LI_INODE" }, \ - { XFS_LI_BUF, "XFS_LI_BUF" }, \ - { XFS_LI_DQUOT, "XFS_LI_DQUOT" }, \ - { XFS_LI_QUOTAOFF, "XFS_LI_QUOTAOFF" } - -/* - * Transaction types. Used to distinguish types of buffers. - */ -#define XFS_TRANS_SETATTR_NOT_SIZE 1 -#define XFS_TRANS_SETATTR_SIZE 2 -#define XFS_TRANS_INACTIVE 3 -#define XFS_TRANS_CREATE 4 -#define XFS_TRANS_CREATE_TRUNC 5 -#define XFS_TRANS_TRUNCATE_FILE 6 -#define XFS_TRANS_REMOVE 7 -#define XFS_TRANS_LINK 8 -#define XFS_TRANS_RENAME 9 -#define XFS_TRANS_MKDIR 10 -#define XFS_TRANS_RMDIR 11 -#define XFS_TRANS_SYMLINK 12 -#define XFS_TRANS_SET_DMATTRS 13 -#define XFS_TRANS_GROWFS 14 -#define XFS_TRANS_STRAT_WRITE 15 -#define XFS_TRANS_DIOSTRAT 16 -/* 17 was XFS_TRANS_WRITE_SYNC */ -#define XFS_TRANS_WRITEID 18 -#define XFS_TRANS_ADDAFORK 19 -#define XFS_TRANS_ATTRINVAL 20 -#define XFS_TRANS_ATRUNCATE 21 -#define XFS_TRANS_ATTR_SET 22 -#define XFS_TRANS_ATTR_RM 23 -#define XFS_TRANS_ATTR_FLAG 24 -#define XFS_TRANS_CLEAR_AGI_BUCKET 25 -#define XFS_TRANS_QM_SBCHANGE 26 -/* - * Dummy entries since we use the transaction type to index into the - * trans_type[] in xlog_recover_print_trans_head() - */ -#define XFS_TRANS_DUMMY1 27 -#define XFS_TRANS_DUMMY2 28 -#define XFS_TRANS_QM_QUOTAOFF 29 -#define XFS_TRANS_QM_DQALLOC 30 -#define XFS_TRANS_QM_SETQLIM 31 -#define XFS_TRANS_QM_DQCLUSTER 32 -#define XFS_TRANS_QM_QINOCREATE 33 -#define XFS_TRANS_QM_QUOTAOFF_END 34 -#define XFS_TRANS_SB_UNIT 35 -#define XFS_TRANS_FSYNC_TS 36 -#define XFS_TRANS_GROWFSRT_ALLOC 37 -#define XFS_TRANS_GROWFSRT_ZERO 38 -#define XFS_TRANS_GROWFSRT_FREE 39 -#define XFS_TRANS_SWAPEXT 40 -#define XFS_TRANS_SB_COUNT 41 -#define XFS_TRANS_CHECKPOINT 42 -#define XFS_TRANS_TYPE_MAX 42 -/* new transaction types need to be reflected in xfs_logprint(8) */ - -#define XFS_TRANS_TYPES \ - { XFS_TRANS_SETATTR_NOT_SIZE, "SETATTR_NOT_SIZE" }, \ - { XFS_TRANS_SETATTR_SIZE, "SETATTR_SIZE" }, \ - { XFS_TRANS_INACTIVE, "INACTIVE" }, \ - { XFS_TRANS_CREATE, "CREATE" }, \ - { XFS_TRANS_CREATE_TRUNC, "CREATE_TRUNC" }, \ - { XFS_TRANS_TRUNCATE_FILE, "TRUNCATE_FILE" }, \ - { XFS_TRANS_REMOVE, "REMOVE" }, \ - { XFS_TRANS_LINK, "LINK" }, \ - { XFS_TRANS_RENAME, "RENAME" }, \ - { XFS_TRANS_MKDIR, "MKDIR" }, \ - { XFS_TRANS_RMDIR, "RMDIR" }, \ - { XFS_TRANS_SYMLINK, "SYMLINK" }, \ - { XFS_TRANS_SET_DMATTRS, "SET_DMATTRS" }, \ - { XFS_TRANS_GROWFS, "GROWFS" }, \ - { XFS_TRANS_STRAT_WRITE, "STRAT_WRITE" }, \ - { XFS_TRANS_DIOSTRAT, "DIOSTRAT" }, \ - { XFS_TRANS_WRITEID, "WRITEID" }, \ - { XFS_TRANS_ADDAFORK, "ADDAFORK" }, \ - { XFS_TRANS_ATTRINVAL, "ATTRINVAL" }, \ - { XFS_TRANS_ATRUNCATE, "ATRUNCATE" }, \ - { XFS_TRANS_ATTR_SET, "ATTR_SET" }, \ - { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \ - { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \ - { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \ - { XFS_TRANS_QM_SBCHANGE, "QM_SBCHANGE" }, \ - { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \ - { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \ - { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \ - { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \ - { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \ - { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \ - { XFS_TRANS_SB_UNIT, "SB_UNIT" }, \ - { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \ - { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \ - { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \ - { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \ - { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \ - { XFS_TRANS_SB_COUNT, "SB_COUNT" }, \ - { XFS_TRANS_CHECKPOINT, "CHECKPOINT" }, \ - { XFS_TRANS_DUMMY1, "DUMMY1" }, \ - { XFS_TRANS_DUMMY2, "DUMMY2" }, \ - { XLOG_UNMOUNT_REC_TYPE, "UNMOUNT" } - -/* - * This structure is used to track log items associated with - * a transaction. It points to the log item and keeps some - * flags to track the state of the log item. It also tracks - * the amount of space needed to log the item it describes - * once we get to commit processing (see xfs_trans_commit()). - */ -struct xfs_log_item_desc { - struct xfs_log_item *lid_item; - ushort lid_size; - unsigned char lid_flags; - struct list_head lid_trans; -}; - -#define XFS_LID_DIRTY 0x1 - -#define XFS_TRANS_MAGIC 0x5452414E /* 'TRAN' */ -/* - * Values for t_flags. - */ -#define XFS_TRANS_DIRTY 0x01 /* something needs to be logged */ -#define XFS_TRANS_SB_DIRTY 0x02 /* superblock is modified */ -#define XFS_TRANS_PERM_LOG_RES 0x04 /* xact took a permanent log res */ -#define XFS_TRANS_SYNC 0x08 /* make commit synchronous */ -#define XFS_TRANS_DQ_DIRTY 0x10 /* at least one dquot in trx dirty */ -#define XFS_TRANS_RESERVE 0x20 /* OK to use reserved data blocks */ - -/* - * Values for call flags parameter. - */ -#define XFS_TRANS_RELEASE_LOG_RES 0x4 -#define XFS_TRANS_ABORT 0x8 - -/* - * Field values for xfs_trans_mod_sb. - */ -#define XFS_TRANS_SB_ICOUNT 0x00000001 -#define XFS_TRANS_SB_IFREE 0x00000002 -#define XFS_TRANS_SB_FDBLOCKS 0x00000004 -#define XFS_TRANS_SB_RES_FDBLOCKS 0x00000008 -#define XFS_TRANS_SB_FREXTENTS 0x00000010 -#define XFS_TRANS_SB_RES_FREXTENTS 0x00000020 -#define XFS_TRANS_SB_DBLOCKS 0x00000040 -#define XFS_TRANS_SB_AGCOUNT 0x00000080 -#define XFS_TRANS_SB_IMAXPCT 0x00000100 -#define XFS_TRANS_SB_REXTSIZE 0x00000200 -#define XFS_TRANS_SB_RBMBLOCKS 0x00000400 -#define XFS_TRANS_SB_RBLOCKS 0x00000800 -#define XFS_TRANS_SB_REXTENTS 0x00001000 -#define XFS_TRANS_SB_REXTSLOG 0x00002000 - - -/* - * Per-extent log reservation for the allocation btree changes - * involved in freeing or allocating an extent. - * 2 trees * (2 blocks/level * max depth - 1) * block size - */ -#define XFS_ALLOCFREE_LOG_RES(mp,nx) \ - ((nx) * (2 * XFS_FSB_TO_B((mp), 2 * XFS_AG_MAXLEVELS(mp) - 1))) -#define XFS_ALLOCFREE_LOG_COUNT(mp,nx) \ - ((nx) * (2 * (2 * XFS_AG_MAXLEVELS(mp) - 1))) - -/* - * Per-directory log reservation for any directory change. - * dir blocks: (1 btree block per level + data block + free block) * dblock size - * bmap btree: (levels + 2) * max depth * block size - * v2 directory blocks can be fragmented below the dirblksize down to the fsb - * size, so account for that in the DAENTER macros. - */ -#define XFS_DIROP_LOG_RES(mp) \ - (XFS_FSB_TO_B(mp, XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK)) + \ - (XFS_FSB_TO_B(mp, XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1))) -#define XFS_DIROP_LOG_COUNT(mp) \ - (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \ - XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1) - - -#define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write) -#define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate) -#define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename) -#define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link) -#define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove) -#define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink) -#define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create) -#define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir) -#define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree) -#define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange) -#define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata) -#define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc) -#define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero) -#define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree) -#define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) -/* - * Logging the inode timestamps on an fsync -- same as SWRITE - * as long as SWRITE logs the entire inode core - */ -#define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) -#define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) -#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) -#define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval) -#define XFS_ATTRSET_LOG_RES(mp, ext) \ - ((mp)->m_reservations.tr_attrset + \ - (ext * (mp)->m_sb.sb_sectsize) + \ - (ext * XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))) + \ - (128 * (ext + (ext * XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))))) -#define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm) -#define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi) - - -/* - * Various log count values. - */ -#define XFS_DEFAULT_LOG_COUNT 1 -#define XFS_DEFAULT_PERM_LOG_COUNT 2 -#define XFS_ITRUNCATE_LOG_COUNT 2 -#define XFS_INACTIVE_LOG_COUNT 2 -#define XFS_CREATE_LOG_COUNT 2 -#define XFS_MKDIR_LOG_COUNT 3 -#define XFS_SYMLINK_LOG_COUNT 3 -#define XFS_REMOVE_LOG_COUNT 2 -#define XFS_LINK_LOG_COUNT 2 -#define XFS_RENAME_LOG_COUNT 2 -#define XFS_WRITE_LOG_COUNT 2 -#define XFS_ADDAFORK_LOG_COUNT 2 -#define XFS_ATTRINVAL_LOG_COUNT 1 -#define XFS_ATTRSET_LOG_COUNT 3 -#define XFS_ATTRRM_LOG_COUNT 3 - -/* - * Here we centralize the specification of XFS meta-data buffer - * reference count values. This determine how hard the buffer - * cache tries to hold onto the buffer. - */ -#define XFS_AGF_REF 4 -#define XFS_AGI_REF 4 -#define XFS_AGFL_REF 3 -#define XFS_INO_BTREE_REF 3 -#define XFS_ALLOC_BTREE_REF 2 -#define XFS_BMAP_BTREE_REF 2 -#define XFS_DIR_BTREE_REF 2 -#define XFS_INO_REF 2 -#define XFS_ATTR_BTREE_REF 1 -#define XFS_DQUOT_REF 1 - -#ifdef __KERNEL__ - -struct xfs_buf; -struct xfs_buftarg; -struct xfs_efd_log_item; -struct xfs_efi_log_item; -struct xfs_inode; -struct xfs_item_ops; -struct xfs_log_iovec; -struct xfs_log_item_desc; -struct xfs_mount; -struct xfs_trans; -struct xfs_dquot_acct; -struct xfs_busy_extent; - -typedef struct xfs_log_item { - struct list_head li_ail; /* AIL pointers */ - xfs_lsn_t li_lsn; /* last on-disk lsn */ - struct xfs_log_item_desc *li_desc; /* ptr to current desc*/ - struct xfs_mount *li_mountp; /* ptr to fs mount */ - struct xfs_ail *li_ailp; /* ptr to AIL */ - uint li_type; /* item type */ - uint li_flags; /* misc flags */ - struct xfs_log_item *li_bio_list; /* buffer item list */ - void (*li_cb)(struct xfs_buf *, - struct xfs_log_item *); - /* buffer item iodone */ - /* callback func */ - struct xfs_item_ops *li_ops; /* function list */ - - /* delayed logging */ - struct list_head li_cil; /* CIL pointers */ - struct xfs_log_vec *li_lv; /* active log vector */ - xfs_lsn_t li_seq; /* CIL commit seq */ -} xfs_log_item_t; - -#define XFS_LI_IN_AIL 0x1 -#define XFS_LI_ABORTED 0x2 - -#define XFS_LI_FLAGS \ - { XFS_LI_IN_AIL, "IN_AIL" }, \ - { XFS_LI_ABORTED, "ABORTED" } - -typedef struct xfs_item_ops { - uint (*iop_size)(xfs_log_item_t *); - void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); - void (*iop_pin)(xfs_log_item_t *); - void (*iop_unpin)(xfs_log_item_t *, int remove); - uint (*iop_trylock)(xfs_log_item_t *); - void (*iop_unlock)(xfs_log_item_t *); - xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t); - void (*iop_push)(xfs_log_item_t *); - void (*iop_pushbuf)(xfs_log_item_t *); - void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); -} xfs_item_ops_t; - -#define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip) -#define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp) -#define IOP_PIN(ip) (*(ip)->li_ops->iop_pin)(ip) -#define IOP_UNPIN(ip, remove) (*(ip)->li_ops->iop_unpin)(ip, remove) -#define IOP_TRYLOCK(ip) (*(ip)->li_ops->iop_trylock)(ip) -#define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip) -#define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn) -#define IOP_PUSH(ip) (*(ip)->li_ops->iop_push)(ip) -#define IOP_PUSHBUF(ip) (*(ip)->li_ops->iop_pushbuf)(ip) -#define IOP_COMMITTING(ip, lsn) (*(ip)->li_ops->iop_committing)(ip, lsn) - -/* - * Return values for the IOP_TRYLOCK() routines. - */ -#define XFS_ITEM_SUCCESS 0 -#define XFS_ITEM_PINNED 1 -#define XFS_ITEM_LOCKED 2 -#define XFS_ITEM_PUSHBUF 3 - -/* - * This is the type of function which can be given to xfs_trans_callback() - * to be called upon the transaction's commit to disk. - */ -typedef void (*xfs_trans_callback_t)(struct xfs_trans *, void *); - -/* - * This is the structure maintained for every active transaction. - */ -typedef struct xfs_trans { - unsigned int t_magic; /* magic number */ - xfs_log_callback_t t_logcb; /* log callback struct */ - unsigned int t_type; /* transaction type */ - unsigned int t_log_res; /* amt of log space resvd */ - unsigned int t_log_count; /* count for perm log res */ - unsigned int t_blk_res; /* # of blocks resvd */ - unsigned int t_blk_res_used; /* # of resvd blocks used */ - unsigned int t_rtx_res; /* # of rt extents resvd */ - unsigned int t_rtx_res_used; /* # of resvd rt extents used */ - struct xlog_ticket *t_ticket; /* log mgr ticket */ - xfs_lsn_t t_lsn; /* log seq num of start of - * transaction. */ - xfs_lsn_t t_commit_lsn; /* log seq num of end of - * transaction. */ - struct xfs_mount *t_mountp; /* ptr to fs mount struct */ - struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */ - unsigned int t_flags; /* misc flags */ - int64_t t_icount_delta; /* superblock icount change */ - int64_t t_ifree_delta; /* superblock ifree change */ - int64_t t_fdblocks_delta; /* superblock fdblocks chg */ - int64_t t_res_fdblocks_delta; /* on-disk only chg */ - int64_t t_frextents_delta;/* superblock freextents chg*/ - int64_t t_res_frextents_delta; /* on-disk only chg */ -#ifdef DEBUG - int64_t t_ag_freeblks_delta; /* debugging counter */ - int64_t t_ag_flist_delta; /* debugging counter */ - int64_t t_ag_btree_delta; /* debugging counter */ -#endif - int64_t t_dblocks_delta;/* superblock dblocks change */ - int64_t t_agcount_delta;/* superblock agcount change */ - int64_t t_imaxpct_delta;/* superblock imaxpct change */ - int64_t t_rextsize_delta;/* superblock rextsize chg */ - int64_t t_rbmblocks_delta;/* superblock rbmblocks chg */ - int64_t t_rblocks_delta;/* superblock rblocks change */ - int64_t t_rextents_delta;/* superblocks rextents chg */ - int64_t t_rextslog_delta;/* superblocks rextslog chg */ - struct list_head t_items; /* log item descriptors */ - xfs_trans_header_t t_header; /* header for in-log trans */ - struct list_head t_busy; /* list of busy extents */ - unsigned long t_pflags; /* saved process flags state */ -} xfs_trans_t; - -/* - * XFS transaction mechanism exported interfaces that are - * actually macros. - */ -#define xfs_trans_get_log_res(tp) ((tp)->t_log_res) -#define xfs_trans_get_log_count(tp) ((tp)->t_log_count) -#define xfs_trans_get_block_res(tp) ((tp)->t_blk_res) -#define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC) - -#ifdef DEBUG -#define xfs_trans_agblocks_delta(tp, d) ((tp)->t_ag_freeblks_delta += (int64_t)d) -#define xfs_trans_agflist_delta(tp, d) ((tp)->t_ag_flist_delta += (int64_t)d) -#define xfs_trans_agbtree_delta(tp, d) ((tp)->t_ag_btree_delta += (int64_t)d) -#else -#define xfs_trans_agblocks_delta(tp, d) -#define xfs_trans_agflist_delta(tp, d) -#define xfs_trans_agbtree_delta(tp, d) -#endif - -/* - * XFS transaction mechanism exported interfaces. - */ -xfs_trans_t *xfs_trans_alloc(struct xfs_mount *, uint); -xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint, uint); -xfs_trans_t *xfs_trans_dup(xfs_trans_t *); -int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, - uint, uint); -void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t); -struct xfs_buf *xfs_trans_get_buf(xfs_trans_t *, struct xfs_buftarg *, xfs_daddr_t, - int, uint); -int xfs_trans_read_buf(struct xfs_mount *, xfs_trans_t *, - struct xfs_buftarg *, xfs_daddr_t, int, uint, - struct xfs_buf **); -struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int); - -void xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *); -void xfs_trans_bjoin(xfs_trans_t *, struct xfs_buf *); -void xfs_trans_bhold(xfs_trans_t *, struct xfs_buf *); -void xfs_trans_bhold_release(xfs_trans_t *, struct xfs_buf *); -void xfs_trans_binval(xfs_trans_t *, struct xfs_buf *); -void xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *); -void xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *); -void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint); -void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *); -int xfs_trans_iget(struct xfs_mount *, xfs_trans_t *, - xfs_ino_t , uint, uint, struct xfs_inode **); -void xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int); -void xfs_trans_ijoin_ref(struct xfs_trans *, struct xfs_inode *, uint); -void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *); -void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint); -void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint); -struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint); -void xfs_efi_release(struct xfs_efi_log_item *, uint); -void xfs_trans_log_efi_extent(xfs_trans_t *, - struct xfs_efi_log_item *, - xfs_fsblock_t, - xfs_extlen_t); -struct xfs_efd_log_item *xfs_trans_get_efd(xfs_trans_t *, - struct xfs_efi_log_item *, - uint); -void xfs_trans_log_efd_extent(xfs_trans_t *, - struct xfs_efd_log_item *, - xfs_fsblock_t, - xfs_extlen_t); -int _xfs_trans_commit(xfs_trans_t *, - uint flags, - int *); -#define xfs_trans_commit(tp, flags) _xfs_trans_commit(tp, flags, NULL) -void xfs_trans_cancel(xfs_trans_t *, int); -int xfs_trans_ail_init(struct xfs_mount *); -void xfs_trans_ail_destroy(struct xfs_mount *); - -extern kmem_zone_t *xfs_trans_zone; -extern kmem_zone_t *xfs_log_item_desc_zone; - -#endif /* __KERNEL__ */ - -void xfs_trans_init(struct xfs_mount *); -int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *); - -#endif /* __XFS_TRANS_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_trans_resv.h xfsprogs-3.2.1ubuntu1/include/xfs_trans_resv.h --- xfsprogs-3.1.9ubuntu2/include/xfs_trans_resv.h 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_trans_resv.h 2013-10-10 21:07:17.000000000 +0000 @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_TRANS_RESV_H__ +#define __XFS_TRANS_RESV_H__ + +struct xfs_mount; + +/* + * structure for maintaining pre-calculated transaction reservations. + */ +struct xfs_trans_res { + uint tr_logres; /* log space unit in bytes per log ticket */ + int tr_logcount; /* number of log operations per log ticket */ + int tr_logflags; /* log flags, currently only used for indicating + * a reservation request is permanent or not */ +}; + +struct xfs_trans_resv { + struct xfs_trans_res tr_write; /* extent alloc trans */ + struct xfs_trans_res tr_itruncate; /* truncate trans */ + struct xfs_trans_res tr_rename; /* rename trans */ + struct xfs_trans_res tr_link; /* link trans */ + struct xfs_trans_res tr_remove; /* unlink trans */ + struct xfs_trans_res tr_symlink; /* symlink trans */ + struct xfs_trans_res tr_create; /* create trans */ + struct xfs_trans_res tr_mkdir; /* mkdir trans */ + struct xfs_trans_res tr_ifree; /* inode free trans */ + struct xfs_trans_res tr_ichange; /* inode update trans */ + struct xfs_trans_res tr_growdata; /* fs data section grow trans */ + struct xfs_trans_res tr_swrite; /* sync write inode trans */ + struct xfs_trans_res tr_addafork; /* add inode attr fork trans */ + struct xfs_trans_res tr_writeid; /* write setuid/setgid file */ + struct xfs_trans_res tr_attrinval; /* attr fork buffer + * invalidation */ + struct xfs_trans_res tr_attrsetm; /* set/create an attribute at + * mount time */ + struct xfs_trans_res tr_attrsetrt; /* set/create an attribute at + * runtime */ + struct xfs_trans_res tr_attrrm; /* remove an attribute */ + struct xfs_trans_res tr_clearagi; /* clear agi unlinked bucket */ + struct xfs_trans_res tr_growrtalloc; /* grow realtime allocations */ + struct xfs_trans_res tr_growrtzero; /* grow realtime zeroing */ + struct xfs_trans_res tr_growrtfree; /* grow realtime freeing */ + struct xfs_trans_res tr_qm_sbchange; /* change quota flags */ + struct xfs_trans_res tr_qm_setqlim; /* adjust quota limits */ + struct xfs_trans_res tr_qm_dqalloc; /* allocate quota on disk */ + struct xfs_trans_res tr_qm_quotaoff; /* turn quota off */ + struct xfs_trans_res tr_qm_equotaoff;/* end of turn quota off */ + struct xfs_trans_res tr_sb; /* modify superblock */ + struct xfs_trans_res tr_fsyncts; /* update timestamps on fsync */ +}; + +/* shorthand way of accessing reservation structure */ +#define M_RES(mp) (&(mp)->m_resv) + +/* + * Per-extent log reservation for the allocation btree changes + * involved in freeing or allocating an extent. + * 2 trees * (2 blocks/level * max depth - 1) * block size + */ +#define XFS_ALLOCFREE_LOG_RES(mp,nx) \ + ((nx) * (2 * XFS_FSB_TO_B((mp), 2 * XFS_AG_MAXLEVELS(mp) - 1))) +#define XFS_ALLOCFREE_LOG_COUNT(mp,nx) \ + ((nx) * (2 * (2 * XFS_AG_MAXLEVELS(mp) - 1))) + +/* + * Per-directory log reservation for any directory change. + * dir blocks: (1 btree block per level + data block + free block) * dblock size + * bmap btree: (levels + 2) * max depth * block size + * v2 directory blocks can be fragmented below the dirblksize down to the fsb + * size, so account for that in the DAENTER macros. + */ +#define XFS_DIROP_LOG_RES(mp) \ + (XFS_FSB_TO_B(mp, XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK)) + \ + (XFS_FSB_TO_B(mp, XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1))) +#define XFS_DIROP_LOG_COUNT(mp) \ + (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \ + XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1) + +/* + * Various log count values. + */ +#define XFS_DEFAULT_LOG_COUNT 1 +#define XFS_DEFAULT_PERM_LOG_COUNT 2 +#define XFS_ITRUNCATE_LOG_COUNT 2 +#define XFS_INACTIVE_LOG_COUNT 2 +#define XFS_CREATE_LOG_COUNT 2 +#define XFS_MKDIR_LOG_COUNT 3 +#define XFS_SYMLINK_LOG_COUNT 3 +#define XFS_REMOVE_LOG_COUNT 2 +#define XFS_LINK_LOG_COUNT 2 +#define XFS_RENAME_LOG_COUNT 2 +#define XFS_WRITE_LOG_COUNT 2 +#define XFS_ADDAFORK_LOG_COUNT 2 +#define XFS_ATTRINVAL_LOG_COUNT 1 +#define XFS_ATTRSET_LOG_COUNT 3 +#define XFS_ATTRRM_LOG_COUNT 3 + +void xfs_trans_resv_calc(struct xfs_mount *mp, struct xfs_trans_resv *resp); + +#endif /* __XFS_TRANS_RESV_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_trans_space.h xfsprogs-3.2.1ubuntu1/include/xfs_trans_space.h --- xfsprogs-3.1.9ubuntu2/include/xfs_trans_space.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_trans_space.h 2014-06-19 22:42:17.000000000 +0000 @@ -47,7 +47,9 @@ #define XFS_DIRREMOVE_SPACE_RES(mp) \ XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK) #define XFS_IALLOC_SPACE_RES(mp) \ - (XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels - 1) + (XFS_IALLOC_BLOCKS(mp) + \ + (xfs_sb_version_hasfinobt(&mp->m_sb) ? 2 : 1 * \ + ((mp)->m_in_maxlevels - 1))) /* * Space reservation values for various transactions. @@ -82,5 +84,8 @@ (XFS_DIRREMOVE_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl)) #define XFS_SYMLINK_SPACE_RES(mp,nl,b) \ (XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl) + (b)) +#define XFS_IFREE_SPACE_RES(mp) \ + (xfs_sb_version_hasfinobt(&mp->m_sb) ? (mp)->m_in_maxlevels : 0) + #endif /* __XFS_TRANS_SPACE_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/include/xfs_types.h xfsprogs-3.2.1ubuntu1/include/xfs_types.h --- xfsprogs-3.1.9ubuntu2/include/xfs_types.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/include/xfs_types.h 2014-06-19 22:42:17.000000000 +0000 @@ -18,45 +18,10 @@ #ifndef __XFS_TYPES_H__ #define __XFS_TYPES_H__ -#ifdef __KERNEL__ - -/* - * Additional type declarations for XFS - */ -typedef signed char __int8_t; -typedef unsigned char __uint8_t; -typedef signed short int __int16_t; -typedef unsigned short int __uint16_t; -typedef signed int __int32_t; -typedef unsigned int __uint32_t; -typedef signed long long int __int64_t; -typedef unsigned long long int __uint64_t; - -typedef enum { B_FALSE,B_TRUE } boolean_t; -typedef __uint32_t prid_t; /* project ID */ -typedef __uint32_t inst_t; /* an instruction */ - -typedef __s64 xfs_off_t; /* type */ -typedef unsigned long long xfs_ino_t; /* type */ -typedef __s64 xfs_daddr_t; /* type */ -typedef char * xfs_caddr_t; /* type */ -typedef __u32 xfs_dev_t; -typedef __u32 xfs_nlink_t; - -/* __psint_t is the same size as a pointer */ -#if (BITS_PER_LONG == 32) -typedef __int32_t __psint_t; -typedef __uint32_t __psunsigned_t; -#elif (BITS_PER_LONG == 64) -typedef __int64_t __psint_t; -typedef __uint64_t __psunsigned_t; -#else -#error BITS_PER_LONG must be 32 or 64 -#endif - -#endif /* __KERNEL__ */ +typedef __uint32_t prid_t; /* project ID */ typedef __uint32_t xfs_agblock_t; /* blockno in alloc. group */ +typedef __uint32_t xfs_agino_t; /* inode # within allocation grp */ typedef __uint32_t xfs_extlen_t; /* extent length in blocks */ typedef __uint32_t xfs_agnumber_t; /* allocation group number */ typedef __int32_t xfs_extnum_t; /* # of extents in a file */ @@ -73,8 +38,6 @@ typedef __uint32_t xfs_dablk_t; /* dir/attr block number (in file) */ typedef __uint32_t xfs_dahash_t; /* dir/attr hash value */ -typedef __uint32_t xlog_tid_t; /* transaction ID type */ - /* * These types are 64 bits on disk but are either 32 or 64 bits in memory. * Disk based types: @@ -103,6 +66,7 @@ typedef __int64_t xfs_sfiloff_t; /* signed block number in a file */ typedef __uint64_t xfs_filblks_t; /* number of blocks in a file */ + /* * Null values for the types. */ @@ -122,6 +86,9 @@ #define NULLCOMMITLSN ((xfs_lsn_t)-1) +#define NULLFSINO ((xfs_ino_t)-1) +#define NULLAGINO ((xfs_agino_t)-1) + /* * Max values for extlen, extnum, aextnum. */ @@ -130,6 +97,26 @@ #define MAXAEXTNUM ((xfs_aextnum_t)0x7fff) /* signed short */ /* + * Minimum and maximum blocksize and sectorsize. + * The blocksize upper limit is pretty much arbitrary. + * The sectorsize upper limit is due to sizeof(sb_sectsize). + */ +#define XFS_MIN_BLOCKSIZE_LOG 9 /* i.e. 512 bytes */ +#define XFS_MAX_BLOCKSIZE_LOG 16 /* i.e. 65536 bytes */ +#define XFS_MIN_BLOCKSIZE (1 << XFS_MIN_BLOCKSIZE_LOG) +#define XFS_MAX_BLOCKSIZE (1 << XFS_MAX_BLOCKSIZE_LOG) +#define XFS_MIN_SECTORSIZE_LOG 9 /* i.e. 512 bytes */ +#define XFS_MAX_SECTORSIZE_LOG 15 /* i.e. 32768 bytes */ +#define XFS_MIN_SECTORSIZE (1 << XFS_MIN_SECTORSIZE_LOG) +#define XFS_MAX_SECTORSIZE (1 << XFS_MAX_SECTORSIZE_LOG) + +/* + * Inode fork identifiers. + */ +#define XFS_DATA_FORK 0 +#define XFS_ATTR_FORK 1 + +/* * Min numbers of data/attr fork btree root pointers. */ #define MINDBTPTRS 3 @@ -147,12 +134,29 @@ typedef enum { XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_BMAPi, XFS_BTNUM_INOi, - XFS_BTNUM_MAX + XFS_BTNUM_FINOi, XFS_BTNUM_MAX } xfs_btnum_t; struct xfs_name { const unsigned char *name; int len; + int type; }; +/* + * uid_t and gid_t are hard-coded to 32 bits in the inode. + * Hence, an 'id' in a dquot is 32 bits.. + */ +typedef __uint32_t xfs_dqid_t; + +/* + * Constants for bit manipulations. + */ +#define XFS_NBBYLOG 3 /* log2(NBBY) */ +#define XFS_WORDLOG 2 /* log2(sizeof(xfs_rtword_t)) */ +#define XFS_NBWORDLOG (XFS_NBBYLOG + XFS_WORDLOG) +#define XFS_NBWORD (1 << XFS_NBWORDLOG) +#define XFS_WORDMASK ((1 << XFS_WORDLOG) - 1) + + #endif /* __XFS_TYPES_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/install-sh xfsprogs-3.2.1ubuntu1/install-sh --- xfsprogs-3.1.9ubuntu2/install-sh 2012-01-31 09:53:46.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/install-sh 2013-02-14 01:41:01.000000000 +0000 @@ -85,6 +85,8 @@ INSTALL=true MANIFEST=: +: ${DIST_ROOT:=${DESTDIR}} + [ -n "$DIST_MANIFEST" -a -z "$DIST_ROOT" ] && INSTALL=false [ -n "$DIST_MANIFEST" ] && MANIFEST="_manifest" diff -Nru xfsprogs-3.1.9ubuntu2/io/fiemap.c xfsprogs-3.2.1ubuntu1/io/fiemap.c --- xfsprogs-3.1.9ubuntu2/io/fiemap.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/io/fiemap.c 2013-06-06 22:52:59.000000000 +0000 @@ -90,6 +90,14 @@ memset(lbuf, 0, sizeof(lbuf)); memset(bbuf, 0, sizeof(bbuf)); + if (*cur_extent == 0) { + printf("%4s: %-*s %-*s %*s %*s\n", _("EXT"), + foff_w, _("FILE-OFFSET"), + boff_w, _("BLOCK-RANGE"), + tot_w, _("TOTAL"), + flg_w, _("FLAGS")); + } + if (lstart != llast) { snprintf(lbuf, sizeof(lbuf), "[%llu..%llu]:", llast, lstart - 1ULL); @@ -157,6 +165,47 @@ *last_logical = extent->fe_logical + extent->fe_length; } +/* + * Calculate the proper extent table format based on first + * set of extents + */ +static void +calc_print_format( + struct fiemap *fiemap, + __u64 blocksize, + int *foff_w, + int *boff_w, + int *tot_w, + int *flg_w) +{ + int i; + char lbuf[32]; + char bbuf[32]; + __u64 logical; + __u64 block; + __u64 len; + struct fiemap_extent *extent; + + for (i = 0; i < fiemap->fm_mapped_extents; i++) { + + extent = &fiemap->fm_extents[i]; + logical = extent->fe_logical / blocksize; + len = extent->fe_length / blocksize; + block = extent->fe_physical / blocksize; + + snprintf(lbuf, sizeof(lbuf), "[%llu..%llu]", logical, + logical + len - 1); + snprintf(bbuf, sizeof(bbuf), "%llu..%llu", block, + block + len - 1); + *foff_w = max(*foff_w, strlen(lbuf)); + *boff_w = max(*boff_w, strlen(bbuf)); + *tot_w = max(*tot_w, numlen(len, 10)); + *flg_w = max(*flg_w, numlen(extent->fe_flags, 16)); + if (extent->fe_flags & FIEMAP_EXTENT_LAST) + break; + } +} + int fiemap_f( int argc, @@ -215,38 +264,6 @@ printf("%s:\n", file->name); - if (vflag) { - for (i = 0; i < fiemap->fm_mapped_extents; i++) { - char lbuf[32]; - char bbuf[32]; - __u64 logical; - __u64 block; - __u64 len; - struct fiemap_extent *extent; - - extent = &fiemap->fm_extents[i]; - logical = extent->fe_logical / blocksize; - len = extent->fe_length / blocksize; - block = extent->fe_physical / blocksize; - - snprintf(lbuf, sizeof(lbuf), "[%llu..%llu]", logical, - logical + len - 1); - snprintf(bbuf, sizeof(bbuf), "%llu..%llu", block, - block + len - 1); - foff_w = max(foff_w, strlen(lbuf)); - boff_w = max(boff_w, strlen(bbuf)); - tot_w = max(tot_w, numlen(len, 10)); - flg_w = max(flg_w, numlen(extent->fe_flags, 16)); - if (extent->fe_flags & FIEMAP_EXTENT_LAST) - break; - } - printf("%4s: %-*s %-*s %*s %*s\n", _("EXT"), - foff_w, _("FILE-OFFSET"), - boff_w, _("BLOCK-RANGE"), - tot_w, _("TOTAL"), - flg_w, _("FLAGS")); - } - while (!last && ((cur_extent + 1) != max_extents)) { if (max_extents) num_extents = min(num_extents, @@ -275,12 +292,18 @@ struct fiemap_extent *extent; extent = &fiemap->fm_extents[i]; - if (vflag) + if (vflag) { + if (cur_extent == 0) { + calc_print_format(fiemap, blocksize, + &foff_w, &boff_w, + &tot_w, &flg_w); + } + print_verbose(extent, blocksize, foff_w, boff_w, tot_w, flg_w, max_extents, &cur_extent, &last_logical); - else + } else print_plain(extent, lflag, blocksize, max_extents, &cur_extent, &last_logical); diff -Nru xfsprogs-3.1.9ubuntu2/io/file.c xfsprogs-3.2.1ubuntu1/io/file.c --- xfsprogs-3.1.9ubuntu2/io/file.c 2011-07-06 01:35:29.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/io/file.c 2014-05-02 00:09:15.000000000 +0000 @@ -36,7 +36,7 @@ int index, int braces) { - printf(_("%c%03d%c %-14s (%s,%s,%s,%s%s%s%s)\n"), + printf(_("%c%03d%c %-14s (%s,%s,%s,%s%s%s%s%s)\n"), braces? '[' : ' ', index, braces? ']' : ' ', file->name, file->flags & IO_FOREIGN ? _("foreign") : _("xfs"), file->flags & IO_OSYNC ? _("sync") : _("non-sync"), @@ -44,7 +44,8 @@ file->flags & IO_READONLY ? _("read-only") : _("read-write"), file->flags & IO_REALTIME ? _(",real-time") : "", file->flags & IO_APPEND ? _(",append-only") : "", - file->flags & IO_NONBLOCK ? _(",non-block") : ""); + file->flags & IO_NONBLOCK ? _(",non-block") : "", + file->flags & IO_TMPFILE ? _(",tmpfile") : ""); } int diff -Nru xfsprogs-3.1.9ubuntu2/io/imap.c xfsprogs-3.2.1ubuntu1/io/imap.c --- xfsprogs-3.1.9ubuntu2/io/imap.c 2011-07-06 01:35:29.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/io/imap.c 2014-05-02 00:09:15.000000000 +0000 @@ -67,7 +67,7 @@ imap_cmd.name = "imap"; imap_cmd.cfunc = imap_f; imap_cmd.argmin = 0; - imap_cmd.argmax = 0; + imap_cmd.argmax = 1; imap_cmd.args = _("[nentries]"); imap_cmd.flags = CMD_NOMAP_OK; imap_cmd.oneline = _("inode map for filesystem of current file"); diff -Nru xfsprogs-3.1.9ubuntu2/io/init.c xfsprogs-3.2.1ubuntu1/io/init.c --- xfsprogs-3.1.9ubuntu2/io/init.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/io/init.c 2014-05-02 00:09:15.000000000 +0000 @@ -32,7 +32,7 @@ usage(void) { fprintf(stderr, - _("Usage: %s [-adfmrRstx] [-p prog] [-c cmd]... file\n"), + _("Usage: %s [-adfmnrRstVx] [-p prog] [-c cmd]... file\n"), progname); exit(1); } @@ -58,12 +58,14 @@ bmap_init(); fadvise_init(); file_init(); + flink_init(); freeze_init(); fsync_init(); getrusage_init(); help_init(); imap_init(); inject_init(); + seek_init(); madvise_init(); mincore_init(); mmap_init(); @@ -74,6 +76,7 @@ fiemap_init(); pwrite_init(); quit_init(); + readdir_init(); resblks_init(); sendfile_init(); shutdown_init(); @@ -134,7 +137,7 @@ pagesize = getpagesize(); gettimeofday(&stopwatch, NULL); - while ((c = getopt(argc, argv, "ac:dFfmp:nrRstVx")) != EOF) { + while ((c = getopt(argc, argv, "ac:dFfmp:nrRstTVx")) != EOF) { switch (c) { case 'a': flags |= IO_APPEND; @@ -177,6 +180,9 @@ case 'R': flags |= IO_REALTIME; break; + case 'T': + flags |= IO_TMPFILE; + break; case 'x': expert = 1; break; diff -Nru xfsprogs-3.1.9ubuntu2/io/init.h xfsprogs-3.2.1ubuntu1/io/init.h --- xfsprogs-3.1.9ubuntu2/io/init.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/io/init.h 2013-10-10 21:07:17.000000000 +0000 @@ -26,7 +26,4 @@ extern size_t pagesize; extern struct timeval stopwatch; -#define min(a,b) (((a)<(b))?(a):(b)) -#define max(a,b) (((a)>(b))?(a):(b)) - extern void init_cvtnum(size_t *blocksize, size_t *sectsize); diff -Nru xfsprogs-3.1.9ubuntu2/io/io.h xfsprogs-3.2.1ubuntu1/io/io.h --- xfsprogs-3.1.9ubuntu2/io/io.h 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/io/io.h 2014-05-02 00:09:15.000000000 +0000 @@ -35,6 +35,7 @@ #define IO_TRUNC (1<<6) #define IO_FOREIGN (1<<7) #define IO_NONBLOCK (1<<8) +#define IO_TMPFILE (1<<9) /* * Regular file I/O control @@ -92,6 +93,7 @@ extern void attr_init(void); extern void bmap_init(void); extern void file_init(void); +extern void flink_init(void); extern void freeze_init(void); extern void fsync_init(void); extern void getrusage_init(void); @@ -105,6 +107,7 @@ extern void prealloc_init(void); extern void pwrite_init(void); extern void quit_init(void); +extern void seek_init(void); extern void shutdown_init(void); extern void truncate_init(void); @@ -149,3 +152,9 @@ #else #define sync_range_init() do { } while (0) #endif + +#ifdef HAVE_READDIR +extern void readdir_init(void); +#else +#define readdir_init() do { } while (0) +#endif diff -Nru xfsprogs-3.1.9ubuntu2/io/link.c xfsprogs-3.2.1ubuntu1/io/link.c --- xfsprogs-3.1.9ubuntu2/io/link.c 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/io/link.c 2014-05-02 00:09:15.000000000 +0000 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014 Christoph Hellwig. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include "init.h" +#include "io.h" + +#ifndef AT_EMPTY_PATH +#define AT_EMPTY_PATH 0x1000 +#endif + +static cmdinfo_t flink_cmd; + +static void +flink_help(void) +{ + printf(_( +"\n" +"link the open file descriptor to the supplied filename\n" +"\n" +"\n")); +} + +static int +flink_f( + int argc, + char **argv) +{ + if (argc != 2) + return command_usage(&flink_cmd); + + if (linkat(file->fd, "", AT_FDCWD, argv[1], AT_EMPTY_PATH) < 0) { + perror("flink"); + return 0; + } + return 0; +} + +void +flink_init(void) +{ + flink_cmd.name = "flink"; + flink_cmd.cfunc = flink_f; + flink_cmd.argmin = 1; + flink_cmd.argmax = 1; + flink_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; + flink_cmd.args = _("filename"); + flink_cmd.oneline = + _("link the open file descriptor to the supplied filename"); + flink_cmd.help = flink_help; + + add_command(&flink_cmd); +} diff -Nru xfsprogs-3.1.9ubuntu2/io/Makefile xfsprogs-3.2.1ubuntu1/io/Makefile --- xfsprogs-3.1.9ubuntu2/io/Makefile 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/io/Makefile 2014-05-02 00:09:15.000000000 +0000 @@ -9,8 +9,9 @@ LSRCFILES = xfs_bmap.sh xfs_freeze.sh xfs_mkfile.sh HFILES = init.h io.h CFILES = init.c \ - attr.c bmap.c file.c freeze.c fsync.c getrusage.c imap.c mmap.c \ - open.c parent.c pread.c prealloc.c pwrite.c shutdown.c truncate.c + attr.c bmap.c file.c freeze.c fsync.c getrusage.c imap.c link.c \ + mmap.c open.c parent.c pread.c prealloc.c pwrite.c seek.c shutdown.c \ + truncate.c LLDLIBS = $(LIBXCMD) $(LIBHANDLE) LTDEPENDENCIES = $(LIBXCMD) $(LIBHANDLE) @@ -80,6 +81,11 @@ LCFLAGS += -DHAVE_PREADV -DHAVE_PWRITEV endif +ifeq ($(HAVE_READDIR),yes) +CFILES += readdir.c +LCFLAGS += -DHAVE_READDIR +endif + default: depend $(LTCOMMAND) include $(BUILDRULES) diff -Nru xfsprogs-3.1.9ubuntu2/io/open.c xfsprogs-3.2.1ubuntu1/io/open.c --- xfsprogs-3.1.9ubuntu2/io/open.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/io/open.c 2014-05-02 00:09:15.000000000 +0000 @@ -22,10 +22,25 @@ #include "init.h" #include "io.h" +#ifndef __O_TMPFILE +#if defined __alpha__ +#define __O_TMPFILE 0100000000 +#elif defined(__hppa__) +#define __O_TMPFILE 040000000 +#elif defined(__sparc__) +#define __O_TMPFILE 0x2000000 +#else +#define __O_TMPFILE 020000000 +#endif +#endif /* __O_TMPFILE */ + +#ifndef O_TMPFILE +#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) +#endif + static cmdinfo_t open_cmd; static cmdinfo_t stat_cmd; static cmdinfo_t close_cmd; -static cmdinfo_t setfl_cmd; static cmdinfo_t statfs_cmd; static cmdinfo_t chproj_cmd; static cmdinfo_t lsproj_cmd; @@ -78,13 +93,14 @@ int verbose = (argc == 2 && !strcmp(argv[1], "-v")); printf(_("fd.path = \"%s\"\n"), file->name); - printf(_("fd.flags = %s,%s,%s%s%s%s\n"), + printf(_("fd.flags = %s,%s,%s%s%s%s%s\n"), file->flags & IO_OSYNC ? _("sync") : _("non-sync"), file->flags & IO_DIRECT ? _("direct") : _("non-direct"), file->flags & IO_READONLY ? _("read-only") : _("read-write"), file->flags & IO_REALTIME ? _(",real-time") : "", file->flags & IO_APPEND ? _(",append-only") : "", - file->flags & IO_NONBLOCK ? _(",non-block") : ""); + file->flags & IO_NONBLOCK ? _(",non-block") : "", + file->flags & IO_TMPFILE ? _(",tmpfile") : ""); if (fstat64(file->fd, &st) < 0) { perror("fstat64"); } else { @@ -144,10 +160,13 @@ oflags |= O_TRUNC; if (flags & IO_NONBLOCK) oflags |= O_NONBLOCK; + if (flags & IO_TMPFILE) + oflags |= O_TMPFILE; fd = open(path, oflags, mode); if (fd < 0) { - if ((errno == EISDIR) && (oflags & O_RDWR)) { + if (errno == EISDIR && + ((oflags & (O_RDWR|O_TMPFILE)) == O_RDWR)) { /* make it as if we asked for O_RDONLY & try again */ oflags &= ~O_RDWR; oflags |= O_RDONLY; @@ -249,6 +268,7 @@ " -s -- open with O_SYNC\n" " -t -- open with O_TRUNC (truncate the file to zero length if it exists)\n" " -R -- mark the file as a realtime XFS file immediately after opening it\n" +" -T -- open with O_TMPFILE (create a file not visible in the namespace)\n" " Note1: usually read/write direct IO requests must be blocksize aligned;\n" " some kernels, however, allow sectorsize alignment for direct IO.\n" " Note2: the bmap for non-regular files can be obtained provided the file\n" @@ -273,7 +293,7 @@ return 0; } - while ((c = getopt(argc, argv, "FRacdfm:nrstx")) != EOF) { + while ((c = getopt(argc, argv, "FRTacdfm:nrstx")) != EOF) { switch (c) { case 'F': /* Ignored / deprecated now, handled automatically */ @@ -311,6 +331,9 @@ case 'x': /* backwards compatibility */ flags |= IO_REALTIME; break; + case 'T': + flags |= IO_TMPFILE; + break; default: return command_usage(&open_cmd); } @@ -319,6 +342,11 @@ if (optind != argc - 1) return command_usage(&open_cmd); + if ((flags & (IO_READONLY|IO_TMPFILE)) == (IO_READONLY|IO_TMPFILE)) { + fprintf(stderr, _("-T and -r options are incompatible\n")); + return -1; + } + fd = openfile(argv[optind], &geometry, flags, mode); if (fd < 0) return 0; @@ -668,45 +696,6 @@ } static int -setfl_f( - int argc, - char **argv) -{ - int c, flags; - - flags = fcntl(file->fd, F_GETFL, 0); - if (flags < 0) { - perror("fcntl(F_GETFL)"); - return 0; - } - - while ((c = getopt(argc, argv, "ad")) != EOF) { - switch (c) { - case 'a': - if (flags & O_APPEND) - flags |= O_APPEND; - else - flags &= ~O_APPEND; - break; - case 'd': - if (flags & O_DIRECT) - flags |= O_DIRECT; - else - flags &= ~O_DIRECT; - break; - default: - printf(_("invalid setfl argument -- '%c'\n"), c); - return 0; - } - } - - if (fcntl(file->fd, F_SETFL, flags) < 0) - perror("fcntl(F_SETFL)"); - - return 0; -} - -static int statfs_f( int argc, char **argv) @@ -771,7 +760,7 @@ open_cmd.argmin = 0; open_cmd.argmax = -1; open_cmd.flags = CMD_NOMAP_OK | CMD_NOFILE_OK | CMD_FOREIGN_OK; - open_cmd.args = _("[-acdrstx] [path]"); + open_cmd.args = _("[-acdrstxT] [path]"); open_cmd.oneline = _("open the file specified by path"); open_cmd.help = open_help; @@ -791,13 +780,6 @@ close_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; close_cmd.oneline = _("close the current open file"); - setfl_cmd.name = "setfl"; - setfl_cmd.cfunc = setfl_f; - setfl_cmd.args = _("[-adx]"); - setfl_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; - setfl_cmd.oneline = - _("set/clear append/direct flags on the open file"); - statfs_cmd.name = "statfs"; statfs_cmd.cfunc = statfs_f; statfs_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; @@ -837,7 +819,6 @@ add_command(&open_cmd); add_command(&stat_cmd); add_command(&close_cmd); - add_command(&setfl_cmd); add_command(&statfs_cmd); add_command(&chproj_cmd); add_command(&lsproj_cmd); diff -Nru xfsprogs-3.1.9ubuntu2/io/parent.c xfsprogs-3.2.1ubuntu1/io/parent.c --- xfsprogs-3.1.9ubuntu2/io/parent.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/io/parent.c 2014-05-02 00:09:15.000000000 +0000 @@ -258,6 +258,8 @@ if (!bstatbuf || !parentbuf) { fprintf(stderr, _("unable to allocate buffers: %s\n"), strerror(errno)); + free(bstatbuf); + free(parentbuf); return 1; } diff -Nru xfsprogs-3.1.9ubuntu2/io/pread.c xfsprogs-3.2.1ubuntu1/io/pread.c --- xfsprogs-3.1.9ubuntu2/io/pread.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/io/pread.c 2014-05-02 00:09:15.000000000 +0000 @@ -246,7 +246,7 @@ *total = 0; while (count > 0) { - off = ((random() % range) / buffersize) * buffersize; + off = ((offset + (random() % range)) / buffersize) * buffersize; bytes = do_pread(fd, off, buffersize, buffersize); if (bytes == 0) break; diff -Nru xfsprogs-3.1.9ubuntu2/io/prealloc.c xfsprogs-3.2.1ubuntu1/io/prealloc.c --- xfsprogs-3.1.9ubuntu2/io/prealloc.c 2011-07-06 01:35:29.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/io/prealloc.c 2014-05-02 00:09:15.000000000 +0000 @@ -29,6 +29,14 @@ #define FALLOC_FL_PUNCH_HOLE 0x02 #endif +#ifndef FALLOC_FL_COLLAPSE_RANGE +#define FALLOC_FL_COLLAPSE_RANGE 0x08 +#endif + +#ifndef FALLOC_FL_ZERO_RANGE +#define FALLOC_FL_ZERO_RANGE 0x10 +#endif + static cmdinfo_t allocsp_cmd; static cmdinfo_t freesp_cmd; static cmdinfo_t resvsp_cmd; @@ -37,6 +45,8 @@ #if defined(HAVE_FALLOCATE) static cmdinfo_t falloc_cmd; static cmdinfo_t fpunch_cmd; +static cmdinfo_t fcollapse_cmd; +static cmdinfo_t fzero_cmd; #endif static int @@ -159,8 +169,11 @@ int mode = 0; int c; - while ((c = getopt(argc, argv, "kp")) != EOF) { + while ((c = getopt(argc, argv, "ckp")) != EOF) { switch (c) { + case 'c': + mode = FALLOC_FL_COLLAPSE_RANGE; + break; case 'k': mode = FALLOC_FL_KEEP_SIZE; break; @@ -203,6 +216,50 @@ } return 0; } + +static int +fcollapse_f( + int argc, + char **argv) +{ + xfs_flock64_t segment; + int mode = FALLOC_FL_COLLAPSE_RANGE; + + if (!offset_length(argv[1], argv[2], &segment)) + return 0; + + if (fallocate(file->fd, mode, + segment.l_start, segment.l_len)) { + perror("fallocate"); + return 0; + } + return 0; +} + +static int +fzero_f( + int argc, + char **argv) +{ + xfs_flock64_t segment; + int mode = FALLOC_FL_ZERO_RANGE; + int index = 1; + + if (strncmp(argv[index], "-k", 3) == 0) { + mode |= FALLOC_FL_KEEP_SIZE; + index++; + } + + if (!offset_length(argv[index], argv[index + 1], &segment)) + return 0; + + if (fallocate(file->fd, mode, + segment.l_start, segment.l_len)) { + perror("fallocate"); + return 0; + } + return 0; +} #endif /* HAVE_FALLOCATE */ void @@ -263,9 +320,9 @@ falloc_cmd.argmin = 2; falloc_cmd.argmax = -1; falloc_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; - falloc_cmd.args = _("[-k] [-p] off len"); + falloc_cmd.args = _("[-c] [-k] [-p] off len"); falloc_cmd.oneline = - _("allocates space associated with part of a file via fallocate"); + _("allocates space associated with part of a file via fallocate"); add_command(&falloc_cmd); fpunch_cmd.name = "fpunch"; @@ -275,7 +332,27 @@ fpunch_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; fpunch_cmd.args = _("off len"); fpunch_cmd.oneline = - _("de-allocates space assocated with part of a file via fallocate"); + _("de-allocates space assocated with part of a file via fallocate"); add_command(&fpunch_cmd); + + fcollapse_cmd.name = "fcollapse"; + fcollapse_cmd.cfunc = fcollapse_f; + fcollapse_cmd.argmin = 2; + fcollapse_cmd.argmax = 2; + fcollapse_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; + fcollapse_cmd.args = _("off len"); + fcollapse_cmd.oneline = + _("de-allocates space and eliminates the hole by shifting extents"); + add_command(&fcollapse_cmd); + + fzero_cmd.name = "fzero"; + fzero_cmd.cfunc = fzero_f; + fzero_cmd.argmin = 2; + fzero_cmd.argmax = 3; + fzero_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; + fzero_cmd.args = _("[-k] off len"); + fzero_cmd.oneline = + _("zeroes space and eliminates holes by preallocating"); + add_command(&fzero_cmd); #endif /* HAVE_FALLOCATE */ } diff -Nru xfsprogs-3.1.9ubuntu2/io/pwrite.c xfsprogs-3.2.1ubuntu1/io/pwrite.c --- xfsprogs-3.1.9ubuntu2/io/pwrite.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/io/pwrite.c 2014-05-02 00:09:15.000000000 +0000 @@ -129,7 +129,7 @@ *total = 0; while (count > 0) { - off = ((random() % range) / buffersize) * buffersize; + off = ((offset + (random() % range)) / buffersize) * buffersize; bytes = do_pwrite(file->fd, off, buffersize, buffersize); if (bytes == 0) break; diff -Nru xfsprogs-3.1.9ubuntu2/io/readdir.c xfsprogs-3.2.1ubuntu1/io/readdir.c --- xfsprogs-3.1.9ubuntu2/io/readdir.c 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/io/readdir.c 2014-05-02 00:09:15.000000000 +0000 @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2013 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include "init.h" +#include "io.h" + +#include +#include + +static struct cmdinfo readdir_cmd; + +const char *d_type_str(unsigned int type) +{ + const char *str; + + switch (type) { + case DT_UNKNOWN: + str = "DT_UNKNOWN"; + break; + case DT_FIFO: + str = "DT_FIFO"; + break; + case DT_CHR: + str = "DT_CHR"; + break; + case DT_DIR: + str = "DT_DIR"; + break; + case DT_BLK: + str = "DT_BLK"; + break; + case DT_REG: + str = "DT_REG"; + break; + case DT_LNK: + str = "DT_LNK"; + break; + case DT_SOCK: + str = "DT_SOCK"; + break; + case DT_WHT: + str = "DT_WHT"; + break; + default: + str = "ERROR!"; + break; + } + + return str; +} + +static void +dump_dirent( + long long offset, + struct dirent *dirent) +{ + printf("%08llx: d_ino: 0x%08lx", offset, dirent->d_ino); +#ifdef _DIRENT_HAVE_D_OFF + printf(" d_off: 0x%08lx", dirent->d_off); +#endif +#ifdef _DIRENT_HAVE_D_RECLEN + printf(" d_reclen: 0x%x", dirent->d_reclen); +#endif +#ifdef _DIRENT_HAVE_D_TYPE + printf(" d_type: %s", d_type_str(dirent->d_type)); +#endif + printf(" d_name: %s\n", dirent->d_name); +} + +static int +read_directory( + DIR *dir, + long long offset, + unsigned long long length, + int dump, + unsigned long long *total) +{ + struct dirent *dirent; + int count = 0; + + seekdir(dir, offset); + + *total = 0; + while (*total < length) { + dirent = readdir(dir); + if (!dirent) + break; + + *total += dirent->d_reclen; + count++; + + if (dump) { + dump_dirent(offset, dirent); + offset = dirent->d_off; + } + } + + return count; +} + +static int +readdir_f( + int argc, + char **argv) +{ + int cnt; + unsigned long long total; + int c; + size_t fsblocksize, fssectsize; + struct timeval t1, t2; + char s1[64], s2[64], ts[64]; + long long offset = -1; + unsigned long long length = -1; /* max length limit */ + int verbose = 0; + DIR *dir; + int dfd; + + init_cvtnum(&fsblocksize, &fssectsize); + + while ((c = getopt(argc, argv, "l:o:v")) != EOF) { + switch (c) { + case 'l': + length = cvtnum(fsblocksize, fssectsize, optarg); + break; + case 'o': + offset = cvtnum(fsblocksize, fssectsize, optarg); + break; + case 'v': + verbose = 1; + break; + default: + return command_usage(&readdir_cmd); + } + } + + dfd = dup(file->fd); + if (dfd < 0) + return -1; + + dir = fdopendir(dfd); + if (!dir) { + close(dfd); + return -1; + } + + if (offset == -1) { + rewinddir(dir); + offset = telldir(dir); + } + + gettimeofday(&t1, NULL); + cnt = read_directory(dir, offset, length, verbose, &total); + gettimeofday(&t2, NULL); + + closedir(dir); + close(dfd); + + t2 = tsub(t2, t1); + timestr(&t2, ts, sizeof(ts), 0); + + cvtstr(total, s1, sizeof(s1)); + cvtstr(tdiv(total, t2), s2, sizeof(s2)); + + printf(_("read %llu bytes from offset %lld\n"), total, offset); + printf(_("%s, %d ops, %s (%s/sec and %.4f ops/sec)\n"), + s1, cnt, ts, s2, tdiv(cnt, t2)); + + return 0; +} + +void +readdir_init(void) +{ + readdir_cmd.name = "readdir"; + readdir_cmd.cfunc = readdir_f; + readdir_cmd.argmax = 5; + readdir_cmd.flags = CMD_NOMAP_OK|CMD_FOREIGN_OK; + readdir_cmd.args = _("[-v][-o offset][-l length]"); + readdir_cmd.oneline = _("read directory entries"); + + add_command(&readdir_cmd); +} diff -Nru xfsprogs-3.1.9ubuntu2/io/seek.c xfsprogs-3.2.1ubuntu1/io/seek.c --- xfsprogs-3.1.9ubuntu2/io/seek.c 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/io/seek.c 2013-10-10 21:07:17.000000000 +0000 @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2013 SGI + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include "init.h" +#include "io.h" + +static cmdinfo_t seek_cmd; + +static void +seek_help(void) +{ + printf(_( +"\n" +" returns the next hole and/or data offset at or after the requested offset\n" +"\n" +" Example:\n" +" 'seek -d 512' - offset of data at or following offset 512\n" +" 'seek -a -r 0' - offsets of all data and hole in entire file\n" +"\n" +" Returns the offset of the next data and/or hole. There is an implied hole\n" +" at the end of file. If the specified offset is past end of file, or there\n" +" is no data past the specified offset, EOF is returned.\n" +" -a -- return the next data and hole starting at the specified offset.\n" +" -d -- return the next data starting at the specified offset.\n" +" -h -- return the next hole starting at the specified offset.\n" +" -r -- return all remaining type(s) starting at the specified offset.\n" +" -s -- also print the starting offset.\n" +"\n")); +} + +#ifndef HAVE_SEEK_DATA +#define SEEK_DATA 3 /* seek to the next data */ +#define SEEK_HOLE 4 /* seek to the next hole */ +#endif + +/* values for flag variable */ +#define SEEK_DFLAG (1 << 0) +#define SEEK_HFLAG (1 << 1) +#define SEEK_RFLAG (1 << 2) + +/* indexes into the seekinfo array */ +#define DATA 0 +#define HOLE 1 + +struct seekinfo { + char *name; /* display item name */ + int seektype; /* data or hole */ + int mask; /* compared for print and looping */ +} seekinfo[] = { + {"DATA", SEEK_DATA, SEEK_DFLAG}, + {"HOLE", SEEK_HOLE, SEEK_HFLAG} +}; + +/* print item type and offset. catch special cases of eof and error */ +void +seek_output( + int startflag, + char *type, + off64_t start, + off64_t offset) +{ + if (offset == -1) { + if (errno == ENXIO) { + if (startflag) + printf("%s %lld EOF\n", type, + (long long)start); + else + printf("%s EOF\n", type); + } else { + printf("ERR %lld ", (long long)start); + fflush(stdout); /* so the printf preceded the perror */ + perror(""); + } + } else { + if (startflag) + printf("%s %lld %lld\n", type, + (long long)start, (long long)offset); + else + printf("%s %lld\n", type, (long long)offset); + } +} + +static int +seek_f( + int argc, + char **argv) +{ + off64_t offset, start; + size_t fsblocksize, fssectsize; + int c; + int current; /* specify data or hole */ + int flag; + int startflag; + + flag = startflag = 0; + init_cvtnum(&fsblocksize, &fssectsize); + + while ((c = getopt(argc, argv, "adhrs")) != EOF) { + switch (c) { + case 'a': + flag |= (SEEK_HFLAG | SEEK_DFLAG); + break; + case 'd': + flag |= SEEK_DFLAG; + break; + case 'h': + flag |= SEEK_HFLAG; + break; + case 'r': + flag |= SEEK_RFLAG; + break; + case 's': + startflag = 1; + break; + default: + return command_usage(&seek_cmd); + } + } + if (!(flag & (SEEK_DFLAG | SEEK_HFLAG)) || optind != argc - 1) + return command_usage(&seek_cmd); + + start = offset = cvtnum(fsblocksize, fssectsize, argv[optind]); + if (offset < 0) + return command_usage(&seek_cmd); + + /* + * check to see if the offset is a data or hole entry and + * decide if we want to display that type of entry. + */ + if (flag & SEEK_HFLAG) { + offset = lseek64(file->fd, start, SEEK_HOLE); + if ((start == offset) || !(flag & SEEK_DFLAG)) { + /* + * this offset is a hole or are only displaying holes. + * if this offset is for data and we are displaying + * data, then we will fall through below to + * initialize the data search. + */ + current = HOLE; + goto found_hole; + } + } + + /* The offset is not a hole, or we are looking just for data */ + current = DATA; + offset = lseek64(file->fd, start, SEEK_DATA); + +found_hole: + /* + * At this point we know which type and the offset of the starting + * item. "current" alternates between data / hole entries in + * assending order - this alternation is needed even if only one + * type is to be displayed. + * + * An error or EOF will terminate the display, otherwise "flag" + * determines if there are more items to be displayed. + */ + if (startflag) + printf("Whence Start Result\n"); + else + printf("Whence Result\n"); + + for (c = 0; flag; c++) { + if (offset == -1) { + /* print error or eof if the only entry */ + if (errno != ENXIO || c == 0 ) + seek_output(startflag, seekinfo[current].name, + start, offset); + return 0; /* stop on error or EOF */ + } + + if (flag & seekinfo[current].mask) + seek_output(startflag, seekinfo[current].name, start, + offset); + + /* + * When displaying only a single data and/or hole item, mask + * off the item as it is displayed. The loop will end when all + * requested items have been displayed. + */ + if (!(flag & SEEK_RFLAG)) + flag &= ~seekinfo[current].mask; + + current ^= 1; /* alternate between data and hole */ + start = offset; + offset = lseek64(file->fd, start, seekinfo[current].seektype); + } + return 0; +} + +void +seek_init(void) +{ + seek_cmd.name = "seek"; + seek_cmd.cfunc = seek_f; + seek_cmd.argmin = 2; + seek_cmd.argmax = 5; + seek_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; + seek_cmd.args = _("-a | -d | -h [-r] off"); + seek_cmd.oneline = _("locate the next data and/or hole"); + seek_cmd.help = seek_help; + + add_command(&seek_cmd); +} diff -Nru xfsprogs-3.1.9ubuntu2/io/sync_file_range.c xfsprogs-3.2.1ubuntu1/io/sync_file_range.c --- xfsprogs-3.1.9ubuntu2/io/sync_file_range.c 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/io/sync_file_range.c 2013-02-14 01:39:05.000000000 +0000 @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2012 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include "init.h" +#include "io.h" + +static cmdinfo_t sync_range_cmd; + +static void +sync_range_help(void) +{ + printf(_( +"\n" +" Trigger specific writeback commands on a range of the current file\n" +"\n" +" With no options, the SYNC_FILE_RANGE_WRITE is implied.\n" +" -a -- wait for IO to finish after writing (SYNC_FILE_RANGE_WAIT_AFTER).\n" +" -b -- wait for IO to finish before writing (SYNC_FILE_RANGE_WAIT_BEFORE).\n" +" -w -- write dirty data in range (SYNC_FILE_RANGE_WRITE).\n" +"\n")); +} + +static int +sync_range_f( + int argc, + char **argv) +{ + off64_t offset = 0, length = 0; + int c, sync_mode = 0; + size_t blocksize, sectsize; + + while ((c = getopt(argc, argv, "abw")) != EOF) { + switch (c) { + case 'a': + sync_mode = SYNC_FILE_RANGE_WAIT_AFTER; + break; + case 'b': + sync_mode = SYNC_FILE_RANGE_WAIT_BEFORE; + break; + case 'w': + sync_mode = SYNC_FILE_RANGE_WRITE; + break; + default: + return command_usage(&sync_range_cmd); + } + } + + /* default to just starting writeback on the range */ + if (!sync_mode) + sync_mode = SYNC_FILE_RANGE_WRITE; + + if (optind != argc - 2) + return command_usage(&sync_range_cmd); + init_cvtnum(&blocksize, §size); + offset = cvtnum(blocksize, sectsize, argv[optind]); + if (offset < 0) { + printf(_("non-numeric offset argument -- %s\n"), + argv[optind]); + return 0; + } + optind++; + length = cvtnum(blocksize, sectsize, argv[optind]); + if (length < 0) { + printf(_("non-numeric length argument -- %s\n"), + argv[optind]); + return 0; + } + + if (sync_file_range(file->fd, offset, length, sync_mode) < 0) { + perror("sync_file_range"); + return 0; + } + return 0; +} + +void +sync_range_init(void) +{ + sync_range_cmd.name = "sync_range"; + sync_range_cmd.cfunc = sync_range_f; + sync_range_cmd.argmin = 2; + sync_range_cmd.argmax = -1; + sync_range_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; + sync_range_cmd.args = _("[-abw] off len"); + sync_range_cmd.oneline = _("Control writeback on a range of a file"); + sync_range_cmd.help = sync_range_help; + + add_command(&sync_range_cmd); +} diff -Nru xfsprogs-3.1.9ubuntu2/io/xfs_freeze.sh xfsprogs-3.2.1ubuntu1/io/xfs_freeze.sh --- xfsprogs-3.1.9ubuntu2/io/xfs_freeze.sh 2009-02-17 01:14:58.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/io/xfs_freeze.sh 2013-06-06 22:52:59.000000000 +0000 @@ -4,7 +4,7 @@ # OPTS="" -USAGE="Usage: xfs_freeze -f | -u " +USAGE="Usage: xfs_freeze [-V] [-f | -u] " DIRNAME=`dirname $0` VERSION=false FREEZE=false diff -Nru xfsprogs-3.1.9ubuntu2/libhandle/handle.c xfsprogs-3.2.1ubuntu1/libhandle/handle.c --- xfsprogs-3.1.9ubuntu2/libhandle/handle.c 2011-07-06 01:35:29.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libhandle/handle.c 2014-05-02 00:09:15.000000000 +0000 @@ -97,6 +97,7 @@ /* new filesystem. add it to the cache */ fdhp = malloc(sizeof(struct fdhash)); if (fdhp == NULL) { + close(fd); errno = ENOMEM; return -1; } @@ -158,7 +159,8 @@ if (S_ISREG(statbuf.st_mode) || S_ISDIR(statbuf.st_mode)) return path; - strcpy(dirpath, path); + strncpy(dirpath, path, MAXPATHLEN); + dirpath[MAXPATHLEN-1] = '\0'; return dirname(dirpath); } diff -Nru xfsprogs-3.1.9ubuntu2/libxcmd/input.c xfsprogs-3.2.1ubuntu1/libxcmd/input.c --- xfsprogs-3.1.9ubuntu2/libxcmd/input.c 2010-11-09 11:17:04.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxcmd/input.c 2013-06-06 22:52:59.000000000 +0000 @@ -19,6 +19,7 @@ #include #include #include +#include #if defined(ENABLE_READLINE) # include @@ -88,7 +89,7 @@ if (!line) return NULL; - printf(get_prompt()); + printf("%s", get_prompt()); fflush(stdout); if (!fgets(line, MAXREADLINESZ, stdin)) { free(line); @@ -398,6 +399,18 @@ return -1; } +bool isdigits_only( + const char *str) +{ + int i; + + for (i = 0; i < strlen(str); i++) { + if (!isdigit(str[i])) + return false; + } + return true; +} + #define HAVE_FTW_H 1 /* TODO: configure me */ #ifndef HAVE_FTW_H diff -Nru xfsprogs-3.1.9ubuntu2/libxcmd/paths.c xfsprogs-3.2.1ubuntu1/libxcmd/paths.c --- xfsprogs-3.1.9ubuntu2/libxcmd/paths.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxcmd/paths.c 2014-07-21 09:15:17.000000000 +0000 @@ -27,6 +27,7 @@ #include #include #include +#include extern char *progname; @@ -265,6 +266,10 @@ return ENOMEM; } +/* + * If *path is NULL, initialize the fs table with all xfs mount points in mtab + * If *path is specified, search for that path in mtab + */ static int fs_table_initialise_mounts( char *path) @@ -273,6 +278,7 @@ FILE *mtp; char *fslog, *fsrt; int error, found; + char *rpath = NULL; error = found = 0; fslog = fsrt = NULL; @@ -286,12 +292,19 @@ if ((mtp = setmntent(mtab_file, "r")) == NULL) return ENOENT; + /* Use realpath to resolve symlinks, relative paths, etc */ + if (path) + if ((rpath = realpath(path, NULL)) == NULL) + return ENOENT; + while ((mnt = getmntent(mtp)) != NULL) { if (strcmp(mnt->mnt_type, "xfs") != 0) continue; if (path && ((strcmp(path, mnt->mnt_dir) != 0) && - (strcmp(path, mnt->mnt_fsname) != 0))) + (strcmp(path, mnt->mnt_fsname) != 0) && + (strcmp(rpath, mnt->mnt_dir) != 0) && + (strcmp(rpath, mnt->mnt_fsname) != 0))) continue; if (fs_extract_mount_options(mnt, &fslog, &fsrt)) continue; @@ -303,6 +316,8 @@ } } endmntent(mtp); + free(rpath); + if (path && !found) error = ENXIO; @@ -312,12 +327,17 @@ #elif defined(HAVE_GETMNTINFO) #include +/* + * If *path is NULL, initialize the fs table with all xfs mount points in mtab + * If *path is specified, search for that path in mtab + */ static int fs_table_initialise_mounts( char *path) { struct statfs *stats; int i, count, error, found; + char *rpath = NULL; error = found = 0; if ((count = getmntinfo(&stats, 0)) < 0) { @@ -326,12 +346,19 @@ return 0; } + /* Use realpath to resolve symlinks, relative paths, etc */ + if (path) + if ((rpath = realpath(path, NULL)) == NULL) + return ENOENT; + for (i = 0; i < count; i++) { if (strcmp(stats[i].f_fstypename, "xfs") != 0) continue; if (path && ((strcmp(path, stats[i].f_mntonname) != 0) && - (strcmp(path, stats[i].f_mntfromname) != 0))) + (strcmp(path, stats[i].f_mntfromname) != 0) && + (strcmp(rpath, stats[i].f_mntonname) != 0) && + (strcmp(rpath, stats[i].f_mntfromname) != 0))) continue; /* TODO: external log and realtime device? */ (void) fs_table_insert(stats[i].f_mntonname, 0, @@ -342,6 +369,7 @@ break; } } + free(rpath); if (path && !found) error = ENXIO; diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/cache.c xfsprogs-3.2.1ubuntu1/libxfs/cache.c --- xfsprogs-3.1.9ubuntu2/libxfs/cache.c 2009-09-23 01:42:38.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/cache.c 2014-05-02 00:09:15.000000000 +0000 @@ -25,6 +25,7 @@ #include #include #include +#include #define CACHE_DEBUG 1 #undef CACHE_DEBUG @@ -38,6 +39,7 @@ struct cache * cache_init( + int flags, unsigned int hashsize, struct cache_operations *cache_operations) { @@ -53,12 +55,14 @@ return NULL; } + cache->c_flags = flags; cache->c_count = 0; cache->c_max = 0; cache->c_hits = 0; cache->c_misses = 0; cache->c_maxcount = maxcount; cache->c_hashsize = hashsize; + cache->c_hashshift = libxfs_highbit32(hashsize); cache->hash = cache_operations->hash; cache->alloc = cache_operations->alloc; cache->flush = cache_operations->flush; @@ -289,6 +293,34 @@ return (cache->c_maxcount == cache->c_max); } + +static int +__cache_node_purge( + struct cache * cache, + struct cache_node * node) +{ + int count; + struct cache_mru * mru; + + pthread_mutex_lock(&node->cn_mutex); + count = node->cn_count; + if (count != 0) { + pthread_mutex_unlock(&node->cn_mutex); + return count; + } + mru = &cache->c_mrus[node->cn_priority]; + pthread_mutex_lock(&mru->cm_mutex); + list_del_init(&node->cn_mru); + mru->cm_count--; + pthread_mutex_unlock(&mru->cm_mutex); + + pthread_mutex_unlock(&node->cn_mutex); + pthread_mutex_destroy(&node->cn_mutex); + list_del_init(&node->cn_hash); + cache->relse(node); + return count; +} + /* * Lookup in the cache hash table. With any luck we'll get a cache * hit, in which case this will all be over quickly and painlessly. @@ -308,19 +340,37 @@ struct cache_mru * mru; struct list_head * head; struct list_head * pos; + struct list_head * n; unsigned int hashidx; int priority = 0; + int purged = 0; - hashidx = cache->hash(key, cache->c_hashsize); + hashidx = cache->hash(key, cache->c_hashsize, cache->c_hashshift); hash = cache->c_hash + hashidx; head = &hash->ch_list; for (;;) { pthread_mutex_lock(&hash->ch_mutex); - for (pos = head->next; pos != head; pos = pos->next) { + for (pos = head->next, n = pos->next; pos != head; + pos = n, n = pos->next) { + int result; + node = list_entry(pos, struct cache_node, cn_hash); - if (!cache->compare(node, key)) - continue; + result = cache->compare(node, key); + switch (result) { + case CACHE_HIT: + break; + case CACHE_PURGE: + if ((cache->c_flags & CACHE_MISCOMPARE_PURGE) && + !__cache_node_purge(cache, node)) { + purged++; + hash->ch_count--; + } + /* FALL THROUGH */ + case CACHE_MISS: + goto next_object; + } + /* * node found, bump node's reference count, remove it * from its MRU list, and update stats. @@ -347,6 +397,8 @@ *nodep = node; return 0; +next_object: + continue; /* what the hell, gcc? */ } pthread_mutex_unlock(&hash->ch_mutex); /* @@ -375,6 +427,12 @@ list_add(&node->cn_hash, &hash->ch_list); pthread_mutex_unlock(&hash->ch_mutex); + if (purged) { + pthread_mutex_lock(&cache->c_mutex); + cache->c_count -= purged; + pthread_mutex_unlock(&cache->c_mutex); + } + *nodep = node; return 1; } @@ -457,10 +515,10 @@ struct list_head * pos; struct list_head * n; struct cache_hash * hash; - struct cache_mru * mru; int count = -1; - hash = cache->c_hash + cache->hash(key, cache->c_hashsize); + hash = cache->c_hash + cache->hash(key, cache->c_hashsize, + cache->c_hashshift); head = &hash->ch_list; pthread_mutex_lock(&hash->ch_mutex); for (pos = head->next, n = pos->next; pos != head; @@ -468,23 +526,9 @@ if ((struct cache_node *)pos != node) continue; - pthread_mutex_lock(&node->cn_mutex); - count = node->cn_count; - if (count != 0) { - pthread_mutex_unlock(&node->cn_mutex); - break; - } - mru = &cache->c_mrus[node->cn_priority]; - pthread_mutex_lock(&mru->cm_mutex); - list_del_init(&node->cn_mru); - mru->cm_count--; - pthread_mutex_unlock(&mru->cm_mutex); - - pthread_mutex_unlock(&node->cn_mutex); - pthread_mutex_destroy(&node->cn_mutex); - list_del_init(&node->cn_hash); - hash->ch_count--; - cache->relse(node); + count = __cache_node_purge(cache, node); + if (!count) + hash->ch_count--; break; } pthread_mutex_unlock(&hash->ch_mutex); diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/crc32.c xfsprogs-3.2.1ubuntu1/libxfs/crc32.c --- xfsprogs-3.1.9ubuntu2/libxfs/crc32.c 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/crc32.c 2014-05-02 00:09:16.000000000 +0000 @@ -0,0 +1,1038 @@ +/* + * Aug 8, 2011 Bob Pearson with help from Joakim Tjernlund and George Spelvin + * cleaned up code to current version of sparse and added the slicing-by-8 + * algorithm to the closely similar existing slicing-by-4 algorithm. + * + * Oct 15, 2000 Matt Domsch + * Nicer crc32 functions/docs submitted by linux@horizon.com. Thanks! + * Code was from the public domain, copyright abandoned. Code was + * subsequently included in the kernel, thus was re-licensed under the + * GNU GPL v2. + * + * Oct 12, 2000 Matt Domsch + * Same crc32 function was used in 5 other places in the kernel. + * I made one version, and deleted the others. + * There are various incantations of crc32(). Some use a seed of 0 or ~0. + * Some xor at the end with ~0. The generic crc32() function takes + * seed as an argument, and doesn't xor at the end. Then individual + * users can do whatever they need. + * drivers/net/smc9194.c uses seed ~0, doesn't xor with ~0. + * fs/jffs2 uses seed 0, doesn't xor with ~0. + * fs/partitions/efi.c uses seed ~0, xor's with ~0. + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +/* see: Documentation/crc32.txt for a description of algorithms */ + +/* + * lifted from the 3.8-rc2 kernel source for xfsprogs. Killed CONFIG_X86 + * specific bits for just the generic algorithm. Also removed the big endian + * version of the algorithm as XFS only uses the little endian CRC version to + * match the hardware acceleration available on Intel CPUs. + */ + +#include +#include "crc32defs.h" + +/* types specifc to this file */ +typedef __u8 u8; +typedef __u16 u16; +typedef __u32 u32; +typedef __u32 u64; +#define __pure + +#if CRC_LE_BITS > 8 +# define tole(x) ((__force u32) __constant_cpu_to_le32(x)) +#else +# define tole(x) (x) +#endif + +#if CRC_BE_BITS > 8 +# define tobe(x) ((__force u32) __constant_cpu_to_be32(x)) +#else +# define tobe(x) (x) +#endif + +#include "crc32table.h" + +#if CRC_LE_BITS > 8 || CRC_BE_BITS > 8 + +/* implements slicing-by-4 or slicing-by-8 algorithm */ +static inline u32 +crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256]) +{ +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define DO_CRC(x) crc = t0[(crc ^ (x)) & 255] ^ (crc >> 8) +# define DO_CRC4 (t3[(q) & 255] ^ t2[(q >> 8) & 255] ^ \ + t1[(q >> 16) & 255] ^ t0[(q >> 24) & 255]) +# define DO_CRC8 (t7[(q) & 255] ^ t6[(q >> 8) & 255] ^ \ + t5[(q >> 16) & 255] ^ t4[(q >> 24) & 255]) +# elif __BYTE_ORDER == __BIG_ENDIAN +# define DO_CRC(x) crc = t0[((crc >> 24) ^ (x)) & 255] ^ (crc << 8) +# define DO_CRC4 (t0[(q) & 255] ^ t1[(q >> 8) & 255] ^ \ + t2[(q >> 16) & 255] ^ t3[(q >> 24) & 255]) +# define DO_CRC8 (t4[(q) & 255] ^ t5[(q >> 8) & 255] ^ \ + t6[(q >> 16) & 255] ^ t7[(q >> 24) & 255]) +# else +# error What endian are you? +# endif + const u32 *b; + size_t rem_len; + const u32 *t0=tab[0], *t1=tab[1], *t2=tab[2], *t3=tab[3]; +# if CRC_LE_BITS != 32 + const u32 *t4 = tab[4], *t5 = tab[5], *t6 = tab[6], *t7 = tab[7]; +# endif + u32 q; + + /* Align it */ + if (((long)buf & 3) && len) { + do { + DO_CRC(*buf++); + } while ((--len) && ((long)buf)&3); + } + +# if CRC_LE_BITS == 32 + rem_len = len & 3; + len = len >> 2; +# else + rem_len = len & 7; + len = len >> 3; +# endif + + b = (const u32 *)buf; + for (--b; len; --len) { + q = crc ^ *++b; /* use pre increment for speed */ +# if CRC_LE_BITS == 32 + crc = DO_CRC4; +# else + crc = DO_CRC8; + q = *++b; + crc ^= DO_CRC4; +# endif + } + len = rem_len; + /* And the last few bytes */ + if (len) { + u8 *p = (u8 *)(b + 1) - 1; + do { + DO_CRC(*++p); /* use pre increment for speed */ + } while (--len); + } + return crc; +#undef DO_CRC +#undef DO_CRC4 +#undef DO_CRC8 +} +#endif + +/** + * crc32_le() - Calculate bitwise little-endian Ethernet AUTODIN II CRC32 + * @crc: seed value for computation. ~0 for Ethernet, sometimes 0 for + * other uses, or the previous crc32 value if computing incrementally. + * @p: pointer to buffer over which CRC is run + * @len: length of buffer @p + */ +static inline u32 __pure crc32_le_generic(u32 crc, unsigned char const *p, + size_t len, const u32 (*tab)[256], + u32 polynomial) +{ +#if CRC_LE_BITS == 1 + int i; + while (len--) { + crc ^= *p++; + for (i = 0; i < 8; i++) + crc = (crc >> 1) ^ ((crc & 1) ? polynomial : 0); + } +# elif CRC_LE_BITS == 2 + while (len--) { + crc ^= *p++; + crc = (crc >> 2) ^ tab[0][crc & 3]; + crc = (crc >> 2) ^ tab[0][crc & 3]; + crc = (crc >> 2) ^ tab[0][crc & 3]; + crc = (crc >> 2) ^ tab[0][crc & 3]; + } +# elif CRC_LE_BITS == 4 + while (len--) { + crc ^= *p++; + crc = (crc >> 4) ^ tab[0][crc & 15]; + crc = (crc >> 4) ^ tab[0][crc & 15]; + } +# elif CRC_LE_BITS == 8 + /* aka Sarwate algorithm */ + while (len--) { + crc ^= *p++; + crc = (crc >> 8) ^ tab[0][crc & 255]; + } +# else + crc = (__force u32) cpu_to_le32(crc); + crc = crc32_body(crc, p, len, tab); + crc = le32_to_cpu((__force __le32)crc); +#endif + return crc; +} + +#if CRC_LE_BITS == 1 +u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) +{ + return crc32_le_generic(crc, p, len, NULL, CRCPOLY_LE); +} +u32 __pure crc32c_le(u32 crc, unsigned char const *p, size_t len) +{ + return crc32_le_generic(crc, p, len, NULL, CRC32C_POLY_LE); +} +#else +u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) +{ + return crc32_le_generic(crc, p, len, + (const u32 (*)[256])crc32table_le, CRCPOLY_LE); +} +u32 __pure crc32c_le(u32 crc, unsigned char const *p, size_t len) +{ + return crc32_le_generic(crc, p, len, + (const u32 (*)[256])crc32ctable_le, CRC32C_POLY_LE); +} +#endif + + +#ifdef CRC32_SELFTEST + +/* 4096 random bytes */ +static u8 __attribute__((__aligned__(8))) test_buf[] = +{ + 0x5b, 0x85, 0x21, 0xcb, 0x09, 0x68, 0x7d, 0x30, + 0xc7, 0x69, 0xd7, 0x30, 0x92, 0xde, 0x59, 0xe4, + 0xc9, 0x6e, 0x8b, 0xdb, 0x98, 0x6b, 0xaa, 0x60, + 0xa8, 0xb5, 0xbc, 0x6c, 0xa9, 0xb1, 0x5b, 0x2c, + 0xea, 0xb4, 0x92, 0x6a, 0x3f, 0x79, 0x91, 0xe4, + 0xe9, 0x70, 0x51, 0x8c, 0x7f, 0x95, 0x6f, 0x1a, + 0x56, 0xa1, 0x5c, 0x27, 0x03, 0x67, 0x9f, 0x3a, + 0xe2, 0x31, 0x11, 0x29, 0x6b, 0x98, 0xfc, 0xc4, + 0x53, 0x24, 0xc5, 0x8b, 0xce, 0x47, 0xb2, 0xb9, + 0x32, 0xcb, 0xc1, 0xd0, 0x03, 0x57, 0x4e, 0xd4, + 0xe9, 0x3c, 0xa1, 0x63, 0xcf, 0x12, 0x0e, 0xca, + 0xe1, 0x13, 0xd1, 0x93, 0xa6, 0x88, 0x5c, 0x61, + 0x5b, 0xbb, 0xf0, 0x19, 0x46, 0xb4, 0xcf, 0x9e, + 0xb6, 0x6b, 0x4c, 0x3a, 0xcf, 0x60, 0xf9, 0x7a, + 0x8d, 0x07, 0x63, 0xdb, 0x40, 0xe9, 0x0b, 0x6f, + 0xad, 0x97, 0xf1, 0xed, 0xd0, 0x1e, 0x26, 0xfd, + 0xbf, 0xb7, 0xc8, 0x04, 0x94, 0xf8, 0x8b, 0x8c, + 0xf1, 0xab, 0x7a, 0xd4, 0xdd, 0xf3, 0xe8, 0x88, + 0xc3, 0xed, 0x17, 0x8a, 0x9b, 0x40, 0x0d, 0x53, + 0x62, 0x12, 0x03, 0x5f, 0x1b, 0x35, 0x32, 0x1f, + 0xb4, 0x7b, 0x93, 0x78, 0x0d, 0xdb, 0xce, 0xa4, + 0xc0, 0x47, 0xd5, 0xbf, 0x68, 0xe8, 0x5d, 0x74, + 0x8f, 0x8e, 0x75, 0x1c, 0xb2, 0x4f, 0x9a, 0x60, + 0xd1, 0xbe, 0x10, 0xf4, 0x5c, 0xa1, 0x53, 0x09, + 0xa5, 0xe0, 0x09, 0x54, 0x85, 0x5c, 0xdc, 0x07, + 0xe7, 0x21, 0x69, 0x7b, 0x8a, 0xfd, 0x90, 0xf1, + 0x22, 0xd0, 0xb4, 0x36, 0x28, 0xe6, 0xb8, 0x0f, + 0x39, 0xde, 0xc8, 0xf3, 0x86, 0x60, 0x34, 0xd2, + 0x5e, 0xdf, 0xfd, 0xcf, 0x0f, 0xa9, 0x65, 0xf0, + 0xd5, 0x4d, 0x96, 0x40, 0xe3, 0xdf, 0x3f, 0x95, + 0x5a, 0x39, 0x19, 0x93, 0xf4, 0x75, 0xce, 0x22, + 0x00, 0x1c, 0x93, 0xe2, 0x03, 0x66, 0xf4, 0x93, + 0x73, 0x86, 0x81, 0x8e, 0x29, 0x44, 0x48, 0x86, + 0x61, 0x7c, 0x48, 0xa3, 0x43, 0xd2, 0x9c, 0x8d, + 0xd4, 0x95, 0xdd, 0xe1, 0x22, 0x89, 0x3a, 0x40, + 0x4c, 0x1b, 0x8a, 0x04, 0xa8, 0x09, 0x69, 0x8b, + 0xea, 0xc6, 0x55, 0x8e, 0x57, 0xe6, 0x64, 0x35, + 0xf0, 0xc7, 0x16, 0x9f, 0x5d, 0x5e, 0x86, 0x40, + 0x46, 0xbb, 0xe5, 0x45, 0x88, 0xfe, 0xc9, 0x63, + 0x15, 0xfb, 0xf5, 0xbd, 0x71, 0x61, 0xeb, 0x7b, + 0x78, 0x70, 0x07, 0x31, 0x03, 0x9f, 0xb2, 0xc8, + 0xa7, 0xab, 0x47, 0xfd, 0xdf, 0xa0, 0x78, 0x72, + 0xa4, 0x2a, 0xe4, 0xb6, 0xba, 0xc0, 0x1e, 0x86, + 0x71, 0xe6, 0x3d, 0x18, 0x37, 0x70, 0xe6, 0xff, + 0xe0, 0xbc, 0x0b, 0x22, 0xa0, 0x1f, 0xd3, 0xed, + 0xa2, 0x55, 0x39, 0xab, 0xa8, 0x13, 0x73, 0x7c, + 0x3f, 0xb2, 0xd6, 0x19, 0xac, 0xff, 0x99, 0xed, + 0xe8, 0xe6, 0xa6, 0x22, 0xe3, 0x9c, 0xf1, 0x30, + 0xdc, 0x01, 0x0a, 0x56, 0xfa, 0xe4, 0xc9, 0x99, + 0xdd, 0xa8, 0xd8, 0xda, 0x35, 0x51, 0x73, 0xb4, + 0x40, 0x86, 0x85, 0xdb, 0x5c, 0xd5, 0x85, 0x80, + 0x14, 0x9c, 0xfd, 0x98, 0xa9, 0x82, 0xc5, 0x37, + 0xff, 0x32, 0x5d, 0xd0, 0x0b, 0xfa, 0xdc, 0x04, + 0x5e, 0x09, 0xd2, 0xca, 0x17, 0x4b, 0x1a, 0x8e, + 0x15, 0xe1, 0xcc, 0x4e, 0x52, 0x88, 0x35, 0xbd, + 0x48, 0xfe, 0x15, 0xa0, 0x91, 0xfd, 0x7e, 0x6c, + 0x0e, 0x5d, 0x79, 0x1b, 0x81, 0x79, 0xd2, 0x09, + 0x34, 0x70, 0x3d, 0x81, 0xec, 0xf6, 0x24, 0xbb, + 0xfb, 0xf1, 0x7b, 0xdf, 0x54, 0xea, 0x80, 0x9b, + 0xc7, 0x99, 0x9e, 0xbd, 0x16, 0x78, 0x12, 0x53, + 0x5e, 0x01, 0xa7, 0x4e, 0xbd, 0x67, 0xe1, 0x9b, + 0x4c, 0x0e, 0x61, 0x45, 0x97, 0xd2, 0xf0, 0x0f, + 0xfe, 0x15, 0x08, 0xb7, 0x11, 0x4c, 0xe7, 0xff, + 0x81, 0x53, 0xff, 0x91, 0x25, 0x38, 0x7e, 0x40, + 0x94, 0xe5, 0xe0, 0xad, 0xe6, 0xd9, 0x79, 0xb6, + 0x92, 0xc9, 0xfc, 0xde, 0xc3, 0x1a, 0x23, 0xbb, + 0xdd, 0xc8, 0x51, 0x0c, 0x3a, 0x72, 0xfa, 0x73, + 0x6f, 0xb7, 0xee, 0x61, 0x39, 0x03, 0x01, 0x3f, + 0x7f, 0x94, 0x2e, 0x2e, 0xba, 0x3a, 0xbb, 0xb4, + 0xfa, 0x6a, 0x17, 0xfe, 0xea, 0xef, 0x5e, 0x66, + 0x97, 0x3f, 0x32, 0x3d, 0xd7, 0x3e, 0xb1, 0xf1, + 0x6c, 0x14, 0x4c, 0xfd, 0x37, 0xd3, 0x38, 0x80, + 0xfb, 0xde, 0xa6, 0x24, 0x1e, 0xc8, 0xca, 0x7f, + 0x3a, 0x93, 0xd8, 0x8b, 0x18, 0x13, 0xb2, 0xe5, + 0xe4, 0x93, 0x05, 0x53, 0x4f, 0x84, 0x66, 0xa7, + 0x58, 0x5c, 0x7b, 0x86, 0x52, 0x6d, 0x0d, 0xce, + 0xa4, 0x30, 0x7d, 0xb6, 0x18, 0x9f, 0xeb, 0xff, + 0x22, 0xbb, 0x72, 0x29, 0xb9, 0x44, 0x0b, 0x48, + 0x1e, 0x84, 0x71, 0x81, 0xe3, 0x6d, 0x73, 0x26, + 0x92, 0xb4, 0x4d, 0x2a, 0x29, 0xb8, 0x1f, 0x72, + 0xed, 0xd0, 0xe1, 0x64, 0x77, 0xea, 0x8e, 0x88, + 0x0f, 0xef, 0x3f, 0xb1, 0x3b, 0xad, 0xf9, 0xc9, + 0x8b, 0xd0, 0xac, 0xc6, 0xcc, 0xa9, 0x40, 0xcc, + 0x76, 0xf6, 0x3b, 0x53, 0xb5, 0x88, 0xcb, 0xc8, + 0x37, 0xf1, 0xa2, 0xba, 0x23, 0x15, 0x99, 0x09, + 0xcc, 0xe7, 0x7a, 0x3b, 0x37, 0xf7, 0x58, 0xc8, + 0x46, 0x8c, 0x2b, 0x2f, 0x4e, 0x0e, 0xa6, 0x5c, + 0xea, 0x85, 0x55, 0xba, 0x02, 0x0e, 0x0e, 0x48, + 0xbc, 0xe1, 0xb1, 0x01, 0x35, 0x79, 0x13, 0x3d, + 0x1b, 0xc0, 0x53, 0x68, 0x11, 0xe7, 0x95, 0x0f, + 0x9d, 0x3f, 0x4c, 0x47, 0x7b, 0x4d, 0x1c, 0xae, + 0x50, 0x9b, 0xcb, 0xdd, 0x05, 0x8d, 0x9a, 0x97, + 0xfd, 0x8c, 0xef, 0x0c, 0x1d, 0x67, 0x73, 0xa8, + 0x28, 0x36, 0xd5, 0xb6, 0x92, 0x33, 0x40, 0x75, + 0x0b, 0x51, 0xc3, 0x64, 0xba, 0x1d, 0xc2, 0xcc, + 0xee, 0x7d, 0x54, 0x0f, 0x27, 0x69, 0xa7, 0x27, + 0x63, 0x30, 0x29, 0xd9, 0xc8, 0x84, 0xd8, 0xdf, + 0x9f, 0x68, 0x8d, 0x04, 0xca, 0xa6, 0xc5, 0xc7, + 0x7a, 0x5c, 0xc8, 0xd1, 0xcb, 0x4a, 0xec, 0xd0, + 0xd8, 0x20, 0x69, 0xc5, 0x17, 0xcd, 0x78, 0xc8, + 0x75, 0x23, 0x30, 0x69, 0xc9, 0xd4, 0xea, 0x5c, + 0x4f, 0x6b, 0x86, 0x3f, 0x8b, 0xfe, 0xee, 0x44, + 0xc9, 0x7c, 0xb7, 0xdd, 0x3e, 0xe5, 0xec, 0x54, + 0x03, 0x3e, 0xaa, 0x82, 0xc6, 0xdf, 0xb2, 0x38, + 0x0e, 0x5d, 0xb3, 0x88, 0xd9, 0xd3, 0x69, 0x5f, + 0x8f, 0x70, 0x8a, 0x7e, 0x11, 0xd9, 0x1e, 0x7b, + 0x38, 0xf1, 0x42, 0x1a, 0xc0, 0x35, 0xf5, 0xc7, + 0x36, 0x85, 0xf5, 0xf7, 0xb8, 0x7e, 0xc7, 0xef, + 0x18, 0xf1, 0x63, 0xd6, 0x7a, 0xc6, 0xc9, 0x0e, + 0x4d, 0x69, 0x4f, 0x84, 0xef, 0x26, 0x41, 0x0c, + 0xec, 0xc7, 0xe0, 0x7e, 0x3c, 0x67, 0x01, 0x4c, + 0x62, 0x1a, 0x20, 0x6f, 0xee, 0x47, 0x4d, 0xc0, + 0x99, 0x13, 0x8d, 0x91, 0x4a, 0x26, 0xd4, 0x37, + 0x28, 0x90, 0x58, 0x75, 0x66, 0x2b, 0x0a, 0xdf, + 0xda, 0xee, 0x92, 0x25, 0x90, 0x62, 0x39, 0x9e, + 0x44, 0x98, 0xad, 0xc1, 0x88, 0xed, 0xe4, 0xb4, + 0xaf, 0xf5, 0x8c, 0x9b, 0x48, 0x4d, 0x56, 0x60, + 0x97, 0x0f, 0x61, 0x59, 0x9e, 0xa6, 0x27, 0xfe, + 0xc1, 0x91, 0x15, 0x38, 0xb8, 0x0f, 0xae, 0x61, + 0x7d, 0x26, 0x13, 0x5a, 0x73, 0xff, 0x1c, 0xa3, + 0x61, 0x04, 0x58, 0x48, 0x55, 0x44, 0x11, 0xfe, + 0x15, 0xca, 0xc3, 0xbd, 0xca, 0xc5, 0xb4, 0x40, + 0x5d, 0x1b, 0x7f, 0x39, 0xb5, 0x9c, 0x35, 0xec, + 0x61, 0x15, 0x32, 0x32, 0xb8, 0x4e, 0x40, 0x9f, + 0x17, 0x1f, 0x0a, 0x4d, 0xa9, 0x91, 0xef, 0xb7, + 0xb0, 0xeb, 0xc2, 0x83, 0x9a, 0x6c, 0xd2, 0x79, + 0x43, 0x78, 0x5e, 0x2f, 0xe5, 0xdd, 0x1a, 0x3c, + 0x45, 0xab, 0x29, 0x40, 0x3a, 0x37, 0x5b, 0x6f, + 0xd7, 0xfc, 0x48, 0x64, 0x3c, 0x49, 0xfb, 0x21, + 0xbe, 0xc3, 0xff, 0x07, 0xfb, 0x17, 0xe9, 0xc9, + 0x0c, 0x4c, 0x5c, 0x15, 0x9e, 0x8e, 0x22, 0x30, + 0x0a, 0xde, 0x48, 0x7f, 0xdb, 0x0d, 0xd1, 0x2b, + 0x87, 0x38, 0x9e, 0xcc, 0x5a, 0x01, 0x16, 0xee, + 0x75, 0x49, 0x0d, 0x30, 0x01, 0x34, 0x6a, 0xb6, + 0x9a, 0x5a, 0x2a, 0xec, 0xbb, 0x48, 0xac, 0xd3, + 0x77, 0x83, 0xd8, 0x08, 0x86, 0x4f, 0x48, 0x09, + 0x29, 0x41, 0x79, 0xa1, 0x03, 0x12, 0xc4, 0xcd, + 0x90, 0x55, 0x47, 0x66, 0x74, 0x9a, 0xcc, 0x4f, + 0x35, 0x8c, 0xd6, 0x98, 0xef, 0xeb, 0x45, 0xb9, + 0x9a, 0x26, 0x2f, 0x39, 0xa5, 0x70, 0x6d, 0xfc, + 0xb4, 0x51, 0xee, 0xf4, 0x9c, 0xe7, 0x38, 0x59, + 0xad, 0xf4, 0xbc, 0x46, 0xff, 0x46, 0x8e, 0x60, + 0x9c, 0xa3, 0x60, 0x1d, 0xf8, 0x26, 0x72, 0xf5, + 0x72, 0x9d, 0x68, 0x80, 0x04, 0xf6, 0x0b, 0xa1, + 0x0a, 0xd5, 0xa7, 0x82, 0x3a, 0x3e, 0x47, 0xa8, + 0x5a, 0xde, 0x59, 0x4f, 0x7b, 0x07, 0xb3, 0xe9, + 0x24, 0x19, 0x3d, 0x34, 0x05, 0xec, 0xf1, 0xab, + 0x6e, 0x64, 0x8f, 0xd3, 0xe6, 0x41, 0x86, 0x80, + 0x70, 0xe3, 0x8d, 0x60, 0x9c, 0x34, 0x25, 0x01, + 0x07, 0x4d, 0x19, 0x41, 0x4e, 0x3d, 0x5c, 0x7e, + 0xa8, 0xf5, 0xcc, 0xd5, 0x7b, 0xe2, 0x7d, 0x3d, + 0x49, 0x86, 0x7d, 0x07, 0xb7, 0x10, 0xe3, 0x35, + 0xb8, 0x84, 0x6d, 0x76, 0xab, 0x17, 0xc6, 0x38, + 0xb4, 0xd3, 0x28, 0x57, 0xad, 0xd3, 0x88, 0x5a, + 0xda, 0xea, 0xc8, 0x94, 0xcc, 0x37, 0x19, 0xac, + 0x9c, 0x9f, 0x4b, 0x00, 0x15, 0xc0, 0xc8, 0xca, + 0x1f, 0x15, 0xaa, 0xe0, 0xdb, 0xf9, 0x2f, 0x57, + 0x1b, 0x24, 0xc7, 0x6f, 0x76, 0x29, 0xfb, 0xed, + 0x25, 0x0d, 0xc0, 0xfe, 0xbd, 0x5a, 0xbf, 0x20, + 0x08, 0x51, 0x05, 0xec, 0x71, 0xa3, 0xbf, 0xef, + 0x5e, 0x99, 0x75, 0xdb, 0x3c, 0x5f, 0x9a, 0x8c, + 0xbb, 0x19, 0x5c, 0x0e, 0x93, 0x19, 0xf8, 0x6a, + 0xbc, 0xf2, 0x12, 0x54, 0x2f, 0xcb, 0x28, 0x64, + 0x88, 0xb3, 0x92, 0x0d, 0x96, 0xd1, 0xa6, 0xe4, + 0x1f, 0xf1, 0x4d, 0xa4, 0xab, 0x1c, 0xee, 0x54, + 0xf2, 0xad, 0x29, 0x6d, 0x32, 0x37, 0xb2, 0x16, + 0x77, 0x5c, 0xdc, 0x2e, 0x54, 0xec, 0x75, 0x26, + 0xc6, 0x36, 0xd9, 0x17, 0x2c, 0xf1, 0x7a, 0xdc, + 0x4b, 0xf1, 0xe2, 0xd9, 0x95, 0xba, 0xac, 0x87, + 0xc1, 0xf3, 0x8e, 0x58, 0x08, 0xd8, 0x87, 0x60, + 0xc9, 0xee, 0x6a, 0xde, 0xa4, 0xd2, 0xfc, 0x0d, + 0xe5, 0x36, 0xc4, 0x5c, 0x52, 0xb3, 0x07, 0x54, + 0x65, 0x24, 0xc1, 0xb1, 0xd1, 0xb1, 0x53, 0x13, + 0x31, 0x79, 0x7f, 0x05, 0x76, 0xeb, 0x37, 0x59, + 0x15, 0x2b, 0xd1, 0x3f, 0xac, 0x08, 0x97, 0xeb, + 0x91, 0x98, 0xdf, 0x6c, 0x09, 0x0d, 0x04, 0x9f, + 0xdc, 0x3b, 0x0e, 0x60, 0x68, 0x47, 0x23, 0x15, + 0x16, 0xc6, 0x0b, 0x35, 0xf8, 0x77, 0xa2, 0x78, + 0x50, 0xd4, 0x64, 0x22, 0x33, 0xff, 0xfb, 0x93, + 0x71, 0x46, 0x50, 0x39, 0x1b, 0x9c, 0xea, 0x4e, + 0x8d, 0x0c, 0x37, 0xe5, 0x5c, 0x51, 0x3a, 0x31, + 0xb2, 0x85, 0x84, 0x3f, 0x41, 0xee, 0xa2, 0xc1, + 0xc6, 0x13, 0x3b, 0x54, 0x28, 0xd2, 0x18, 0x37, + 0xcc, 0x46, 0x9f, 0x6a, 0x91, 0x3d, 0x5a, 0x15, + 0x3c, 0x89, 0xa3, 0x61, 0x06, 0x7d, 0x2e, 0x78, + 0xbe, 0x7d, 0x40, 0xba, 0x2f, 0x95, 0xb1, 0x2f, + 0x87, 0x3b, 0x8a, 0xbe, 0x6a, 0xf4, 0xc2, 0x31, + 0x74, 0xee, 0x91, 0xe0, 0x23, 0xaa, 0x5d, 0x7f, + 0xdd, 0xf0, 0x44, 0x8c, 0x0b, 0x59, 0x2b, 0xfc, + 0x48, 0x3a, 0xdf, 0x07, 0x05, 0x38, 0x6c, 0xc9, + 0xeb, 0x18, 0x24, 0x68, 0x8d, 0x58, 0x98, 0xd3, + 0x31, 0xa3, 0xe4, 0x70, 0x59, 0xb1, 0x21, 0xbe, + 0x7e, 0x65, 0x7d, 0xb8, 0x04, 0xab, 0xf6, 0xe4, + 0xd7, 0xda, 0xec, 0x09, 0x8f, 0xda, 0x6d, 0x24, + 0x07, 0xcc, 0x29, 0x17, 0x05, 0x78, 0x1a, 0xc1, + 0xb1, 0xce, 0xfc, 0xaa, 0x2d, 0xe7, 0xcc, 0x85, + 0x84, 0x84, 0x03, 0x2a, 0x0c, 0x3f, 0xa9, 0xf8, + 0xfd, 0x84, 0x53, 0x59, 0x5c, 0xf0, 0xd4, 0x09, + 0xf0, 0xd2, 0x6c, 0x32, 0x03, 0xb0, 0xa0, 0x8c, + 0x52, 0xeb, 0x23, 0x91, 0x88, 0x43, 0x13, 0x46, + 0xf6, 0x1e, 0xb4, 0x1b, 0xf5, 0x8e, 0x3a, 0xb5, + 0x3d, 0x00, 0xf6, 0xe5, 0x08, 0x3d, 0x5f, 0x39, + 0xd3, 0x21, 0x69, 0xbc, 0x03, 0x22, 0x3a, 0xd2, + 0x5c, 0x84, 0xf8, 0x15, 0xc4, 0x80, 0x0b, 0xbc, + 0x29, 0x3c, 0xf3, 0x95, 0x98, 0xcd, 0x8f, 0x35, + 0xbc, 0xa5, 0x3e, 0xfc, 0xd4, 0x13, 0x9e, 0xde, + 0x4f, 0xce, 0x71, 0x9d, 0x09, 0xad, 0xf2, 0x80, + 0x6b, 0x65, 0x7f, 0x03, 0x00, 0x14, 0x7c, 0x15, + 0x85, 0x40, 0x6d, 0x70, 0xea, 0xdc, 0xb3, 0x63, + 0x35, 0x4f, 0x4d, 0xe0, 0xd9, 0xd5, 0x3c, 0x58, + 0x56, 0x23, 0x80, 0xe2, 0x36, 0xdd, 0x75, 0x1d, + 0x94, 0x11, 0x41, 0x8e, 0xe0, 0x81, 0x8e, 0xcf, + 0xe0, 0xe5, 0xf6, 0xde, 0xd1, 0xe7, 0x04, 0x12, + 0x79, 0x92, 0x2b, 0x71, 0x2a, 0x79, 0x8b, 0x7c, + 0x44, 0x79, 0x16, 0x30, 0x4e, 0xf4, 0xf6, 0x9b, + 0xb7, 0x40, 0xa3, 0x5a, 0xa7, 0x69, 0x3e, 0xc1, + 0x3a, 0x04, 0xd0, 0x88, 0xa0, 0x3b, 0xdd, 0xc6, + 0x9e, 0x7e, 0x1e, 0x1e, 0x8f, 0x44, 0xf7, 0x73, + 0x67, 0x1e, 0x1a, 0x78, 0xfa, 0x62, 0xf4, 0xa9, + 0xa8, 0xc6, 0x5b, 0xb8, 0xfa, 0x06, 0x7d, 0x5e, + 0x38, 0x1c, 0x9a, 0x39, 0xe9, 0x39, 0x98, 0x22, + 0x0b, 0xa7, 0xac, 0x0b, 0xf3, 0xbc, 0xf1, 0xeb, + 0x8c, 0x81, 0xe3, 0x48, 0x8a, 0xed, 0x42, 0xc2, + 0x38, 0xcf, 0x3e, 0xda, 0xd2, 0x89, 0x8d, 0x9c, + 0x53, 0xb5, 0x2f, 0x41, 0x01, 0x26, 0x84, 0x9c, + 0xa3, 0x56, 0xf6, 0x49, 0xc7, 0xd4, 0x9f, 0x93, + 0x1b, 0x96, 0x49, 0x5e, 0xad, 0xb3, 0x84, 0x1f, + 0x3c, 0xa4, 0xe0, 0x9b, 0xd1, 0x90, 0xbc, 0x38, + 0x6c, 0xdd, 0x95, 0x4d, 0x9d, 0xb1, 0x71, 0x57, + 0x2d, 0x34, 0xe8, 0xb8, 0x42, 0xc7, 0x99, 0x03, + 0xc7, 0x07, 0x30, 0x65, 0x91, 0x55, 0xd5, 0x90, + 0x70, 0x97, 0x37, 0x68, 0xd4, 0x11, 0xf9, 0xe8, + 0xce, 0xec, 0xdc, 0x34, 0xd5, 0xd3, 0xb7, 0xc4, + 0xb8, 0x97, 0x05, 0x92, 0xad, 0xf8, 0xe2, 0x36, + 0x64, 0x41, 0xc9, 0xc5, 0x41, 0x77, 0x52, 0xd7, + 0x2c, 0xa5, 0x24, 0x2f, 0xd9, 0x34, 0x0b, 0x47, + 0x35, 0xa7, 0x28, 0x8b, 0xc5, 0xcd, 0xe9, 0x46, + 0xac, 0x39, 0x94, 0x3c, 0x10, 0xc6, 0x29, 0x73, + 0x0e, 0x0e, 0x5d, 0xe0, 0x71, 0x03, 0x8a, 0x72, + 0x0e, 0x26, 0xb0, 0x7d, 0x84, 0xed, 0x95, 0x23, + 0x49, 0x5a, 0x45, 0x83, 0x45, 0x60, 0x11, 0x4a, + 0x46, 0x31, 0xd4, 0xd8, 0x16, 0x54, 0x98, 0x58, + 0xed, 0x6d, 0xcc, 0x5d, 0xd6, 0x50, 0x61, 0x9f, + 0x9d, 0xc5, 0x3e, 0x9d, 0x32, 0x47, 0xde, 0x96, + 0xe1, 0x5d, 0xd8, 0xf8, 0xb4, 0x69, 0x6f, 0xb9, + 0x15, 0x90, 0x57, 0x7a, 0xf6, 0xad, 0xb0, 0x5b, + 0xf5, 0xa6, 0x36, 0x94, 0xfd, 0x84, 0xce, 0x1c, + 0x0f, 0x4b, 0xd0, 0xc2, 0x5b, 0x6b, 0x56, 0xef, + 0x73, 0x93, 0x0b, 0xc3, 0xee, 0xd9, 0xcf, 0xd3, + 0xa4, 0x22, 0x58, 0xcd, 0x50, 0x6e, 0x65, 0xf4, + 0xe9, 0xb7, 0x71, 0xaf, 0x4b, 0xb3, 0xb6, 0x2f, + 0x0f, 0x0e, 0x3b, 0xc9, 0x85, 0x14, 0xf5, 0x17, + 0xe8, 0x7a, 0x3a, 0xbf, 0x5f, 0x5e, 0xf8, 0x18, + 0x48, 0xa6, 0x72, 0xab, 0x06, 0x95, 0xe9, 0xc8, + 0xa7, 0xf4, 0x32, 0x44, 0x04, 0x0c, 0x84, 0x98, + 0x73, 0xe3, 0x89, 0x8d, 0x5f, 0x7e, 0x4a, 0x42, + 0x8f, 0xc5, 0x28, 0xb1, 0x82, 0xef, 0x1c, 0x97, + 0x31, 0x3b, 0x4d, 0xe0, 0x0e, 0x10, 0x10, 0x97, + 0x93, 0x49, 0x78, 0x2f, 0x0d, 0x86, 0x8b, 0xa1, + 0x53, 0xa9, 0x81, 0x20, 0x79, 0xe7, 0x07, 0x77, + 0xb6, 0xac, 0x5e, 0xd2, 0x05, 0xcd, 0xe9, 0xdb, + 0x8a, 0x94, 0x82, 0x8a, 0x23, 0xb9, 0x3d, 0x1c, + 0xa9, 0x7d, 0x72, 0x4a, 0xed, 0x33, 0xa3, 0xdb, + 0x21, 0xa7, 0x86, 0x33, 0x45, 0xa5, 0xaa, 0x56, + 0x45, 0xb5, 0x83, 0x29, 0x40, 0x47, 0x79, 0x04, + 0x6e, 0xb9, 0x95, 0xd0, 0x81, 0x77, 0x2d, 0x48, + 0x1e, 0xfe, 0xc3, 0xc2, 0x1e, 0xe5, 0xf2, 0xbe, + 0xfd, 0x3b, 0x94, 0x9f, 0xc4, 0xc4, 0x26, 0x9d, + 0xe4, 0x66, 0x1e, 0x19, 0xee, 0x6c, 0x79, 0x97, + 0x11, 0x31, 0x4b, 0x0d, 0x01, 0xcb, 0xde, 0xa8, + 0xf6, 0x6d, 0x7c, 0x39, 0x46, 0x4e, 0x7e, 0x3f, + 0x94, 0x17, 0xdf, 0xa1, 0x7d, 0xd9, 0x1c, 0x8e, + 0xbc, 0x7d, 0x33, 0x7d, 0xe3, 0x12, 0x40, 0xca, + 0xab, 0x37, 0x11, 0x46, 0xd4, 0xae, 0xef, 0x44, + 0xa2, 0xb3, 0x6a, 0x66, 0x0e, 0x0c, 0x90, 0x7f, + 0xdf, 0x5c, 0x66, 0x5f, 0xf2, 0x94, 0x9f, 0xa6, + 0x73, 0x4f, 0xeb, 0x0d, 0xad, 0xbf, 0xc0, 0x63, + 0x5c, 0xdc, 0x46, 0x51, 0xe8, 0x8e, 0x90, 0x19, + 0xa8, 0xa4, 0x3c, 0x91, 0x79, 0xfa, 0x7e, 0x58, + 0x85, 0x13, 0x55, 0xc5, 0x19, 0x82, 0x37, 0x1b, + 0x0a, 0x02, 0x1f, 0x99, 0x6b, 0x18, 0xf1, 0x28, + 0x08, 0xa2, 0x73, 0xb8, 0x0f, 0x2e, 0xcd, 0xbf, + 0xf3, 0x86, 0x7f, 0xea, 0xef, 0xd0, 0xbb, 0xa6, + 0x21, 0xdf, 0x49, 0x73, 0x51, 0xcc, 0x36, 0xd3, + 0x3e, 0xa0, 0xf8, 0x44, 0xdf, 0xd3, 0xa6, 0xbe, + 0x8a, 0xd4, 0x57, 0xdd, 0x72, 0x94, 0x61, 0x0f, + 0x82, 0xd1, 0x07, 0xb8, 0x7c, 0x18, 0x83, 0xdf, + 0x3a, 0xe5, 0x50, 0x6a, 0x82, 0x20, 0xac, 0xa9, + 0xa8, 0xff, 0xd9, 0xf3, 0x77, 0x33, 0x5a, 0x9e, + 0x7f, 0x6d, 0xfe, 0x5d, 0x33, 0x41, 0x42, 0xe7, + 0x6c, 0x19, 0xe0, 0x44, 0x8a, 0x15, 0xf6, 0x70, + 0x98, 0xb7, 0x68, 0x4d, 0xfa, 0x97, 0x39, 0xb0, + 0x8e, 0xe8, 0x84, 0x8b, 0x75, 0x30, 0xb7, 0x7d, + 0x92, 0x69, 0x20, 0x9c, 0x81, 0xfb, 0x4b, 0xf4, + 0x01, 0x50, 0xeb, 0xce, 0x0c, 0x1c, 0x6c, 0xb5, + 0x4a, 0xd7, 0x27, 0x0c, 0xce, 0xbb, 0xe5, 0x85, + 0xf0, 0xb6, 0xee, 0xd5, 0x70, 0xdd, 0x3b, 0xfc, + 0xd4, 0x99, 0xf1, 0x33, 0xdd, 0x8b, 0xc4, 0x2f, + 0xae, 0xab, 0x74, 0x96, 0x32, 0xc7, 0x4c, 0x56, + 0x3c, 0x89, 0x0f, 0x96, 0x0b, 0x42, 0xc0, 0xcb, + 0xee, 0x0f, 0x0b, 0x8c, 0xfb, 0x7e, 0x47, 0x7b, + 0x64, 0x48, 0xfd, 0xb2, 0x00, 0x80, 0x89, 0xa5, + 0x13, 0x55, 0x62, 0xfc, 0x8f, 0xe2, 0x42, 0x03, + 0xb7, 0x4e, 0x2a, 0x79, 0xb4, 0x82, 0xea, 0x23, + 0x49, 0xda, 0xaf, 0x52, 0x63, 0x1e, 0x60, 0x03, + 0x89, 0x06, 0x44, 0x46, 0x08, 0xc3, 0xc4, 0x87, + 0x70, 0x2e, 0xda, 0x94, 0xad, 0x6b, 0xe0, 0xe4, + 0xd1, 0x8a, 0x06, 0xc2, 0xa8, 0xc0, 0xa7, 0x43, + 0x3c, 0x47, 0x52, 0x0e, 0xc3, 0x77, 0x81, 0x11, + 0x67, 0x0e, 0xa0, 0x70, 0x04, 0x47, 0x29, 0x40, + 0x86, 0x0d, 0x34, 0x56, 0xa7, 0xc9, 0x35, 0x59, + 0x68, 0xdc, 0x93, 0x81, 0x70, 0xee, 0x86, 0xd9, + 0x80, 0x06, 0x40, 0x4f, 0x1a, 0x0d, 0x40, 0x30, + 0x0b, 0xcb, 0x96, 0x47, 0xc1, 0xb7, 0x52, 0xfd, + 0x56, 0xe0, 0x72, 0x4b, 0xfb, 0xbd, 0x92, 0x45, + 0x61, 0x71, 0xc2, 0x33, 0x11, 0xbf, 0x52, 0x83, + 0x79, 0x26, 0xe0, 0x49, 0x6b, 0xb7, 0x05, 0x8b, + 0xe8, 0x0e, 0x87, 0x31, 0xd7, 0x9d, 0x8a, 0xf5, + 0xc0, 0x5f, 0x2e, 0x58, 0x4a, 0xdb, 0x11, 0xb3, + 0x6c, 0x30, 0x2a, 0x46, 0x19, 0xe3, 0x27, 0x84, + 0x1f, 0x63, 0x6e, 0xf6, 0x57, 0xc7, 0xc9, 0xd8, + 0x5e, 0xba, 0xb3, 0x87, 0xd5, 0x83, 0x26, 0x34, + 0x21, 0x9e, 0x65, 0xde, 0x42, 0xd3, 0xbe, 0x7b, + 0xbc, 0x91, 0x71, 0x44, 0x4d, 0x99, 0x3b, 0x31, + 0xe5, 0x3f, 0x11, 0x4e, 0x7f, 0x13, 0x51, 0x3b, + 0xae, 0x79, 0xc9, 0xd3, 0x81, 0x8e, 0x25, 0x40, + 0x10, 0xfc, 0x07, 0x1e, 0xf9, 0x7b, 0x9a, 0x4b, + 0x6c, 0xe3, 0xb3, 0xad, 0x1a, 0x0a, 0xdd, 0x9e, + 0x59, 0x0c, 0xa2, 0xcd, 0xae, 0x48, 0x4a, 0x38, + 0x5b, 0x47, 0x41, 0x94, 0x65, 0x6b, 0xbb, 0xeb, + 0x5b, 0xe3, 0xaf, 0x07, 0x5b, 0xd4, 0x4a, 0xa2, + 0xc9, 0x5d, 0x2f, 0x64, 0x03, 0xd7, 0x3a, 0x2c, + 0x6e, 0xce, 0x76, 0x95, 0xb4, 0xb3, 0xc0, 0xf1, + 0xe2, 0x45, 0x73, 0x7a, 0x5c, 0xab, 0xc1, 0xfc, + 0x02, 0x8d, 0x81, 0x29, 0xb3, 0xac, 0x07, 0xec, + 0x40, 0x7d, 0x45, 0xd9, 0x7a, 0x59, 0xee, 0x34, + 0xf0, 0xe9, 0xd5, 0x7b, 0x96, 0xb1, 0x3d, 0x95, + 0xcc, 0x86, 0xb5, 0xb6, 0x04, 0x2d, 0xb5, 0x92, + 0x7e, 0x76, 0xf4, 0x06, 0xa9, 0xa3, 0x12, 0x0f, + 0xb1, 0xaf, 0x26, 0xba, 0x7c, 0xfc, 0x7e, 0x1c, + 0xbc, 0x2c, 0x49, 0x97, 0x53, 0x60, 0x13, 0x0b, + 0xa6, 0x61, 0x83, 0x89, 0x42, 0xd4, 0x17, 0x0c, + 0x6c, 0x26, 0x52, 0xc3, 0xb3, 0xd4, 0x67, 0xf5, + 0xe3, 0x04, 0xb7, 0xf4, 0xcb, 0x80, 0xb8, 0xcb, + 0x77, 0x56, 0x3e, 0xaa, 0x57, 0x54, 0xee, 0xb4, + 0x2c, 0x67, 0xcf, 0xf2, 0xdc, 0xbe, 0x55, 0xf9, + 0x43, 0x1f, 0x6e, 0x22, 0x97, 0x67, 0x7f, 0xc4, + 0xef, 0xb1, 0x26, 0x31, 0x1e, 0x27, 0xdf, 0x41, + 0x80, 0x47, 0x6c, 0xe2, 0xfa, 0xa9, 0x8c, 0x2a, + 0xf6, 0xf2, 0xab, 0xf0, 0x15, 0xda, 0x6c, 0xc8, + 0xfe, 0xb5, 0x23, 0xde, 0xa9, 0x05, 0x3f, 0x06, + 0x54, 0x4c, 0xcd, 0xe1, 0xab, 0xfc, 0x0e, 0x62, + 0x33, 0x31, 0x73, 0x2c, 0x76, 0xcb, 0xb4, 0x47, + 0x1e, 0x20, 0xad, 0xd8, 0xf2, 0x31, 0xdd, 0xc4, + 0x8b, 0x0c, 0x77, 0xbe, 0xe1, 0x8b, 0x26, 0x00, + 0x02, 0x58, 0xd6, 0x8d, 0xef, 0xad, 0x74, 0x67, + 0xab, 0x3f, 0xef, 0xcb, 0x6f, 0xb0, 0xcc, 0x81, + 0x44, 0x4c, 0xaf, 0xe9, 0x49, 0x4f, 0xdb, 0xa0, + 0x25, 0xa4, 0xf0, 0x89, 0xf1, 0xbe, 0xd8, 0x10, + 0xff, 0xb1, 0x3b, 0x4b, 0xfa, 0x98, 0xf5, 0x79, + 0x6d, 0x1e, 0x69, 0x4d, 0x57, 0xb1, 0xc8, 0x19, + 0x1b, 0xbd, 0x1e, 0x8c, 0x84, 0xb7, 0x7b, 0xe8, + 0xd2, 0x2d, 0x09, 0x41, 0x41, 0x37, 0x3d, 0xb1, + 0x6f, 0x26, 0x5d, 0x71, 0x16, 0x3d, 0xb7, 0x83, + 0x27, 0x2c, 0xa7, 0xb6, 0x50, 0xbd, 0x91, 0x86, + 0xab, 0x24, 0xa1, 0x38, 0xfd, 0xea, 0x71, 0x55, + 0x7e, 0x9a, 0x07, 0x77, 0x4b, 0xfa, 0x61, 0x66, + 0x20, 0x1e, 0x28, 0x95, 0x18, 0x1b, 0xa4, 0xa0, + 0xfd, 0xc0, 0x89, 0x72, 0x43, 0xd9, 0x3b, 0x49, + 0x5a, 0x3f, 0x9d, 0xbf, 0xdb, 0xb4, 0x46, 0xea, + 0x42, 0x01, 0x77, 0x23, 0x68, 0x95, 0xb6, 0x24, + 0xb3, 0xa8, 0x6c, 0x28, 0x3b, 0x11, 0x40, 0x7e, + 0x18, 0x65, 0x6d, 0xd8, 0x24, 0x42, 0x7d, 0x88, + 0xc0, 0x52, 0xd9, 0x05, 0xe4, 0x95, 0x90, 0x87, + 0x8c, 0xf4, 0xd0, 0x6b, 0xb9, 0x83, 0x99, 0x34, + 0x6d, 0xfe, 0x54, 0x40, 0x94, 0x52, 0x21, 0x4f, + 0x14, 0x25, 0xc5, 0xd6, 0x5e, 0x95, 0xdc, 0x0a, + 0x2b, 0x89, 0x20, 0x11, 0x84, 0x48, 0xd6, 0x3a, + 0xcd, 0x5c, 0x24, 0xad, 0x62, 0xe3, 0xb1, 0x93, + 0x25, 0x8d, 0xcd, 0x7e, 0xfc, 0x27, 0xa3, 0x37, + 0xfd, 0x84, 0xfc, 0x1b, 0xb2, 0xf1, 0x27, 0x38, + 0x5a, 0xb7, 0xfc, 0xf2, 0xfa, 0x95, 0x66, 0xd4, + 0xfb, 0xba, 0xa7, 0xd7, 0xa3, 0x72, 0x69, 0x48, + 0x48, 0x8c, 0xeb, 0x28, 0x89, 0xfe, 0x33, 0x65, + 0x5a, 0x36, 0x01, 0x7e, 0x06, 0x79, 0x0a, 0x09, + 0x3b, 0x74, 0x11, 0x9a, 0x6e, 0xbf, 0xd4, 0x9e, + 0x58, 0x90, 0x49, 0x4f, 0x4d, 0x08, 0xd4, 0xe5, + 0x4a, 0x09, 0x21, 0xef, 0x8b, 0xb8, 0x74, 0x3b, + 0x91, 0xdd, 0x36, 0x85, 0x60, 0x2d, 0xfa, 0xd4, + 0x45, 0x7b, 0x45, 0x53, 0xf5, 0x47, 0x87, 0x7e, + 0xa6, 0x37, 0xc8, 0x78, 0x7a, 0x68, 0x9d, 0x8d, + 0x65, 0x2c, 0x0e, 0x91, 0x5c, 0xa2, 0x60, 0xf0, + 0x8e, 0x3f, 0xe9, 0x1a, 0xcd, 0xaa, 0xe7, 0xd5, + 0x77, 0x18, 0xaf, 0xc9, 0xbc, 0x18, 0xea, 0x48, + 0x1b, 0xfb, 0x22, 0x48, 0x70, 0x16, 0x29, 0x9e, + 0x5b, 0xc1, 0x2c, 0x66, 0x23, 0xbc, 0xf0, 0x1f, + 0xef, 0xaf, 0xe4, 0xd6, 0x04, 0x19, 0x82, 0x7a, + 0x0b, 0xba, 0x4b, 0x46, 0xb1, 0x6a, 0x85, 0x5d, + 0xb4, 0x73, 0xd6, 0x21, 0xa1, 0x71, 0x60, 0x14, + 0xee, 0x0a, 0x77, 0xc4, 0x66, 0x2e, 0xf9, 0x69, + 0x30, 0xaf, 0x41, 0x0b, 0xc8, 0x83, 0x3c, 0x53, + 0x99, 0x19, 0x27, 0x46, 0xf7, 0x41, 0x6e, 0x56, + 0xdc, 0x94, 0x28, 0x67, 0x4e, 0xb7, 0x25, 0x48, + 0x8a, 0xc2, 0xe0, 0x60, 0x96, 0xcc, 0x18, 0xf4, + 0x84, 0xdd, 0xa7, 0x5e, 0x3e, 0x05, 0x0b, 0x26, + 0x26, 0xb2, 0x5c, 0x1f, 0x57, 0x1a, 0x04, 0x7e, + 0x6a, 0xe3, 0x2f, 0xb4, 0x35, 0xb6, 0x38, 0x40, + 0x40, 0xcd, 0x6f, 0x87, 0x2e, 0xef, 0xa3, 0xd7, + 0xa9, 0xc2, 0xe8, 0x0d, 0x27, 0xdf, 0x44, 0x62, + 0x99, 0xa0, 0xfc, 0xcf, 0x81, 0x78, 0xcb, 0xfe, + 0xe5, 0xa0, 0x03, 0x4e, 0x6c, 0xd7, 0xf4, 0xaf, + 0x7a, 0xbb, 0x61, 0x82, 0xfe, 0x71, 0x89, 0xb2, + 0x22, 0x7c, 0x8e, 0x83, 0x04, 0xce, 0xf6, 0x5d, + 0x84, 0x8f, 0x95, 0x6a, 0x7f, 0xad, 0xfd, 0x32, + 0x9c, 0x5e, 0xe4, 0x9c, 0x89, 0x60, 0x54, 0xaa, + 0x96, 0x72, 0xd2, 0xd7, 0x36, 0x85, 0xa9, 0x45, + 0xd2, 0x2a, 0xa1, 0x81, 0x49, 0x6f, 0x7e, 0x04, + 0xfa, 0xe2, 0xfe, 0x90, 0x26, 0x77, 0x5a, 0x33, + 0xb8, 0x04, 0x9a, 0x7a, 0xe6, 0x4c, 0x4f, 0xad, + 0x72, 0x96, 0x08, 0x28, 0x58, 0x13, 0xf8, 0xc4, + 0x1c, 0xf0, 0xc3, 0x45, 0x95, 0x49, 0x20, 0x8c, + 0x9f, 0x39, 0x70, 0xe1, 0x77, 0xfe, 0xd5, 0x4b, + 0xaf, 0x86, 0xda, 0xef, 0x22, 0x06, 0x83, 0x36, + 0x29, 0x12, 0x11, 0x40, 0xbc, 0x3b, 0x86, 0xaa, + 0xaa, 0x65, 0x60, 0xc3, 0x80, 0xca, 0xed, 0xa9, + 0xf3, 0xb0, 0x79, 0x96, 0xa2, 0x55, 0x27, 0x28, + 0x55, 0x73, 0x26, 0xa5, 0x50, 0xea, 0x92, 0x4b, + 0x3c, 0x5c, 0x82, 0x33, 0xf0, 0x01, 0x3f, 0x03, + 0xc1, 0x08, 0x05, 0xbf, 0x98, 0xf4, 0x9b, 0x6d, + 0xa5, 0xa8, 0xb4, 0x82, 0x0c, 0x06, 0xfa, 0xff, + 0x2d, 0x08, 0xf3, 0x05, 0x4f, 0x57, 0x2a, 0x39, + 0xd4, 0x83, 0x0d, 0x75, 0x51, 0xd8, 0x5b, 0x1b, + 0xd3, 0x51, 0x5a, 0x32, 0x2a, 0x9b, 0x32, 0xb2, + 0xf2, 0xa4, 0x96, 0x12, 0xf2, 0xae, 0x40, 0x34, + 0x67, 0xa8, 0xf5, 0x44, 0xd5, 0x35, 0x53, 0xfe, + 0xa3, 0x60, 0x96, 0x63, 0x0f, 0x1f, 0x6e, 0xb0, + 0x5a, 0x42, 0xa6, 0xfc, 0x51, 0x0b, 0x60, 0x27, + 0xbc, 0x06, 0x71, 0xed, 0x65, 0x5b, 0x23, 0x86, + 0x4a, 0x07, 0x3b, 0x22, 0x07, 0x46, 0xe6, 0x90, + 0x3e, 0xf3, 0x25, 0x50, 0x1b, 0x4c, 0x7f, 0x03, + 0x08, 0xa8, 0x36, 0x6b, 0x87, 0xe5, 0xe3, 0xdb, + 0x9a, 0x38, 0x83, 0xff, 0x9f, 0x1a, 0x9f, 0x57, + 0xa4, 0x2a, 0xf6, 0x37, 0xbc, 0x1a, 0xff, 0xc9, + 0x1e, 0x35, 0x0c, 0xc3, 0x7c, 0xa3, 0xb2, 0xe5, + 0xd2, 0xc6, 0xb4, 0x57, 0x47, 0xe4, 0x32, 0x16, + 0x6d, 0xa9, 0xae, 0x64, 0xe6, 0x2d, 0x8d, 0xc5, + 0x8d, 0x50, 0x8e, 0xe8, 0x1a, 0x22, 0x34, 0x2a, + 0xd9, 0xeb, 0x51, 0x90, 0x4a, 0xb1, 0x41, 0x7d, + 0x64, 0xf9, 0xb9, 0x0d, 0xf6, 0x23, 0x33, 0xb0, + 0x33, 0xf4, 0xf7, 0x3f, 0x27, 0x84, 0xc6, 0x0f, + 0x54, 0xa5, 0xc0, 0x2e, 0xec, 0x0b, 0x3a, 0x48, + 0x6e, 0x80, 0x35, 0x81, 0x43, 0x9b, 0x90, 0xb1, + 0xd0, 0x2b, 0xea, 0x21, 0xdc, 0xda, 0x5b, 0x09, + 0xf4, 0xcc, 0x10, 0xb4, 0xc7, 0xfe, 0x79, 0x51, + 0xc3, 0xc5, 0xac, 0x88, 0x74, 0x84, 0x0b, 0x4b, + 0xca, 0x79, 0x16, 0x29, 0xfb, 0x69, 0x54, 0xdf, + 0x41, 0x7e, 0xe9, 0xc7, 0x8e, 0xea, 0xa5, 0xfe, + 0xfc, 0x76, 0x0e, 0x90, 0xc4, 0x92, 0x38, 0xad, + 0x7b, 0x48, 0xe6, 0x6e, 0xf7, 0x21, 0xfd, 0x4e, + 0x93, 0x0a, 0x7b, 0x41, 0x83, 0x68, 0xfb, 0x57, + 0x51, 0x76, 0x34, 0xa9, 0x6c, 0x00, 0xaa, 0x4f, + 0x66, 0x65, 0x98, 0x4a, 0x4f, 0xa3, 0xa0, 0xef, + 0x69, 0x3f, 0xe3, 0x1c, 0x92, 0x8c, 0xfd, 0xd8, + 0xe8, 0xde, 0x7c, 0x7f, 0x3e, 0x84, 0x8e, 0x69, + 0x3c, 0xf1, 0xf2, 0x05, 0x46, 0xdc, 0x2f, 0x9d, + 0x5e, 0x6e, 0x4c, 0xfb, 0xb5, 0x99, 0x2a, 0x59, + 0x63, 0xc1, 0x34, 0xbc, 0x57, 0xc0, 0x0d, 0xb9, + 0x61, 0x25, 0xf3, 0x33, 0x23, 0x51, 0xb6, 0x0d, + 0x07, 0xa6, 0xab, 0x94, 0x4a, 0xb7, 0x2a, 0xea, + 0xee, 0xac, 0xa3, 0xc3, 0x04, 0x8b, 0x0e, 0x56, + 0xfe, 0x44, 0xa7, 0x39, 0xe2, 0xed, 0xed, 0xb4, + 0x22, 0x2b, 0xac, 0x12, 0x32, 0x28, 0x91, 0xd8, + 0xa5, 0xab, 0xff, 0x5f, 0xe0, 0x4b, 0xda, 0x78, + 0x17, 0xda, 0xf1, 0x01, 0x5b, 0xcd, 0xe2, 0x5f, + 0x50, 0x45, 0x73, 0x2b, 0xe4, 0x76, 0x77, 0xf4, + 0x64, 0x1d, 0x43, 0xfb, 0x84, 0x7a, 0xea, 0x91, + 0xae, 0xf9, 0x9e, 0xb7, 0xb4, 0xb0, 0x91, 0x5f, + 0x16, 0x35, 0x9a, 0x11, 0xb8, 0xc7, 0xc1, 0x8c, + 0xc6, 0x10, 0x8d, 0x2f, 0x63, 0x4a, 0xa7, 0x57, + 0x3a, 0x51, 0xd6, 0x32, 0x2d, 0x64, 0x72, 0xd4, + 0x66, 0xdc, 0x10, 0xa6, 0x67, 0xd6, 0x04, 0x23, + 0x9d, 0x0a, 0x11, 0x77, 0xdd, 0x37, 0x94, 0x17, + 0x3c, 0xbf, 0x8b, 0x65, 0xb0, 0x2e, 0x5e, 0x66, + 0x47, 0x64, 0xac, 0xdd, 0xf0, 0x84, 0xfd, 0x39, + 0xfa, 0x15, 0x5d, 0xef, 0xae, 0xca, 0xc1, 0x36, + 0xa7, 0x5c, 0xbf, 0xc7, 0x08, 0xc2, 0x66, 0x00, + 0x74, 0x74, 0x4e, 0x27, 0x3f, 0x55, 0x8a, 0xb7, + 0x38, 0x66, 0x83, 0x6d, 0xcf, 0x99, 0x9e, 0x60, + 0x8f, 0xdd, 0x2e, 0x62, 0x22, 0x0e, 0xef, 0x0c, + 0x98, 0xa7, 0x85, 0x74, 0x3b, 0x9d, 0xec, 0x9e, + 0xa9, 0x19, 0x72, 0xa5, 0x7f, 0x2c, 0x39, 0xb7, + 0x7d, 0xb7, 0xf1, 0x12, 0x65, 0x27, 0x4b, 0x5a, + 0xde, 0x17, 0xfe, 0xad, 0x44, 0xf3, 0x20, 0x4d, + 0xfd, 0xe4, 0x1f, 0xb5, 0x81, 0xb0, 0x36, 0x37, + 0x08, 0x6f, 0xc3, 0x0c, 0xe9, 0x85, 0x98, 0x82, + 0xa9, 0x62, 0x0c, 0xc4, 0x97, 0xc0, 0x50, 0xc8, + 0xa7, 0x3c, 0x50, 0x9f, 0x43, 0xb9, 0xcd, 0x5e, + 0x4d, 0xfa, 0x1c, 0x4b, 0x0b, 0xa9, 0x98, 0x85, + 0x38, 0x92, 0xac, 0x8d, 0xe4, 0xad, 0x9b, 0x98, + 0xab, 0xd9, 0x38, 0xac, 0x62, 0x52, 0xa3, 0x22, + 0x63, 0x0f, 0xbf, 0x95, 0x48, 0xdf, 0x69, 0xe7, + 0x8b, 0x33, 0xd5, 0xb2, 0xbd, 0x05, 0x49, 0x49, + 0x9d, 0x57, 0x73, 0x19, 0x33, 0xae, 0xfa, 0x33, + 0xf1, 0x19, 0xa8, 0x80, 0xce, 0x04, 0x9f, 0xbc, + 0x1d, 0x65, 0x82, 0x1b, 0xe5, 0x3a, 0x51, 0xc8, + 0x1c, 0x21, 0xe3, 0x5d, 0xf3, 0x7d, 0x9b, 0x2f, + 0x2c, 0x1d, 0x4a, 0x7f, 0x9b, 0x68, 0x35, 0xa3, + 0xb2, 0x50, 0xf7, 0x62, 0x79, 0xcd, 0xf4, 0x98, + 0x4f, 0xe5, 0x63, 0x7c, 0x3e, 0x45, 0x31, 0x8c, + 0x16, 0xa0, 0x12, 0xc8, 0x58, 0xce, 0x39, 0xa6, + 0xbc, 0x54, 0xdb, 0xc5, 0xe0, 0xd5, 0xba, 0xbc, + 0xb9, 0x04, 0xf4, 0x8d, 0xe8, 0x2f, 0x15, 0x9d, +}; + +/* 100 test cases */ +static struct crc_test { + u32 crc; /* random starting crc */ + u32 start; /* random 6 bit offset in buf */ + u32 length; /* random 11 bit length of test */ + u32 crc_le; /* expected crc32_le result */ + u32 crc_be; /* expected crc32_be result */ + u32 crc32c_le; /* expected crc32c_le result */ +} test[] = +{ + {0x674bf11d, 0x00000038, 0x00000542, 0x0af6d466, 0xd8b6e4c1, + 0xf6e93d6c}, + {0x35c672c6, 0x0000003a, 0x000001aa, 0xc6d3dfba, 0x28aaf3ad, + 0x0fe92aca}, + {0x496da28e, 0x00000039, 0x000005af, 0xd933660f, 0x5d57e81f, + 0x52e1ebb8}, + {0x09a9b90e, 0x00000027, 0x000001f8, 0xb45fe007, 0xf45fca9a, + 0x0798af9a}, + {0xdc97e5a9, 0x00000025, 0x000003b6, 0xf81a3562, 0xe0126ba2, + 0x18eb3152}, + {0x47c58900, 0x0000000a, 0x000000b9, 0x8e58eccf, 0xf3afc793, + 0xd00d08c7}, + {0x292561e8, 0x0000000c, 0x00000403, 0xa2ba8aaf, 0x0b797aed, + 0x8ba966bc}, + {0x415037f6, 0x00000003, 0x00000676, 0xa17d52e8, 0x7f0fdf35, + 0x11d694a2}, + {0x3466e707, 0x00000026, 0x00000042, 0x258319be, 0x75c484a2, + 0x6ab3208d}, + {0xafd1281b, 0x00000023, 0x000002ee, 0x4428eaf8, 0x06c7ad10, + 0xba4603c5}, + {0xd3857b18, 0x00000028, 0x000004a2, 0x5c430821, 0xb062b7cb, + 0xe6071c6f}, + {0x1d825a8f, 0x0000002b, 0x0000050b, 0xd2c45f0c, 0xd68634e0, + 0x179ec30a}, + {0x5033e3bc, 0x0000000b, 0x00000078, 0xa3ea4113, 0xac6d31fb, + 0x0903beb8}, + {0x94f1fb5e, 0x0000000f, 0x000003a2, 0xfbfc50b1, 0x3cfe50ed, + 0x6a7cb4fa}, + {0xc9a0fe14, 0x00000009, 0x00000473, 0x5fb61894, 0x87070591, + 0xdb535801}, + {0x88a034b1, 0x0000001c, 0x000005ad, 0xc1b16053, 0x46f95c67, + 0x92bed597}, + {0xf0f72239, 0x00000020, 0x0000026d, 0xa6fa58f3, 0xf8c2c1dd, + 0x192a3f1b}, + {0xcc20a5e3, 0x0000003b, 0x0000067a, 0x7740185a, 0x308b979a, + 0xccbaec1a}, + {0xce589c95, 0x0000002b, 0x00000641, 0xd055e987, 0x40aae25b, + 0x7eabae4d}, + {0x78edc885, 0x00000035, 0x000005be, 0xa39cb14b, 0x035b0d1f, + 0x28c72982}, + {0x9d40a377, 0x0000003b, 0x00000038, 0x1f47ccd2, 0x197fbc9d, + 0xc3cd4d18}, + {0x703d0e01, 0x0000003c, 0x000006f1, 0x88735e7c, 0xfed57c5a, + 0xbca8f0e7}, + {0x776bf505, 0x0000000f, 0x000005b2, 0x5cc4fc01, 0xf32efb97, + 0x713f60b3}, + {0x4a3e7854, 0x00000027, 0x000004b8, 0x8d923c82, 0x0cbfb4a2, + 0xebd08fd5}, + {0x209172dd, 0x0000003b, 0x00000356, 0xb89e9c2b, 0xd7868138, + 0x64406c59}, + {0x3ba4cc5b, 0x0000002f, 0x00000203, 0xe51601a9, 0x5b2a1032, + 0x7421890e}, + {0xfc62f297, 0x00000000, 0x00000079, 0x71a8e1a2, 0x5d88685f, + 0xe9347603}, + {0x64280b8b, 0x00000016, 0x000007ab, 0x0fa7a30c, 0xda3a455f, + 0x1bef9060}, + {0x97dd724b, 0x00000033, 0x000007ad, 0x5788b2f4, 0xd7326d32, + 0x34720072}, + {0x61394b52, 0x00000035, 0x00000571, 0xc66525f1, 0xcabe7fef, + 0x48310f59}, + {0x29b4faff, 0x00000024, 0x0000006e, 0xca13751e, 0x993648e0, + 0x783a4213}, + {0x29bfb1dc, 0x0000000b, 0x00000244, 0x436c43f7, 0x429f7a59, + 0x9e8efd41}, + {0x86ae934b, 0x00000035, 0x00000104, 0x0760ec93, 0x9cf7d0f4, + 0xfc3d34a5}, + {0xc4c1024e, 0x0000002e, 0x000006b1, 0x6516a3ec, 0x19321f9c, + 0x17a52ae2}, + {0x3287a80a, 0x00000026, 0x00000496, 0x0b257eb1, 0x754ebd51, + 0x886d935a}, + {0xa4db423e, 0x00000023, 0x0000045d, 0x9b3a66dc, 0x873e9f11, + 0xeaaeaeb2}, + {0x7a1078df, 0x00000015, 0x0000014a, 0x8c2484c5, 0x6a628659, + 0x8e900a4b}, + {0x6048bd5b, 0x00000006, 0x0000006a, 0x897e3559, 0xac9961af, + 0xd74662b1}, + {0xd8f9ea20, 0x0000003d, 0x00000277, 0x60eb905b, 0xed2aaf99, + 0xd26752ba}, + {0xea5ec3b4, 0x0000002a, 0x000004fe, 0x869965dc, 0x6c1f833b, + 0x8b1fcd62}, + {0x2dfb005d, 0x00000016, 0x00000345, 0x6a3b117e, 0xf05e8521, + 0xf54342fe}, + {0x5a214ade, 0x00000020, 0x000005b6, 0x467f70be, 0xcb22ccd3, + 0x5b95b988}, + {0xf0ab9cca, 0x00000032, 0x00000515, 0xed223df3, 0x7f3ef01d, + 0x2e1176be}, + {0x91b444f9, 0x0000002e, 0x000007f8, 0x84e9a983, 0x5676756f, + 0x66120546}, + {0x1b5d2ddb, 0x0000002e, 0x0000012c, 0xba638c4c, 0x3f42047b, + 0xf256a5cc}, + {0xd824d1bb, 0x0000003a, 0x000007b5, 0x6288653b, 0x3a3ebea0, + 0x4af1dd69}, + {0x0470180c, 0x00000034, 0x000001f0, 0x9d5b80d6, 0x3de08195, + 0x56f0a04a}, + {0xffaa3a3f, 0x00000036, 0x00000299, 0xf3a82ab8, 0x53e0c13d, + 0x74f6b6b2}, + {0x6406cfeb, 0x00000023, 0x00000600, 0xa920b8e8, 0xe4e2acf4, + 0x085951fd}, + {0xb24aaa38, 0x0000003e, 0x000004a1, 0x657cc328, 0x5077b2c3, + 0xc65387eb}, + {0x58b2ab7c, 0x00000039, 0x000002b4, 0x3a17ee7e, 0x9dcb3643, + 0x1ca9257b}, + {0x3db85970, 0x00000006, 0x000002b6, 0x95268b59, 0xb9812c10, + 0xfd196d76}, + {0x857830c5, 0x00000003, 0x00000590, 0x4ef439d5, 0xf042161d, + 0x5ef88339}, + {0xe1fcd978, 0x0000003e, 0x000007d8, 0xae8d8699, 0xce0a1ef5, + 0x2c3714d9}, + {0xb982a768, 0x00000016, 0x000006e0, 0x62fad3df, 0x5f8a067b, + 0x58576548}, + {0x1d581ce8, 0x0000001e, 0x0000058b, 0xf0f5da53, 0x26e39eee, + 0xfd7c57de}, + {0x2456719b, 0x00000025, 0x00000503, 0x4296ac64, 0xd50e4c14, + 0xd5fedd59}, + {0xfae6d8f2, 0x00000000, 0x0000055d, 0x057fdf2e, 0x2a31391a, + 0x1cc3b17b}, + {0xcba828e3, 0x00000039, 0x000002ce, 0xe3f22351, 0x8f00877b, + 0x270eed73}, + {0x13d25952, 0x0000000a, 0x0000072d, 0x76d4b4cc, 0x5eb67ec3, + 0x91ecbb11}, + {0x0342be3f, 0x00000015, 0x00000599, 0xec75d9f1, 0x9d4d2826, + 0x05ed8d0c}, + {0xeaa344e0, 0x00000014, 0x000004d8, 0x72a4c981, 0x2064ea06, + 0x0b09ad5b}, + {0xbbb52021, 0x0000003b, 0x00000272, 0x04af99fc, 0xaf042d35, + 0xf8d511fb}, + {0xb66384dc, 0x0000001d, 0x000007fc, 0xd7629116, 0x782bd801, + 0x5ad832cc}, + {0x616c01b6, 0x00000022, 0x000002c8, 0x5b1dab30, 0x783ce7d2, + 0x1214d196}, + {0xce2bdaad, 0x00000016, 0x0000062a, 0x932535c8, 0x3f02926d, + 0x5747218a}, + {0x00fe84d7, 0x00000005, 0x00000205, 0x850e50aa, 0x753d649c, + 0xde8f14de}, + {0xbebdcb4c, 0x00000006, 0x0000055d, 0xbeaa37a2, 0x2d8c9eba, + 0x3563b7b9}, + {0xd8b1a02a, 0x00000010, 0x00000387, 0x5017d2fc, 0x503541a5, + 0x071475d0}, + {0x3b96cad2, 0x00000036, 0x00000347, 0x1d2372ae, 0x926cd90b, + 0x54c79d60}, + {0xc94c1ed7, 0x00000005, 0x0000038b, 0x9e9fdb22, 0x144a9178, + 0x4c53eee6}, + {0x1aad454e, 0x00000025, 0x000002b2, 0xc3f6315c, 0x5c7a35b3, + 0x10137a3c}, + {0xa4fec9a6, 0x00000000, 0x000006d6, 0x90be5080, 0xa4107605, + 0xaa9d6c73}, + {0x1bbe71e2, 0x0000001f, 0x000002fd, 0x4e504c3b, 0x284ccaf1, + 0xb63d23e7}, + {0x4201c7e4, 0x00000002, 0x000002b7, 0x7822e3f9, 0x0cc912a9, + 0x7f53e9cf}, + {0x23fddc96, 0x00000003, 0x00000627, 0x8a385125, 0x07767e78, + 0x13c1cd83}, + {0xd82ba25c, 0x00000016, 0x0000063e, 0x98e4148a, 0x283330c9, + 0x49ff5867}, + {0x786f2032, 0x0000002d, 0x0000060f, 0xf201600a, 0xf561bfcd, + 0x8467f211}, + {0xfebe4e1f, 0x0000002a, 0x000004f2, 0x95e51961, 0xfd80dcab, + 0x3f9683b2}, + {0x1a6e0a39, 0x00000008, 0x00000672, 0x8af6c2a5, 0x78dd84cb, + 0x76a3f874}, + {0x56000ab8, 0x0000000e, 0x000000e5, 0x36bacb8f, 0x22ee1f77, + 0x863b702f}, + {0x4717fe0c, 0x00000000, 0x000006ec, 0x8439f342, 0x5c8e03da, + 0xdc6c58ff}, + {0xd5d5d68e, 0x0000003c, 0x000003a3, 0x46fff083, 0x177d1b39, + 0x0622cc95}, + {0xc25dd6c6, 0x00000024, 0x000006c0, 0x5ceb8eb4, 0x892b0d16, + 0xe85605cd}, + {0xe9b11300, 0x00000023, 0x00000683, 0x07a5d59a, 0x6c6a3208, + 0x31da5f06}, + {0x95cd285e, 0x00000001, 0x00000047, 0x7b3a4368, 0x0202c07e, + 0xa1f2e784}, + {0xd9245a25, 0x0000001e, 0x000003a6, 0xd33c1841, 0x1936c0d5, + 0xb07cc616}, + {0x103279db, 0x00000006, 0x0000039b, 0xca09b8a0, 0x77d62892, + 0xbf943b6c}, + {0x1cba3172, 0x00000027, 0x000001c8, 0xcb377194, 0xebe682db, + 0x2c01af1c}, + {0x8f613739, 0x0000000c, 0x000001df, 0xb4b0bc87, 0x7710bd43, + 0x0fe5f56d}, + {0x1c6aa90d, 0x0000001b, 0x0000053c, 0x70559245, 0xda7894ac, + 0xf8943b2d}, + {0xaabe5b93, 0x0000003d, 0x00000715, 0xcdbf42fa, 0x0c3b99e7, + 0xe4d89272}, + {0xf15dd038, 0x00000006, 0x000006db, 0x6e104aea, 0x8d5967f2, + 0x7c2f6bbb}, + {0x584dd49c, 0x00000020, 0x000007bc, 0x36b6cfd6, 0xad4e23b2, + 0xabbf388b}, + {0x5d8c9506, 0x00000020, 0x00000470, 0x4c62378e, 0x31d92640, + 0x1dca1f4e}, + {0xb80d17b0, 0x00000032, 0x00000346, 0x22a5bb88, 0x9a7ec89f, + 0x5c170e23}, + {0xdaf0592e, 0x00000023, 0x000007b0, 0x3cab3f99, 0x9b1fdd99, + 0xc0e9d672}, + {0x4793cc85, 0x0000000d, 0x00000706, 0xe82e04f6, 0xed3db6b7, + 0xc18bdc86}, + {0x82ebf64e, 0x00000009, 0x000007c3, 0x69d590a9, 0x9efa8499, + 0xa874fcdd}, + {0xb18a0319, 0x00000026, 0x000007db, 0x1cf98dcc, 0x8fa9ad6a, + 0x9dc0bb48}, +}; + +static int crc32c_test(void) +{ + int i; + int errors = 0; + int bytes = 0; + struct timeval start, stop; + uint64_t usec; + + /* keep static to prevent cache warming code from + * getting eliminated by the compiler */ + static u32 crc; + + /* pre-warm the cache */ + for (i = 0; i < 100; i++) { + bytes += 2*test[i].length; + + crc ^= crc32c_le(test[i].crc, test_buf + + test[i].start, test[i].length); + } + + gettimeofday(&start, NULL); + for (i = 0; i < 100; i++) { + if (test[i].crc32c_le != crc32c_le(test[i].crc, test_buf + + test[i].start, test[i].length)) + errors++; + } + gettimeofday(&stop, NULL); + + usec = stop.tv_usec - start.tv_usec + + 1000000 * (stop.tv_sec - start.tv_sec); + + if (errors) + printf("crc32c: %d self tests failed\n", errors); + else { + printf("crc32c: tests passed, %d bytes in %" PRIu64 " usec\n", + bytes, usec); + } + + return errors; +} + +static int crc32_test(void) +{ + int i; + int errors = 0; + int bytes = 0; + struct timeval start, stop; + uint64_t usec; + + /* keep static to prevent cache warming code from + * getting eliminated by the compiler */ + static u32 crc; + + /* pre-warm the cache */ + for (i = 0; i < 100; i++) { + bytes += 2*test[i].length; + + crc ^= crc32_le(test[i].crc, test_buf + + test[i].start, test[i].length); + +#if 0 /* not used */ + crc ^= crc32_be(test[i].crc, test_buf + + test[i].start, test[i].length); +#endif + } + + gettimeofday(&start, NULL); + for (i = 0; i < 100; i++) { + if (test[i].crc_le != crc32_le(test[i].crc, test_buf + + test[i].start, test[i].length)) + errors++; + +#if 0 /* not used */ + if (test[i].crc_be != crc32_be(test[i].crc, test_buf + + test[i].start, test[i].length)) + errors++; +#endif + } + gettimeofday(&stop, NULL); + + usec = stop.tv_usec - start.tv_usec + + 1000000000 * (stop.tv_sec - start.tv_sec); + + if (errors) + printf("crc32: %d self tests failed\n", errors); + else { + printf("crc32: tests passed, %d bytes in %" PRIu64 " usec\n", + bytes, usec); + } + + return errors; +} +/* + * make sure we always return 0 for a successful test run, and non-zero for a + * failed run. The build infrastructure is looking for this information to + * determine whether to allow the build to proceed. + */ +int main(int argc, char **argv) +{ + int errors; + + printf("CRC_LE_BITS = %d\n", CRC_LE_BITS); + + errors = crc32_test(); + errors += crc32c_test(); + + return errors != 0; +} +#endif /* CRC32_SELFTEST */ diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/crc32defs.h xfsprogs-3.2.1ubuntu1/libxfs/crc32defs.h --- xfsprogs-3.1.9ubuntu2/libxfs/crc32defs.h 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/crc32defs.h 2013-06-06 22:52:59.000000000 +0000 @@ -0,0 +1,72 @@ +/* + * There are multiple 16-bit CRC polynomials in common use, but this is + * *the* standard CRC-32 polynomial, first popularized by Ethernet. + * x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0 + */ +#define CRCPOLY_LE 0xedb88320 +#define CRCPOLY_BE 0x04c11db7 + +/* + * This is the CRC32c polynomial, as outlined by Castagnoli. + * x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+ + * x^8+x^6+x^0 + */ +#define CRC32C_POLY_LE 0x82F63B78 + +/* Try to choose an implementation variant via Kconfig */ +#ifdef CONFIG_CRC32_SLICEBY8 +# define CRC_LE_BITS 64 +# define CRC_BE_BITS 64 +#endif +#ifdef CONFIG_CRC32_SLICEBY4 +# define CRC_LE_BITS 32 +# define CRC_BE_BITS 32 +#endif +#ifdef CONFIG_CRC32_SARWATE +# define CRC_LE_BITS 8 +# define CRC_BE_BITS 8 +#endif +#ifdef CONFIG_CRC32_BIT +# define CRC_LE_BITS 1 +# define CRC_BE_BITS 1 +#endif + +/* + * How many bits at a time to use. Valid values are 1, 2, 4, 8, 32 and 64. + * For less performance-sensitive, use 4 or 8 to save table size. + * For larger systems choose same as CPU architecture as default. + * This works well on X86_64, SPARC64 systems. This may require some + * elaboration after experiments with other architectures. + */ +#ifndef CRC_LE_BITS +# ifdef CONFIG_64BIT +# define CRC_LE_BITS 64 +# else +# define CRC_LE_BITS 32 +# endif +#endif +#ifndef CRC_BE_BITS +# ifdef CONFIG_64BIT +# define CRC_BE_BITS 64 +# else +# define CRC_BE_BITS 32 +# endif +#endif + +/* + * Little-endian CRC computation. Used with serial bit streams sent + * lsbit-first. Be sure to use cpu_to_le32() to append the computed CRC. + */ +#if CRC_LE_BITS > 64 || CRC_LE_BITS < 1 || CRC_LE_BITS == 16 || \ + CRC_LE_BITS & CRC_LE_BITS-1 +# error "CRC_LE_BITS must be one of {1, 2, 4, 8, 32, 64}" +#endif + +/* + * Big-endian CRC computation. Used with serial bit streams sent + * msbit-first. Be sure to use cpu_to_be32() to append the computed CRC. + */ +#if CRC_BE_BITS > 64 || CRC_BE_BITS < 1 || CRC_BE_BITS == 16 || \ + CRC_BE_BITS & CRC_BE_BITS-1 +# error "CRC_BE_BITS must be one of {1, 2, 4, 8, 32, 64}" +#endif diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/gen_crc32table.c xfsprogs-3.2.1ubuntu1/libxfs/gen_crc32table.c --- xfsprogs-3.1.9ubuntu2/libxfs/gen_crc32table.c 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/gen_crc32table.c 2013-06-06 22:52:59.000000000 +0000 @@ -0,0 +1,144 @@ +#include +#include "crc32defs.h" +#include + +#define ENTRIES_PER_LINE 4 + +#if CRC_LE_BITS > 8 +# define LE_TABLE_ROWS (CRC_LE_BITS/8) +# define LE_TABLE_SIZE 256 +#else +# define LE_TABLE_ROWS 1 +# define LE_TABLE_SIZE (1 << CRC_LE_BITS) +#endif + +#if CRC_BE_BITS > 8 +# define BE_TABLE_ROWS (CRC_BE_BITS/8) +# define BE_TABLE_SIZE 256 +#else +# define BE_TABLE_ROWS 1 +# define BE_TABLE_SIZE (1 << CRC_BE_BITS) +#endif + +static uint32_t crc32table_le[LE_TABLE_ROWS][256]; +static uint32_t crc32ctable_le[LE_TABLE_ROWS][256]; + +/* + * big endian ordered CRC not used by XFS. +static uint32_t crc32table_be[BE_TABLE_ROWS][256]; + */ + +/** + * crc32init_le() - allocate and initialize LE table data + * + * crc is the crc of the byte i; other entries are filled in based on the + * fact that crctable[i^j] = crctable[i] ^ crctable[j]. + * + */ +static void crc32init_le_generic(const uint32_t polynomial, + uint32_t (*tab)[256]) +{ + unsigned i, j; + uint32_t crc = 1; + + tab[0][0] = 0; + + for (i = LE_TABLE_SIZE >> 1; i; i >>= 1) { + crc = (crc >> 1) ^ ((crc & 1) ? polynomial : 0); + for (j = 0; j < LE_TABLE_SIZE; j += 2 * i) + tab[0][i + j] = crc ^ tab[0][j]; + } + for (i = 0; i < LE_TABLE_SIZE; i++) { + crc = tab[0][i]; + for (j = 1; j < LE_TABLE_ROWS; j++) { + crc = tab[0][crc & 0xff] ^ (crc >> 8); + tab[j][i] = crc; + } + } +} + +static void crc32init_le(void) +{ + crc32init_le_generic(CRCPOLY_LE, crc32table_le); +} + +static void crc32cinit_le(void) +{ + crc32init_le_generic(CRC32C_POLY_LE, crc32ctable_le); +} + +/** + * crc32init_be() - allocate and initialize BE table data + */ +#if 0 /* not used */ +static void crc32init_be(void) +{ + unsigned i, j; + uint32_t crc = 0x80000000; + + crc32table_be[0][0] = 0; + + for (i = 1; i < BE_TABLE_SIZE; i <<= 1) { + crc = (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE : 0); + for (j = 0; j < i; j++) + crc32table_be[0][i + j] = crc ^ crc32table_be[0][j]; + } + for (i = 0; i < BE_TABLE_SIZE; i++) { + crc = crc32table_be[0][i]; + for (j = 1; j < BE_TABLE_ROWS; j++) { + crc = crc32table_be[0][(crc >> 24) & 0xff] ^ (crc << 8); + crc32table_be[j][i] = crc; + } + } +} +#endif + +static void output_table(uint32_t (*table)[256], int rows, int len, char *trans) +{ + int i, j; + + for (j = 0 ; j < rows; j++) { + printf("{"); + for (i = 0; i < len - 1; i++) { + if (i % ENTRIES_PER_LINE == 0) + printf("\n"); + printf("%s(0x%8.8xL), ", trans, table[j][i]); + } + printf("%s(0x%8.8xL)},\n", trans, table[j][len - 1]); + } +} + +int main(int argc, char** argv) +{ + printf("/* this file is generated - do not edit */\n\n"); + + if (CRC_LE_BITS > 1) { + crc32init_le(); + printf("static u32 crc32table_le[%d][%d] = {", + LE_TABLE_ROWS, LE_TABLE_SIZE); + output_table(crc32table_le, LE_TABLE_ROWS, + LE_TABLE_SIZE, "tole"); + printf("};\n"); + } + +#if 0 /* not used by xfsprogs */ + if (CRC_BE_BITS > 1) { + crc32init_be(); + printf("static u32 crc32table_be[%d][%d] = {", + BE_TABLE_ROWS, BE_TABLE_SIZE); + output_table(crc32table_be, LE_TABLE_ROWS, + BE_TABLE_SIZE, "tobe"); + printf("};\n"); + } +#endif + if (CRC_LE_BITS > 1) { + crc32cinit_le(); + printf("static u32 crc32ctable_le[%d][%d] = {", + LE_TABLE_ROWS, LE_TABLE_SIZE); + output_table(crc32ctable_le, LE_TABLE_ROWS, + LE_TABLE_SIZE, "tole"); + printf("};\n"); + } + + return 0; +} diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/init.c xfsprogs-3.2.1ubuntu1/libxfs/init.c --- xfsprogs-3.1.9ubuntu2/libxfs/init.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/init.c 2014-06-19 22:42:17.000000000 +0000 @@ -22,9 +22,6 @@ char *progname = "libxfs"; /* default, changed by each tool */ -struct cache *libxfs_icache; /* global inode cache */ -int libxfs_ihash_size; /* #buckets in icache */ - struct cache *libxfs_bcache; /* global buffer cache */ int libxfs_bhash_size; /* #buckets in bcache */ @@ -32,6 +29,8 @@ static void manage_zones(int); /* setup global zones */ +kmem_zone_t *xfs_inode_zone; + /* * dev_map - map open devices to fd. */ @@ -333,12 +332,10 @@ } if (needcd) chdir(curdir); - if (!libxfs_ihash_size) - libxfs_ihash_size = LIBXFS_IHASHSIZE(sbp); - libxfs_icache = cache_init(libxfs_ihash_size, &libxfs_icache_operations); if (!libxfs_bhash_size) libxfs_bhash_size = LIBXFS_BHASHSIZE(sbp); - libxfs_bcache = cache_init(libxfs_bhash_size, &libxfs_bcache_operations); + libxfs_bcache = cache_init(a->bcache_flags, libxfs_bhash_size, + &libxfs_bcache_operations); use_xfs_buf_lock = a->usebuflock; manage_zones(0); rval = 1; @@ -369,9 +366,7 @@ { extern kmem_zone_t *xfs_buf_zone; extern kmem_zone_t *xfs_ili_zone; - extern kmem_zone_t *xfs_inode_zone; extern kmem_zone_t *xfs_ifork_zone; - extern kmem_zone_t *xfs_dabuf_zone; extern kmem_zone_t *xfs_buf_item_zone; extern kmem_zone_t *xfs_da_state_zone; extern kmem_zone_t *xfs_btree_cur_zone; @@ -383,7 +378,6 @@ kmem_free(xfs_buf_zone); kmem_free(xfs_inode_zone); kmem_free(xfs_ifork_zone); - kmem_free(xfs_dabuf_zone); kmem_free(xfs_buf_item_zone); kmem_free(xfs_da_state_zone); kmem_free(xfs_btree_cur_zone); @@ -395,7 +389,6 @@ xfs_buf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buffer"); xfs_inode_zone = kmem_zone_init(sizeof(xfs_inode_t), "xfs_inode"); xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork"); - xfs_dabuf_zone = kmem_zone_init(sizeof(xfs_dabuf_t), "xfs_dabuf"); xfs_ili_zone = kmem_zone_init( sizeof(xfs_inode_log_item_t), "xfs_inode_log_item"); xfs_buf_item_zone = kmem_zone_init( @@ -412,40 +405,6 @@ } /* - * Get the bitmap and summary inodes into the mount structure - * at mount time. - */ -static int -rtmount_inodes(xfs_mount_t *mp) -{ - int error; - xfs_sb_t *sbp; - - sbp = &mp->m_sb; - if (sbp->sb_rbmino == NULLFSINO) - return 0; - error = libxfs_iget(mp, NULL, sbp->sb_rbmino, 0, &mp->m_rbmip, 0); - if (error) { - fprintf(stderr, - _("%s: cannot read realtime bitmap inode (%d)\n"), - progname, error); - return error; - } - ASSERT(mp->m_rbmip != NULL); - ASSERT(sbp->sb_rsumino != NULLFSINO); - error = libxfs_iget(mp, NULL, sbp->sb_rsumino, 0, &mp->m_rsumip, 0); - if (error) { - libxfs_iput(mp->m_rbmip, 0); - fprintf(stderr, - _("%s: cannot read realtime summary inode (%d)\n"), - progname, error); - return error; - } - ASSERT(mp->m_rsumip != NULL); - return 0; -} - -/* * Initialize realtime fields in the mount structure. */ static int @@ -460,7 +419,7 @@ sbp = &mp->m_sb; if (sbp->sb_rblocks == 0) return 0; - if (mp->m_rtdev == 0 && !(flags & LIBXFS_MOUNT_DEBUGGER)) { + if (mp->m_rtdev_targp->dev == 0 && !(flags & LIBXFS_MOUNT_DEBUGGER)) { fprintf(stderr, _("%s: filesystem has a realtime subvolume\n"), progname); return -1; @@ -489,7 +448,7 @@ return -1; } bp = libxfs_readbuf(mp->m_rtdev, - d - XFS_FSB_TO_BB(mp, 1), XFS_FSB_TO_BB(mp, 1), 0); + d - XFS_FSB_TO_BB(mp, 1), XFS_FSB_TO_BB(mp, 1), 0, NULL); if (bp == NULL) { fprintf(stderr, _("%s: realtime size check failed\n"), progname); @@ -499,22 +458,6 @@ return 0; } - -/* - * Core dir v1 mount code for allowing reading of these dirs. - */ -static void -libxfs_dirv1_mount( - xfs_mount_t *mp) -{ - mp->m_dir_node_ents = mp->m_attr_node_ents = - (XFS_LBSIZE(mp) - (uint)sizeof(xfs_da_node_hdr_t)) / - (uint)sizeof(xfs_da_node_entry_t); - mp->m_dir_magicpct = (XFS_LBSIZE(mp) * 37) / 100; - mp->m_dirblksize = mp->m_sb.sb_blocksize; - mp->m_dirblkfsbs = 1; -} - static int libxfs_initialize_perag( xfs_mount_t *mp, @@ -618,6 +561,72 @@ return error; } +static struct xfs_buftarg * +libxfs_buftarg_alloc( + struct xfs_mount *mp, + dev_t dev) +{ + struct xfs_buftarg *btp; + + btp = malloc(sizeof(*btp)); + if (!btp) { + fprintf(stderr, _("%s: buftarg init failed\n"), + progname); + exit(1); + } + btp->bt_mount = mp; + btp->dev = dev; + return btp; +} + +void +libxfs_buftarg_init( + struct xfs_mount *mp, + dev_t dev, + dev_t logdev, + dev_t rtdev) +{ + if (mp->m_ddev_targp) { + /* should already have all buftargs initialised */ + if (mp->m_ddev_targp->dev != dev || + mp->m_ddev_targp->bt_mount != mp) { + fprintf(stderr, + _("%s: bad buftarg reinit, ddev\n"), + progname); + exit(1); + } + if (!logdev || logdev == dev) { + if (mp->m_logdev_targp != mp->m_ddev_targp) { + fprintf(stderr, + _("%s: bad buftarg reinit, ldev mismatch\n"), + progname); + exit(1); + } + } else if (mp->m_logdev_targp->dev != logdev || + mp->m_logdev_targp->bt_mount != mp) { + fprintf(stderr, + _("%s: bad buftarg reinit, logdev\n"), + progname); + exit(1); + } + if (rtdev && (mp->m_rtdev_targp->dev != rtdev || + mp->m_rtdev_targp->bt_mount != mp)) { + fprintf(stderr, + _("%s: bad buftarg reinit, rtdev\n"), + progname); + exit(1); + } + return; + } + + mp->m_ddev_targp = libxfs_buftarg_alloc(mp, dev); + if (!logdev || logdev == dev) + mp->m_logdev_targp = mp->m_ddev_targp; + else + mp->m_logdev_targp = libxfs_buftarg_alloc(mp, logdev); + mp->m_rtdev_targp = libxfs_buftarg_alloc(mp, rtdev); +} + /* * Mount structure initialization, provides a filled-in xfs_mount_t * such that the numerous XFS_* macros can be used. If dev is zero, @@ -637,15 +646,14 @@ xfs_sb_t *sbp; int error; - mp->m_dev = dev; - mp->m_rtdev = rtdev; - mp->m_logdev = logdev; + libxfs_buftarg_init(mp, dev, logdev, rtdev); + mp->m_flags = (LIBXFS_MOUNT_32BITINODES|LIBXFS_MOUNT_32BITINOOPT); mp->m_sb = *sb; INIT_RADIX_TREE(&mp->m_perag_tree, GFP_KERNEL); sbp = &(mp->m_sb); - xfs_mount_common(mp, sb); + xfs_sb_mount_common(mp, sb); xfs_alloc_compute_maxlevels(mp); xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK); @@ -702,13 +710,14 @@ } /* Initialize the appropriate directory manager */ - if (xfs_sb_version_hasdirv2(sbp)) - xfs_dir_mount(mp); - else { - fprintf(stderr, _("%s: WARNING - filesystem uses v1 dirs," - "limited functionality provided.\n"), progname); - libxfs_dirv1_mount(mp); + if (!xfs_sb_version_hasdirv2(sbp)) { + + fprintf(stderr, _( + "%s: V1 directories unsupported. Please try an older xfsprogs.\n"), + progname); + exit(1); } + xfs_dir_mount(mp); /* Initialize cached values for the attribute manager */ mp->m_attr_magicpct = (mp->m_sb.sb_blocksize * 37) / 100; @@ -723,7 +732,7 @@ bp = libxfs_readbuf(mp->m_dev, d - XFS_FSS_TO_BB(mp, 1), XFS_FSS_TO_BB(mp, 1), - !(flags & LIBXFS_MOUNT_DEBUGGER)); + !(flags & LIBXFS_MOUNT_DEBUGGER), NULL); if (!bp) { fprintf(stderr, _("%s: data size check failed\n"), progname); if (!(flags & LIBXFS_MOUNT_DEBUGGER)) @@ -731,13 +740,14 @@ } else libxfs_putbuf(bp); - if (mp->m_logdev && mp->m_logdev != mp->m_dev) { + if (mp->m_logdev_targp->dev && + mp->m_logdev_targp->dev != mp->m_ddev_targp->dev) { d = (xfs_daddr_t) XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); if ( (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) || - (!(bp = libxfs_readbuf(mp->m_logdev, + (!(bp = libxfs_readbuf(mp->m_logdev_targp, d - XFS_FSB_TO_BB(mp, 1), XFS_FSB_TO_BB(mp, 1), - !(flags & LIBXFS_MOUNT_DEBUGGER)))) ) { + !(flags & LIBXFS_MOUNT_DEBUGGER), NULL))) ) { fprintf(stderr, _("%s: log size checks failed\n"), progname); if (!(flags & LIBXFS_MOUNT_DEBUGGER)) @@ -761,39 +771,6 @@ exit(1); } - /* - * mkfs calls mount before the root inode is allocated. - */ - if ((flags & LIBXFS_MOUNT_ROOTINOS) && sbp->sb_rootino != NULLFSINO) { - error = libxfs_iget(mp, NULL, sbp->sb_rootino, 0, - &mp->m_rootip, 0); - if (error) { - fprintf(stderr, _("%s: cannot read root inode (%d)\n"), - progname, error); - if (!(flags & LIBXFS_MOUNT_DEBUGGER)) - return NULL; - } - ASSERT(mp->m_rootip != NULL); - } - if ((flags & LIBXFS_MOUNT_ROOTINOS) && rtmount_inodes(mp)) { - if (mp->m_rootip) - libxfs_iput(mp->m_rootip, 0); - return NULL; - } - - /* - * mkfs calls mount before the AGF/AGI structures are written. - */ - if ((flags & LIBXFS_MOUNT_ROOTINOS) && sbp->sb_rootino != NULLFSINO && - xfs_sb_version_haslazysbcount(&mp->m_sb)) { - error = xfs_initialize_perag_data(mp, sbp->sb_agcount); - if (error) { - fprintf(stderr, _("%s: cannot init perag data (%d)\n"), - progname, error); - return NULL; - } - } - return mp; } @@ -801,9 +778,9 @@ libxfs_rtmount_destroy(xfs_mount_t *mp) { if (mp->m_rsumip) - libxfs_iput(mp->m_rsumip, 0); + IRELE(mp->m_rsumip); if (mp->m_rbmip) - libxfs_iput(mp->m_rbmip, 0); + IRELE(mp->m_rbmip); mp->m_rsumip = mp->m_rbmip = NULL; } @@ -817,7 +794,6 @@ int agno; libxfs_rtmount_destroy(mp); - libxfs_icache_purge(); libxfs_bcache_purge(); for (agno = 0; agno < mp->m_maxagi; agno++) { @@ -833,7 +809,6 @@ libxfs_destroy(void) { manage_zones(1); - cache_destroy(libxfs_icache); cache_destroy(libxfs_bcache); } @@ -849,7 +824,6 @@ time_t t; char *c; - cache_report(fp, "libxfs_icache", libxfs_icache); cache_report(fp, "libxfs_bcache", libxfs_bcache); t = time(NULL); diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/init.h xfsprogs-3.2.1ubuntu1/libxfs/init.h --- xfsprogs-3.1.9ubuntu2/libxfs/init.h 2010-01-13 03:16:49.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/init.h 2014-05-02 00:09:16.000000000 +0000 @@ -31,7 +31,6 @@ extern char *platform_findblockpath (char *path); extern int platform_direct_blockdev (void); extern int platform_align_blockdev (void); -extern int platform_nproc(void); extern unsigned long platform_physmem(void); /* in kilobytes */ extern int platform_has_uuid; diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/linux.c xfsprogs-3.2.1ubuntu1/libxfs/linux.c --- xfsprogs-3.1.9ubuntu2/libxfs/linux.c 2010-01-13 03:16:49.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/linux.c 2014-06-19 22:42:17.000000000 +0000 @@ -141,10 +141,20 @@ exit(1); } if ((st.st_mode & S_IFMT) == S_IFREG) { + struct xfs_fsop_geom_v1 geom = { 0 }; + *sz = (long long)(st.st_size >> 9); - *bsz = BBSIZE; - if (BBSIZE > max_block_alignment) - max_block_alignment = BBSIZE; + if (ioctl(fd, XFS_IOC_FSGEOMETRY_V1, &geom) < 0) { + /* + * fall back to BBSIZE; mkfs might fail if there's a + * size mismatch between the image & the host fs... + */ + *bsz = BBSIZE; + } else + *bsz = geom.sectsize; + + if (*bsz > max_block_alignment) + max_block_alignment = *bsz; return; } diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/logitem.c xfsprogs-3.2.1ubuntu1/libxfs/logitem.c --- xfsprogs-3.1.9ubuntu2/libxfs/logitem.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/logitem.c 2013-10-10 21:07:17.000000000 +0000 @@ -32,21 +32,27 @@ xfs_buf_t * xfs_trans_buf_item_match( xfs_trans_t *tp, - xfs_buftarg_t *target, - xfs_daddr_t blkno, - int len) + struct xfs_buftarg *btp, + struct xfs_buf_map *map, + int nmaps) { struct xfs_log_item_desc *lidp; struct xfs_buf_log_item *blip; + int len = 0; + int i; + + for (i = 0; i < nmaps; i++) + len += map[i].bm_len; - len = BBTOB(len); list_for_each_entry(lidp, &tp->t_items, lid_trans) { blip = (struct xfs_buf_log_item *)lidp->lid_item; if (blip->bli_item.li_type == XFS_LI_BUF && - XFS_BUF_TARGET(blip->bli_buf) == target->dev && - XFS_BUF_ADDR(blip->bli_buf) == blkno && - XFS_BUF_COUNT(blip->bli_buf) == len) + blip->bli_buf->b_target->dev == btp->dev && + XFS_BUF_ADDR(blip->bli_buf) == map[0].bm_bn && + blip->bli_buf->b_bcount == BBTOB(len)) { + ASSERT(blip->bli_buf->b_map_count == nmaps); return blip->bli_buf; + } } return NULL; diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/Makefile xfsprogs-3.2.1ubuntu1/libxfs/Makefile --- xfsprogs-3.1.9ubuntu2/libxfs/Makefile 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/Makefile 2014-05-02 00:09:15.000000000 +0000 @@ -10,17 +10,40 @@ LT_REVISION = 0 LT_AGE = 0 -HFILES = xfs.h init.h -CFILES = cache.c init.c kmem.c logitem.c radix-tree.c rdwr.c trans.c util.c \ - xfs_alloc.c xfs_ialloc.c xfs_inode.c xfs_btree.c xfs_alloc_btree.c \ - xfs_ialloc_btree.c xfs_bmap_btree.c xfs_da_btree.c \ - xfs_dir2.c xfs_dir2_leaf.c xfs_attr_leaf.c xfs_dir2_block.c \ - xfs_dir2_node.c xfs_dir2_data.c xfs_dir2_sf.c xfs_bmap.c \ - xfs_mount.c xfs_rtalloc.c xfs_trans.c xfs_attr.c +HFILES = xfs.h init.h xfs_dir2_priv.h crc32defs.h crc32table.h +CFILES = cache.c \ + crc32.c \ + init.c kmem.c logitem.c radix-tree.c rdwr.c trans.c util.c \ + xfs_alloc.c \ + xfs_alloc_btree.c \ + xfs_attr.c \ + xfs_attr_leaf.c \ + xfs_attr_remote.c \ + xfs_bmap.c \ + xfs_bmap_btree.c \ + xfs_btree.c \ + xfs_da_btree.c \ + xfs_dir2.c \ + xfs_dir2_block.c \ + xfs_dir2_data.c \ + xfs_dir2_leaf.c \ + xfs_dir2_node.c \ + xfs_dir2_sf.c \ + xfs_dquot_buf.c \ + xfs_ialloc.c \ + xfs_inode_buf.c \ + xfs_inode_fork.c \ + xfs_ialloc_btree.c \ + xfs_log_rlimit.c \ + xfs_rtbitmap.c \ + xfs_sb.c \ + xfs_symlink_remote.c \ + xfs_trans_resv.c CFILES += $(PKG_PLATFORM).c PCFILES = darwin.c freebsd.c irix.c linux.c LSRCFILES = $(shell echo $(PCFILES) | sed -e "s/$(PKG_PLATFORM).c//g") +LSRCFILES += gen_crc32table.c # # Tracing flags: @@ -38,7 +61,25 @@ # don't try linking xfs_repair with a debug libxfs. DEBUG = -DNDEBUG -default: ltdepend $(LTLIBRARY) +LDIRT = gen_crc32table crc32table.h crc32selftest + +default: crc32selftest ltdepend $(LTLIBRARY) + +crc32table.h: gen_crc32table.c + @echo " [CC] gen_crc32table" + $(Q) $(CC) $(CFLAGS) -o gen_crc32table $< + @echo " [GENERATE] $@" + $(Q) ./gen_crc32table > crc32table.h + +# The selftest binary will return an error if it fails. This is made a +# dependency of the build process so that we refuse to build the tools on broken +# systems/architectures. Hence we make sure that xfsprogs will never use a +# busted CRC calculation at build time and hence avoid putting bad CRCs down on +# disk. +crc32selftest: gen_crc32table.c crc32table.h crc32.c + @echo " [TEST] CRC32" + $(Q) $(CC) $(CFLAGS) -D CRC32_SELFTEST=1 crc32.c -o $@ + $(Q) ./$@ include $(BUILDRULES) diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/rdwr.c xfsprogs-3.2.1ubuntu1/libxfs/rdwr.c --- xfsprogs-3.1.9ubuntu2/libxfs/rdwr.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/rdwr.c 2014-07-21 09:13:53.000000000 +0000 @@ -17,17 +17,45 @@ */ #include -#include -#include #include "init.h" +/* + * Important design/architecture note: + * + * The userspace code that uses the buffer cache is much less constrained than + * the kernel code. The userspace code is pretty nasty in places, especially + * when it comes to buffer error handling. Very little of the userspace code + * outside libxfs clears bp->b_error - very little code even checks it - so the + * libxfs code is tripping on stale errors left by the userspace code. + * + * We can't clear errors or zero buffer contents in libxfs_getbuf-* like we do + * in the kernel, because those functions are used by the libxfs_readbuf_* + * functions and hence need to leave the buffers unchanged on cache hits. This + * is actually the only way to gather a write error from a libxfs_writebuf() + * call - you need to get the buffer again so you can check bp->b_error field - + * assuming that the buffer is still in the cache when you check, that is. + * + * This is very different to the kernel code which does not release buffers on a + * write so we can wait on IO and check errors. The kernel buffer cache also + * guarantees a buffer of a known initial state from xfs_buf_get() even on a + * cache hit. + * + * IOWs, userspace is behaving quite differently to the kernel and as a result + * it leaks errors from reads, invalidations and writes through + * libxfs_getbuf/libxfs_readbuf. + * + * The result of this is that until the userspace code outside libxfs is cleaned + * up, functions that release buffers from userspace control (i.e + * libxfs_writebuf/libxfs_putbuf) need to zero bp->b_error to prevent + * propagation of stale errors into future buffer operations. + */ + #define BDSTRAT_SIZE (256 * 1024) -#define min(x, y) ((x) < (y) ? (x) : (y)) #define IO_BCOMPARE_CHECK void -libxfs_device_zero(dev_t dev, xfs_daddr_t start, uint len) +libxfs_device_zero(struct xfs_buftarg *btp, xfs_daddr_t start, uint len) { xfs_off_t start_offset, end_offset, offset; ssize_t zsize, bytes; @@ -43,7 +71,7 @@ } memset(z, 0, zsize); - fd = libxfs_device_to_fd(dev); + fd = libxfs_device_to_fd(btp->dev); start_offset = LIBXFS_BBTOOFF64(start); if ((lseek64(fd, start_offset, SEEK_SET)) < 0) { @@ -102,7 +130,7 @@ int libxfs_log_clear( - dev_t device, + struct xfs_buftarg *btp, xfs_daddr_t start, uint length, uuid_t *fs_uuid, @@ -113,16 +141,16 @@ xfs_buf_t *bp; int len; - if (!device || !fs_uuid) + if (!btp->dev || !fs_uuid) return -EINVAL; /* first zero the log */ - libxfs_device_zero(device, start, length); + libxfs_device_zero(btp, start, length); /* then write a log record header */ len = ((version == 2) && sunit) ? BTOBB(sunit) : 2; len = MAX(len, 2); - bp = libxfs_getbufr(device, start, len); + bp = libxfs_getbufr(btp, start, len); libxfs_log_header(XFS_BUF_PTR(bp), fs_uuid, version, sunit, fmt, next, bp); bp->b_flags |= LIBXFS_B_DIRTY; @@ -159,7 +187,7 @@ head->h_len = cpu_to_be32(sunit - BBSIZE); else head->h_len = cpu_to_be32(20); - head->h_chksum = cpu_to_be32(0); + head->h_crc = cpu_to_be32(0); head->h_prev_block = cpu_to_be32(-1); head->h_num_logops = cpu_to_be32(1); head->h_cycle_data[0] = cpu_to_be32(0xb0c0d0d0); @@ -193,72 +221,93 @@ #ifdef XFS_BUF_TRACING #undef libxfs_readbuf +#undef libxfs_readbuf_map #undef libxfs_writebuf #undef libxfs_getbuf +#undef libxfs_getbuf_map #undef libxfs_getbuf_flags #undef libxfs_putbuf -xfs_buf_t *libxfs_readbuf(dev_t, xfs_daddr_t, int, int); +xfs_buf_t *libxfs_readbuf(struct xfs_buftarg *, xfs_daddr_t, int, int, + const struct xfs_buf_ops *); +xfs_buf_t *libxfs_readbuf_map(struct xfs_buftarg *, struct xfs_buf_map *, + int, int, const struct xfs_buf_ops *); int libxfs_writebuf(xfs_buf_t *, int); -xfs_buf_t *libxfs_getbuf(dev_t, xfs_daddr_t, int); +xfs_buf_t *libxfs_getbuf(struct xfs_buftarg *, xfs_daddr_t, int); +xfs_buf_t *libxfs_getbuf_map(struct xfs_buftarg *, struct xfs_buf_map *, + int, int); +xfs_buf_t *libxfs_getbuf_flags(struct xfs_buftarg *, xfs_daddr_t, int, + unsigned int); void libxfs_putbuf (xfs_buf_t *); +#define __add_trace(bp, func, file, line) \ +do { \ + if (bp) { \ + (bp)->b_func = (func); \ + (bp)->b_file = (file); \ + (bp)->b_line = (line); \ + } \ +} while (0) + xfs_buf_t * -libxfs_trace_readbuf(const char *func, const char *file, int line, dev_t dev, xfs_daddr_t blkno, int len, int flags) +libxfs_trace_readbuf(const char *func, const char *file, int line, + struct xfs_buftarg *btp, xfs_daddr_t blkno, int len, int flags, + const struct xfs_buf_ops *ops) { - xfs_buf_t *bp = libxfs_readbuf(dev, blkno, len, flags); - - if (bp){ - bp->b_func = func; - bp->b_file = file; - bp->b_line = line; - } + xfs_buf_t *bp = libxfs_readbuf(btp, blkno, len, flags, ops); + __add_trace(bp, func, file, line); + return bp; +} +xfs_buf_t * +libxfs_trace_readbuf_map(const char *func, const char *file, int line, + struct xfs_buftarg *btp, struct xfs_buf_map *map, int nmaps, int flags, + const struct xfs_buf_ops *ops) +{ + xfs_buf_t *bp = libxfs_readbuf_map(btp, map, nmaps, flags, ops); + __add_trace(bp, func, file, line); return bp; } int libxfs_trace_writebuf(const char *func, const char *file, int line, xfs_buf_t *bp, int flags) { - bp->b_func = func; - bp->b_file = file; - bp->b_line = line; - + __add_trace(bp, func, file, line); return libxfs_writebuf(bp, flags); } xfs_buf_t * -libxfs_trace_getbuf(const char *func, const char *file, int line, dev_t device, xfs_daddr_t blkno, int len) +libxfs_trace_getbuf(const char *func, const char *file, int line, + struct xfs_buftarg *btp, xfs_daddr_t blkno, int len) { - xfs_buf_t *bp = libxfs_getbuf(device, blkno, len); - - bp->b_func = func; - bp->b_file = file; - bp->b_line = line; + xfs_buf_t *bp = libxfs_getbuf(btp, blkno, len); + __add_trace(bp, func, file, line); + return bp; +} +xfs_buf_t * +libxfs_trace_getbuf_map(const char *func, const char *file, int line, + struct xfs_buftarg *btp, struct xfs_buf_map *map, int nmaps, + int flags) +{ + xfs_buf_t *bp = libxfs_getbuf_map(btp, map, nmaps, flags); + __add_trace(bp, func, file, line); return bp; } xfs_buf_t * libxfs_trace_getbuf_flags(const char *func, const char *file, int line, - dev_t device, xfs_daddr_t blkno, int len, unsigned long flags) + struct xfs_buftarg *btp, xfs_daddr_t blkno, int len, unsigned int flags) { - xfs_buf_t *bp = libxfs_getbuf(device, blkno, len, flags); - - bp->b_func = func; - bp->b_file = file; - bp->b_line = line; - + xfs_buf_t *bp = libxfs_getbuf_flags(btp, blkno, len, flags); + __add_trace(bp, func, file, line); return bp; } void libxfs_trace_putbuf(const char *func, const char *file, int line, xfs_buf_t *bp) { - bp->b_func = func; - bp->b_file = file; - bp->b_line = line; - + __add_trace(bp, func, file, line); libxfs_putbuf(bp); } @@ -269,8 +318,8 @@ xfs_buf_t * libxfs_getsb(xfs_mount_t *mp, int flags) { - return libxfs_readbuf(mp->m_dev, XFS_SB_DADDR, - XFS_FSS_TO_BB(mp, 1), flags); + return libxfs_readbuf(mp->m_ddev_targp, XFS_SB_DADDR, + XFS_FSS_TO_BB(mp, 1), flags, &xfs_sb_buf_ops); } kmem_zone_t *xfs_buf_zone; @@ -279,55 +328,79 @@ {{&xfs_buf_freelist.cm_list, &xfs_buf_freelist.cm_list}, 0, PTHREAD_MUTEX_INITIALIZER }; -typedef struct { - dev_t device; - xfs_daddr_t blkno; - unsigned int bblen; -} xfs_bufkey_t; +/* + * The bufkey is used to pass the new buffer information to the cache object + * allocation routine. Because discontiguous buffers need to pass different + * information, we need fields to pass that information. However, because the + * blkno and bblen is needed for the initial cache entry lookup (i.e. for + * bcompare) the fact that the map/nmaps is non-null to switch to discontiguous + * buffer initialisation instead of a contiguous buffer. + */ +struct xfs_bufkey { + struct xfs_buftarg *buftarg; + xfs_daddr_t blkno; + unsigned int bblen; + struct xfs_buf_map *map; + int nmaps; +}; +/* 2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */ +#define GOLDEN_RATIO_PRIME 0x9e37fffffffc0001UL +#define CACHE_LINE_SIZE 64 static unsigned int -libxfs_bhash(cache_key_t key, unsigned int hashsize) +libxfs_bhash(cache_key_t key, unsigned int hashsize, unsigned int hashshift) { - return (((unsigned int)((xfs_bufkey_t *)key)->blkno) >> 5) % hashsize; + uint64_t hashval = ((struct xfs_bufkey *)key)->blkno; + uint64_t tmp; + + tmp = hashval ^ (GOLDEN_RATIO_PRIME + hashval) / CACHE_LINE_SIZE; + tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> hashshift); + return tmp % hashsize; } static int libxfs_bcompare(struct cache_node *node, cache_key_t key) { - xfs_buf_t *bp = (xfs_buf_t *)node; - xfs_bufkey_t *bkey = (xfs_bufkey_t *)key; + struct xfs_buf *bp = (struct xfs_buf *)node; + struct xfs_bufkey *bkey = (struct xfs_bufkey *)key; + if (bp->b_target->dev == bkey->buftarg->dev && + bp->b_bn == bkey->blkno) { + if (bp->b_bcount == BBTOB(bkey->bblen)) + return CACHE_HIT; #ifdef IO_BCOMPARE_CHECK - if (bp->b_dev == bkey->device && - bp->b_blkno == bkey->blkno && - bp->b_bcount != BBTOB(bkey->bblen)) - fprintf(stderr, "%lx: Badness in key lookup (length)\n" - "bp=(bno %llu, len %u bytes) key=(bno %llu, len %u bytes)\n", - pthread_self(), - (unsigned long long)bp->b_blkno, (int)bp->b_bcount, - (unsigned long long)bkey->blkno, BBTOB(bkey->bblen)); + if (!(libxfs_bcache->c_flags & CACHE_MISCOMPARE_PURGE)) { + fprintf(stderr, + "%lx: Badness in key lookup (length)\n" + "bp=(bno 0x%llx, len %u bytes) key=(bno 0x%llx, len %u bytes)\n", + pthread_self(), + (unsigned long long)bp->b_bn, (int)bp->b_bcount, + (unsigned long long)bkey->blkno, + BBTOB(bkey->bblen)); + } #endif - - return (bp->b_dev == bkey->device && - bp->b_blkno == bkey->blkno && - bp->b_bcount == BBTOB(bkey->bblen)); + return CACHE_PURGE; + } + return CACHE_MISS; } void libxfs_bprint(xfs_buf_t *bp) { fprintf(stderr, "Buffer 0x%p blkno=%llu bytes=%u flags=0x%x count=%u\n", - bp, (unsigned long long)bp->b_blkno, (unsigned)bp->b_bcount, + bp, (unsigned long long)bp->b_bn, (unsigned)bp->b_bcount, bp->b_flags, bp->b_node.cn_count); } static void -libxfs_initbuf(xfs_buf_t *bp, dev_t device, xfs_daddr_t bno, unsigned int bytes) +__initbuf(xfs_buf_t *bp, struct xfs_buftarg *btp, xfs_daddr_t bno, + unsigned int bytes) { bp->b_flags = 0; - bp->b_blkno = bno; + bp->b_bn = bno; bp->b_bcount = bytes; - bp->b_dev = device; + bp->b_length = BTOBB(bytes); + bp->b_target = btp; bp->b_error = 0; if (!bp->b_addr) bp->b_addr = memalign(libxfs_device_alignment(), bytes); @@ -344,13 +417,49 @@ pthread_mutex_init(&bp->b_lock, NULL); bp->b_holder = 0; bp->b_recur = 0; + bp->b_ops = NULL; +} + +static void +libxfs_initbuf(xfs_buf_t *bp, struct xfs_buftarg *btp, xfs_daddr_t bno, + unsigned int bytes) +{ + __initbuf(bp, btp, bno, bytes); +} + +static void +libxfs_initbuf_map(xfs_buf_t *bp, struct xfs_buftarg *btp, + struct xfs_buf_map *map, int nmaps) +{ + unsigned int bytes = 0; + int i; + + bytes = sizeof(struct xfs_buf_map) * nmaps; + bp->b_map = malloc(bytes); + if (!bp->b_map) { + fprintf(stderr, + _("%s: %s can't malloc %u bytes: %s\n"), + progname, __FUNCTION__, bytes, + strerror(errno)); + exit(1); + } + bp->b_nmaps = nmaps; + + bytes = 0; + for ( i = 0; i < nmaps; i++) { + bp->b_map[i].bm_bn = map[i].bm_bn; + bp->b_map[i].bm_len = map[i].bm_len; + bytes += BBTOB(map[i].bm_len); + } + + __initbuf(bp, btp, map[0].bm_bn, bytes); + bp->b_flags |= LIBXFS_B_DISCONTIG; } xfs_buf_t * -libxfs_getbufr(dev_t device, xfs_daddr_t blkno, int bblen) +__libxfs_getbufr(int blen) { xfs_buf_t *bp; - int blen = BBTOB(bblen); /* * first look for a buffer that can be used as-is, @@ -372,15 +481,28 @@ list_del_init(&bp->b_node.cn_mru); free(bp->b_addr); bp->b_addr = NULL; + free(bp->b_map); + bp->b_map = NULL; } } else bp = kmem_zone_zalloc(xfs_buf_zone, 0); pthread_mutex_unlock(&xfs_buf_freelist.cm_mutex); + bp->b_ops = NULL; - if (bp != NULL) - libxfs_initbuf(bp, device, blkno, blen); + return bp; +} + +xfs_buf_t * +libxfs_getbufr(struct xfs_buftarg *btp, xfs_daddr_t blkno, int bblen) +{ + xfs_buf_t *bp; + int blen = BBTOB(bblen); + + bp =__libxfs_getbufr(blen); + if (bp) + libxfs_initbuf(bp, btp, blkno, blen); #ifdef IO_DEBUG - printf("%lx: %s: allocated %u bytes buffer, key=%llu(%llu), %p\n", + printf("%lx: %s: allocated %u bytes buffer, key=0x%llx(0x%llx), %p\n", pthread_self(), __FUNCTION__, blen, (long long)LIBXFS_BBTOOFF64(blkno), (long long)blkno, bp); #endif @@ -388,6 +510,39 @@ return bp; } +xfs_buf_t * +libxfs_getbufr_map(struct xfs_buftarg *btp, xfs_daddr_t blkno, int bblen, + struct xfs_buf_map *map, int nmaps) +{ + xfs_buf_t *bp; + int blen = BBTOB(bblen); + + if (!map || !nmaps) { + fprintf(stderr, + _("%s: %s invalid map %p or nmaps %d\n"), + progname, __FUNCTION__, map, nmaps); + exit(1); + } + + if (blkno != map[0].bm_bn) { + fprintf(stderr, + _("%s: %s map blkno 0x%llx doesn't match key 0x%llx\n"), + progname, __FUNCTION__, (long long)map[0].bm_bn, + (long long)blkno); + exit(1); + } + + bp =__libxfs_getbufr(blen); + if (bp) + libxfs_initbuf_map(bp, btp, map, nmaps); +#ifdef IO_DEBUG + printf("%lx: %s: allocated %u bytes buffer, key=0x%llx(0x%llx), %p\n", + pthread_self(), __FUNCTION__, blen, + (long long)LIBXFS_BBTOOFF64(blkno), (long long)blkno, bp); +#endif + + return bp; +} #ifdef XFS_BUF_TRACING struct list_head lock_buf_list = {&lock_buf_list, &lock_buf_list}; @@ -396,18 +551,12 @@ extern int use_xfs_buf_lock; -struct xfs_buf * -libxfs_getbuf_flags(dev_t device, xfs_daddr_t blkno, int len, unsigned int flags) +static struct xfs_buf * +__cache_lookup(struct xfs_bufkey *key, unsigned int flags) { - xfs_buf_t *bp; - xfs_bufkey_t key; - int miss; + struct xfs_buf *bp; - key.device = device; - key.blkno = blkno; - key.bblen = len; - - miss = cache_node_get(libxfs_bcache, &key, (struct cache_node **)&bp); + cache_node_get(libxfs_bcache, key, (struct cache_node **)&bp); if (!bp) return NULL; @@ -423,7 +572,7 @@ if (pthread_equal(bp->b_holder, pthread_self())) { fprintf(stderr, _("Warning: recursive buffer locking at block %" PRIu64 " detected\n"), - blkno); + key->blkno); bp->b_recur++; return bp; } else { @@ -444,9 +593,9 @@ pthread_mutex_unlock(&libxfs_bcache->c_mutex); #endif #ifdef IO_DEBUG - printf("%lx %s: %s buffer %p for bno = %llu\n", - pthread_self(), __FUNCTION__, miss ? "miss" : "hit", - bp, (long long)LIBXFS_BBTOOFF64(blkno)); + printf("%lx %s: hit buffer %p for bno = 0x%llx/0x%llx\n", + pthread_self(), __FUNCTION__, + bp, bp->b_bn, (long long)LIBXFS_BBTOOFF64(key->blkno)); #endif return bp; @@ -456,14 +605,55 @@ } struct xfs_buf * -libxfs_getbuf(dev_t device, xfs_daddr_t blkno, int len) +libxfs_getbuf_flags(struct xfs_buftarg *btp, xfs_daddr_t blkno, int len, + unsigned int flags) +{ + struct xfs_bufkey key = {0}; + + key.buftarg = btp; + key.blkno = blkno; + key.bblen = len; + + return __cache_lookup(&key, flags); +} + +struct xfs_buf * +libxfs_getbuf(struct xfs_buftarg *btp, xfs_daddr_t blkno, int len) +{ + return libxfs_getbuf_flags(btp, blkno, len, 0); +} + +struct xfs_buf * +libxfs_getbuf_map(struct xfs_buftarg *btp, struct xfs_buf_map *map, + int nmaps, int flags) { - return libxfs_getbuf_flags(device, blkno, len, 0); + struct xfs_bufkey key = {0}; + int i; + + if (nmaps == 1) + return libxfs_getbuf_flags(btp, map[0].bm_bn, map[0].bm_len, + flags); + + key.buftarg = btp; + key.blkno = map[0].bm_bn; + for (i = 0; i < nmaps; i++) { + key.bblen += map[i].bm_len; + } + key.map = map; + key.nmaps = nmaps; + + return __cache_lookup(&key, flags); } void libxfs_putbuf(xfs_buf_t *bp) { + /* + * ensure that any errors on this use of the buffer don't carry + * over to the next user. + */ + bp->b_error = 0; + #ifdef XFS_BUF_TRACING pthread_mutex_lock(&libxfs_bcache->c_mutex); lock_buf_count--; @@ -479,17 +669,18 @@ pthread_mutex_unlock(&bp->b_lock); } } + cache_node_put(libxfs_bcache, (struct cache_node *)bp); } void libxfs_purgebuf(xfs_buf_t *bp) { - xfs_bufkey_t key; + struct xfs_bufkey key = {0}; - key.device = bp->b_dev; - key.blkno = bp->b_blkno; - key.bblen = bp->b_bcount >> BBSHIFT; + key.buftarg = bp->b_target; + key.blkno = bp->b_bn; + key.bblen = bp->b_length; cache_node_purge(libxfs_bcache, &key, (struct cache_node *)bp); } @@ -497,100 +688,285 @@ static struct cache_node * libxfs_balloc(cache_key_t key) { - xfs_bufkey_t *bufkey = (xfs_bufkey_t *)key; + struct xfs_bufkey *bufkey = (struct xfs_bufkey *)key; - return (struct cache_node *)libxfs_getbufr(bufkey->device, - bufkey->blkno, bufkey->bblen); + if (bufkey->map) + return (struct cache_node *) + libxfs_getbufr_map(bufkey->buftarg, + bufkey->blkno, bufkey->bblen, + bufkey->map, bufkey->nmaps); + return (struct cache_node *)libxfs_getbufr(bufkey->buftarg, + bufkey->blkno, bufkey->bblen); } -int -libxfs_readbufr(dev_t dev, xfs_daddr_t blkno, xfs_buf_t *bp, int len, int flags) + +static int +__read_buf(int fd, void *buf, int len, off64_t offset, int flags) { - int fd = libxfs_device_to_fd(dev); - int bytes = BBTOB(len); - int error; int sts; - ASSERT(BBTOB(len) <= bp->b_bcount); - - sts = pread64(fd, bp->b_addr, bytes, LIBXFS_BBTOOFF64(blkno)); + sts = pread64(fd, buf, len, offset); if (sts < 0) { - error = errno; + int error = errno; fprintf(stderr, _("%s: read failed: %s\n"), progname, strerror(error)); if (flags & LIBXFS_EXIT_ON_FAILURE) exit(1); return error; - } else if (sts != bytes) { + } else if (sts != len) { fprintf(stderr, _("%s: error - read only %d of %d bytes\n"), - progname, sts, bytes); + progname, sts, len); if (flags & LIBXFS_EXIT_ON_FAILURE) exit(1); return EIO; } + return 0; +} + +int +libxfs_readbufr(struct xfs_buftarg *btp, xfs_daddr_t blkno, xfs_buf_t *bp, + int len, int flags) +{ + int fd = libxfs_device_to_fd(btp->dev); + int bytes = BBTOB(len); + int error; + + ASSERT(BBTOB(len) <= bp->b_bcount); + + error = __read_buf(fd, bp->b_addr, bytes, LIBXFS_BBTOOFF64(blkno), flags); + if (!error && + bp->b_target->dev == btp->dev && + bp->b_bn == blkno && + bp->b_bcount == bytes) + bp->b_flags |= LIBXFS_B_UPTODATE; #ifdef IO_DEBUG - printf("%lx: %s: read %u bytes, blkno=%llu(%llu), %p\n", - pthread_self(), __FUNCTION__, bytes, + printf("%lx: %s: read %u bytes, error %d, blkno=0x%llx(0x%llx), %p\n", + pthread_self(), __FUNCTION__, bytes, error, (long long)LIBXFS_BBTOOFF64(blkno), (long long)blkno, bp); #endif - if (bp->b_dev == dev && - bp->b_blkno == blkno && - bp->b_bcount == bytes) - bp->b_flags |= LIBXFS_B_UPTODATE; - return 0; + return error; +} + +void +libxfs_readbuf_verify(struct xfs_buf *bp, const struct xfs_buf_ops *ops) +{ + if (!ops) + return; + bp->b_ops = ops; + bp->b_ops->verify_read(bp); + bp->b_flags &= ~LIBXFS_B_UNCHECKED; } + xfs_buf_t * -libxfs_readbuf(dev_t dev, xfs_daddr_t blkno, int len, int flags) +libxfs_readbuf(struct xfs_buftarg *btp, xfs_daddr_t blkno, int len, int flags, + const struct xfs_buf_ops *ops) { xfs_buf_t *bp; int error; - bp = libxfs_getbuf(dev, blkno, len); - if (bp && !(bp->b_flags & (LIBXFS_B_UPTODATE|LIBXFS_B_DIRTY))) { - error = libxfs_readbufr(dev, blkno, bp, len, flags); - if (error) - bp->b_error = error; + bp = libxfs_getbuf(btp, blkno, len); + if (!bp) + return NULL; + + /* + * if the buffer was prefetched, it is likely that it was not validated. + * Hence if we are supplied an ops function and the buffer is marked as + * unchecked, we need to validate it now. + * + * We do this verification even if the buffer is dirty - the + * verification is almost certainly going to fail the CRC check in this + * case as a dirty buffer has not had the CRC recalculated. However, we + * should not be dirtying unchecked buffers and therefore failing it + * here because it's dirty and unchecked indicates we've screwed up + * somewhere else. + */ + bp->b_error = 0; + if ((bp->b_flags & (LIBXFS_B_UPTODATE|LIBXFS_B_DIRTY))) { + if (bp->b_flags & LIBXFS_B_UNCHECKED) + libxfs_readbuf_verify(bp, ops); + return bp; } + + /* + * Set the ops on a cache miss (i.e. first physical read) as the + * verifier may change the ops to match the type of buffer it contains. + * A cache hit might reset the verifier to the original type if we set + * it again, but it won't get called again and set to match the buffer + * contents. *cough* xfs_da_node_buf_ops *cough*. + */ + error = libxfs_readbufr(btp, blkno, bp, len, flags); + if (error) + bp->b_error = error; + else + libxfs_readbuf_verify(bp, ops); return bp; } int -libxfs_writebufr(xfs_buf_t *bp) +libxfs_readbufr_map(struct xfs_buftarg *btp, struct xfs_buf *bp, int flags) +{ + int fd; + int error = 0; + char *buf; + int i; + + fd = libxfs_device_to_fd(btp->dev); + buf = bp->b_addr; + for (i = 0; i < bp->b_nmaps; i++) { + off64_t offset = LIBXFS_BBTOOFF64(bp->b_map[i].bm_bn); + int len = BBTOB(bp->b_map[i].bm_len); + + error = __read_buf(fd, buf, len, offset, flags); + if (error) { + bp->b_error = error; + break; + } + buf += len; + } + + if (!error) + bp->b_flags |= LIBXFS_B_UPTODATE; +#ifdef IO_DEBUG + printf("%lx: %s: read %u bytes, error %d, blkno=0x%llx(0x%llx), %p\n", + pthread_self(), __FUNCTION__, , error, + (long long)LIBXFS_BBTOOFF64(blkno), (long long)blkno, bp); +#endif + return error; +} + +struct xfs_buf * +libxfs_readbuf_map(struct xfs_buftarg *btp, struct xfs_buf_map *map, int nmaps, + int flags, const struct xfs_buf_ops *ops) +{ + struct xfs_buf *bp; + int error = 0; + + if (nmaps == 1) + return libxfs_readbuf(btp, map[0].bm_bn, map[0].bm_len, + flags, ops); + + bp = libxfs_getbuf_map(btp, map, nmaps, 0); + if (!bp) + return NULL; + + bp->b_error = 0; + if ((bp->b_flags & (LIBXFS_B_UPTODATE|LIBXFS_B_DIRTY))) { + if (bp->b_flags & LIBXFS_B_UNCHECKED) + libxfs_readbuf_verify(bp, ops); + return bp; + } + error = libxfs_readbufr_map(btp, bp, flags); + if (!error) + libxfs_readbuf_verify(bp, ops); + +#ifdef IO_DEBUG + printf("%lx: %s: read %lu bytes, error %d, blkno=%llu(%llu), %p\n", + pthread_self(), __FUNCTION__, buf - (char *)bp->b_addr, error, + (long long)LIBXFS_BBTOOFF64(bp->b_bn), (long long)bp->b_bn, bp); +#endif + return bp; +} + +static int +__write_buf(int fd, void *buf, int len, off64_t offset, int flags) { int sts; - int fd = libxfs_device_to_fd(bp->b_dev); - int error; - sts = pwrite64(fd, bp->b_addr, bp->b_bcount, LIBXFS_BBTOOFF64(bp->b_blkno)); + sts = pwrite64(fd, buf, len, offset); if (sts < 0) { - error = errno; + int error = errno; fprintf(stderr, _("%s: pwrite64 failed: %s\n"), progname, strerror(error)); - if (bp->b_flags & LIBXFS_B_EXIT) + if (flags & LIBXFS_B_EXIT) exit(1); return error; - } else if (sts != bp->b_bcount) { - fprintf(stderr, _("%s: error - wrote only %d of %d bytes\n"), - progname, sts, bp->b_bcount); - if (bp->b_flags & LIBXFS_B_EXIT) + } else if (sts != len) { + fprintf(stderr, _("%s: error - pwrite64 only %d of %d bytes\n"), + progname, sts, len); + if (flags & LIBXFS_B_EXIT) exit(1); return EIO; } + return 0; +} + +int +libxfs_writebufr(xfs_buf_t *bp) +{ + int fd = libxfs_device_to_fd(bp->b_target->dev); + int error = 0; + + /* + * we never write buffers that are marked stale. This indicates they + * contain data that has been invalidated, and even if the buffer is + * dirty it must *never* be written. Verifiers are wonderful for finding + * bugs like this. Make sure the error is obvious as to the cause. + */ + if (bp->b_flags & LIBXFS_B_STALE) { + bp->b_error = ESTALE; + return bp->b_error; + } + + /* + * clear any pre-existing error status on the buffer. This can occur if + * the buffer is corrupt on disk and the repair process doesn't clear + * the error before fixing and writing it back. + */ + bp->b_error = 0; + if (bp->b_ops) { + bp->b_ops->verify_write(bp); + if (bp->b_error) { + fprintf(stderr, + _("%s: write verifer failed on bno 0x%llx/0x%x\n"), + __func__, (long long)bp->b_bn, bp->b_bcount); + return bp->b_error; + } + } + + if (!(bp->b_flags & LIBXFS_B_DISCONTIG)) { + error = __write_buf(fd, bp->b_addr, bp->b_bcount, + LIBXFS_BBTOOFF64(bp->b_bn), bp->b_flags); + } else { + int i; + char *buf = bp->b_addr; + + for (i = 0; i < bp->b_nmaps; i++) { + off64_t offset = LIBXFS_BBTOOFF64(bp->b_map[i].bm_bn); + int len = BBTOB(bp->b_map[i].bm_len); + + error = __write_buf(fd, buf, len, offset, bp->b_flags); + if (error) { + bp->b_error = error; + break; + } + buf += len; + } + } + #ifdef IO_DEBUG - printf("%lx: %s: wrote %u bytes, blkno=%llu(%llu), %p\n", + printf("%lx: %s: wrote %u bytes, blkno=%llu(%llu), %p, error %d\n", pthread_self(), __FUNCTION__, bp->b_bcount, - (long long)LIBXFS_BBTOOFF64(bp->b_blkno), - (long long)bp->b_blkno, bp); + (long long)LIBXFS_BBTOOFF64(bp->b_bn), + (long long)bp->b_bn, bp, error); #endif - bp->b_flags |= LIBXFS_B_UPTODATE; - bp->b_flags &= ~(LIBXFS_B_DIRTY | LIBXFS_B_EXIT); - return 0; + if (!error) { + bp->b_flags |= LIBXFS_B_UPTODATE; + bp->b_flags &= ~(LIBXFS_B_DIRTY | LIBXFS_B_EXIT | + LIBXFS_B_UNCHECKED); + } + return error; } int libxfs_writebuf_int(xfs_buf_t *bp, int flags) { + /* + * Clear any error hanging over from reading the buffer. This prevents + * subsequent reads after this write from seeing stale errors. + */ + bp->b_error = 0; + bp->b_flags &= ~LIBXFS_B_STALE; bp->b_flags |= (LIBXFS_B_DIRTY | flags); return 0; } @@ -598,6 +974,18 @@ int libxfs_writebuf(xfs_buf_t *bp, int flags) { +#ifdef IO_DEBUG + printf("%lx: %s: dirty blkno=%llu(%llu)\n", + pthread_self(), __FUNCTION__, + (long long)LIBXFS_BBTOOFF64(bp->b_bn), + (long long)bp->b_bn); +#endif + /* + * Clear any error hanging over from reading the buffer. This prevents + * subsequent reads after this write from seeing stale errors. + */ + bp->b_error = 0; + bp->b_flags &= ~LIBXFS_B_STALE; bp->b_flags |= (LIBXFS_B_DIRTY | flags); libxfs_putbuf(bp); return 0; @@ -609,8 +997,8 @@ #ifdef IO_DEBUG if (boff + len > bp->b_bcount) { printf("Badness, iomove out of range!\n" - "bp=(bno %llu, bytes %u) range=(boff %u, bytes %u)\n", - (long long)bp->b_blkno, bp->b_bcount, boff, len); + "bp=(bno 0x%llx, bytes %u) range=(boff %u, bytes %u)\n", + (long long)bp->b_bn, bp->b_bcount, boff, len); abort(); } #endif @@ -710,26 +1098,12 @@ /* - * Inode cache interfaces + * Inode cache stubs. */ extern kmem_zone_t *xfs_ili_zone; extern kmem_zone_t *xfs_inode_zone; -static unsigned int -libxfs_ihash(cache_key_t key, unsigned int hashsize) -{ - return ((unsigned int)*(xfs_ino_t *)key) % hashsize; -} - -static int -libxfs_icompare(struct cache_node *node, cache_key_t key) -{ - xfs_inode_t *ip = (xfs_inode_t *)node; - - return (ip->i_ino == *(xfs_ino_t *)key); -} - int libxfs_iget(xfs_mount_t *mp, xfs_trans_t *tp, xfs_ino_t ino, uint lock_flags, xfs_inode_t **ipp, xfs_daddr_t bno) @@ -737,31 +1111,21 @@ xfs_inode_t *ip; int error = 0; - if (cache_node_get(libxfs_icache, &ino, (struct cache_node **)&ip)) { -#ifdef INO_DEBUG - fprintf(stderr, "%s: allocated inode, ino=%llu(%llu), %p\n", - __FUNCTION__, (unsigned long long)ino, bno, ip); -#endif - if ((error = libxfs_iread(mp, tp, ino, ip, bno))) { - cache_node_purge(libxfs_icache, &ino, - (struct cache_node *)ip); - ip = NULL; - } + ip = kmem_zone_zalloc(xfs_inode_zone, 0); + if (!ip) + return ENOMEM; + + ip->i_ino = ino; + ip->i_mount = mp; + error = xfs_iread(mp, tp, ip, bno); + if (error) { + kmem_zone_free(xfs_inode_zone, ip); + *ipp = NULL; + return error; } - *ipp = ip; - return error; -} -void -libxfs_iput(xfs_inode_t *ip, uint lock_flags) -{ - cache_node_put(libxfs_icache, (struct cache_node *)ip); -} - -static struct cache_node * -libxfs_ialloc(cache_key_t key) -{ - return kmem_zone_zalloc(xfs_inode_zone, 0); + *ipp = ip; + return 0; } static void @@ -778,32 +1142,12 @@ libxfs_idestroy_fork(ip, XFS_ATTR_FORK); } -static void -libxfs_irelse(struct cache_node *node) -{ - xfs_inode_t *ip = (xfs_inode_t *)node; - - if (ip != NULL) { - if (ip->i_itemp) - kmem_zone_free(xfs_ili_zone, ip->i_itemp); - ip->i_itemp = NULL; - libxfs_idestroy(ip); - kmem_zone_free(xfs_inode_zone, ip); - ip = NULL; - } -} - void -libxfs_icache_purge(void) +libxfs_iput(xfs_inode_t *ip) { - cache_purge(libxfs_icache); + if (ip->i_itemp) + kmem_zone_free(xfs_ili_zone, ip->i_itemp); + ip->i_itemp = NULL; + libxfs_idestroy(ip); + kmem_zone_free(xfs_inode_zone, ip); } - -struct cache_operations libxfs_icache_operations = { - /* .hash */ libxfs_ihash, - /* .alloc */ libxfs_ialloc, - /* .flush */ NULL, - /* .relse */ libxfs_irelse, - /* .compare */ libxfs_icompare, - /* .bulkrelse */ NULL -}; diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/trans.c xfsprogs-3.2.1ubuntu1/libxfs/trans.c --- xfsprogs-3.1.9ubuntu2/libxfs/trans.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/trans.c 2014-06-19 22:42:17.000000000 +0000 @@ -1,5 +1,6 @@ /* * Copyright (c) 2000-2001,2005-2006 Silicon Graphics, Inc. + * Copyright (C) 2010 Red Hat, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -22,6 +23,123 @@ * Simple transaction interface */ +kmem_zone_t *xfs_log_item_desc_zone; + +/* + * Initialize the precomputed transaction reservation values + * in the mount structure. + */ +void +libxfs_trans_init( + struct xfs_mount *mp) +{ + xfs_trans_resv_calc(mp, &mp->m_resv); +} + +/* + * Add the given log item to the transaction's list of log items. + * + * The log item will now point to its new descriptor with its li_desc field. + */ +void +libxfs_trans_add_item( + struct xfs_trans *tp, + struct xfs_log_item *lip) +{ + struct xfs_log_item_desc *lidp; + + ASSERT(lip->li_mountp == tp->t_mountp); + ASSERT(lip->li_ailp == tp->t_mountp->m_ail); + + lidp = calloc(sizeof(struct xfs_log_item_desc), 1); + if (!lidp) { + fprintf(stderr, _("%s: lidp calloc failed (%d bytes): %s\n"), + progname, (int)sizeof(struct xfs_log_item_desc), + strerror(errno)); + exit(1); + } + + lidp->lid_item = lip; + lidp->lid_flags = 0; + list_add_tail(&lidp->lid_trans, &tp->t_items); + + lip->li_desc = lidp; +} + +/* + * Unlink and free the given descriptor. + */ +void +libxfs_trans_del_item( + struct xfs_log_item *lip) +{ + list_del_init(&lip->li_desc->lid_trans); + free(lip->li_desc); + lip->li_desc = NULL; +} + +/* + * Roll from one trans in the sequence of PERMANENT transactions to + * the next: permanent transactions are only flushed out when + * committed with XFS_TRANS_RELEASE_LOG_RES, but we still want as soon + * as possible to let chunks of it go to the log. So we commit the + * chunk we've been working on and get a new transaction to continue. + */ +int +libxfs_trans_roll( + struct xfs_trans **tpp, + struct xfs_inode *dp) +{ + struct xfs_trans *trans; + struct xfs_trans_res tres; + int error; + + /* + * Ensure that the inode is always logged. + */ + trans = *tpp; + xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE); + + /* + * Copy the critical parameters from one trans to the next. + */ + tres.tr_logres = trans->t_log_res; + tres.tr_logcount = trans->t_log_count; + *tpp = xfs_trans_dup(trans); + + /* + * Commit the current transaction. + * If this commit failed, then it'd just unlock those items that + * are marked to be released. That also means that a filesystem shutdown + * is in progress. The caller takes the responsibility to cancel + * the duplicate transaction that gets returned. + */ + error = xfs_trans_commit(trans, 0); + if (error) + return (error); + + trans = *tpp; + + /* + * Reserve space in the log for th next transaction. + * This also pushes items in the "AIL", the list of logged items, + * out to disk if they are taking up space at the tail of the log + * that we want to use. This requires that either nothing be locked + * across this call, or that anything that is locked be logged in + * the prior and the next transactions. + */ + tres.tr_logflags = XFS_TRANS_PERM_LOG_RES; + error = xfs_trans_reserve(trans, &tres, 0, 0); + /* + * Ensure that the inode is in the new transaction and locked. + */ + if (error) + return error; + + xfs_trans_ijoin(trans, dp, 0); + return 0; +} + xfs_trans_t * libxfs_trans_alloc( xfs_mount_t *mp, @@ -58,12 +176,10 @@ int libxfs_trans_reserve( - xfs_trans_t *tp, - uint blocks, - uint logspace, - uint rtextents, - uint flags, - uint logcount) + struct xfs_trans *tp, + struct xfs_trans_res *resp, + uint blocks, + uint rtextents) { xfs_sb_t *mpsb = &tp->t_mountp->m_sb; @@ -132,27 +248,6 @@ } void -libxfs_trans_iput( - xfs_trans_t *tp, - xfs_inode_t *ip, - uint lock_flags) -{ - xfs_inode_log_item_t *iip; - - if (tp == NULL) { - libxfs_iput(ip, lock_flags); - return; - } - - ASSERT(ip->i_transp == tp); - iip = ip->i_itemp; - ASSERT(iip != NULL); - xfs_trans_del_item(&iip->ili_item); - - libxfs_iput(ip, lock_flags); -} - -void libxfs_trans_ijoin( xfs_trans_t *tp, xfs_inode_t *ip, @@ -185,7 +280,6 @@ ASSERT(ip->i_itemp != NULL); xfs_trans_ijoin(tp, ip, lock_flags); - ip->i_itemp->ili_lock_flags = lock_flags; #ifdef XACT_DEBUG fprintf(stderr, "ijoin_ref'd inode %llu, transaction %p\n", ip->i_ino, tp); @@ -193,21 +287,6 @@ } void -libxfs_trans_ihold( - xfs_trans_t *tp, - xfs_inode_t *ip) -{ - ASSERT(ip->i_transp == tp); - ASSERT(ip->i_itemp != NULL); - - ip->i_itemp->ili_lock_flags = 1; - -#ifdef XACT_DEBUG - fprintf(stderr, "ihold'd inode %llu, transaction %p\n", ip->i_ino, tp); -#endif -} - -void libxfs_trans_inode_alloc_buf( xfs_trans_t *tp, xfs_buf_t *bp) @@ -218,6 +297,7 @@ ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF; + xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF); } /* @@ -225,7 +305,7 @@ * to be logged when the transaction is committed. The inode must * already be associated with the given transaction. * - * The values for fieldmask are defined in xfs_inode_item.h. We always + * The values for fieldmask are defined in xfs_log_format.h. We always * log all of the core inode if any of it has changed, and we always log * all of the inline data/extents/b-tree root if any of them has changed. */ @@ -252,7 +332,7 @@ * this coordination mechanism. */ flags |= ip->i_itemp->ili_last_fields; - ip->i_itemp->ili_format.ilf_fields |= flags; + ip->i_itemp->ili_fields |= flags; } /* @@ -338,7 +418,7 @@ if (bip->bli_flags & XFS_BLI_STALE) return; XFS_BUF_UNDELAYWRITE(bp); - XFS_BUF_STALE(bp); + xfs_buf_stale(bp); bip->bli_flags |= XFS_BLI_STALE; bip->bli_flags &= ~XFS_BLI_DIRTY; bip->bli_format.blf_flags &= ~XFS_BLF_INODE_BUF; @@ -383,22 +463,20 @@ } xfs_buf_t * -libxfs_trans_get_buf( +libxfs_trans_get_buf_map( xfs_trans_t *tp, - dev_t dev, - xfs_daddr_t d, - int len, + struct xfs_buftarg *btp, + struct xfs_buf_map *map, + int nmaps, uint f) { xfs_buf_t *bp; xfs_buf_log_item_t *bip; - xfs_buftarg_t bdev; if (tp == NULL) - return libxfs_getbuf(dev, d, len); + return libxfs_getbuf_map(btp, map, nmaps, 0); - bdev.dev = dev; - bp = xfs_trans_buf_item_match(tp, &bdev, d, len); + bp = xfs_trans_buf_item_match(tp, btp, map, nmaps); if (bp != NULL) { ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); @@ -407,7 +485,7 @@ return bp; } - bp = libxfs_getbuf(dev, d, len); + bp = libxfs_getbuf_map(btp, map, nmaps, 0); if (bp == NULL) return NULL; #ifdef XACT_DEBUG @@ -432,15 +510,13 @@ { xfs_buf_t *bp; xfs_buf_log_item_t *bip; - xfs_buftarg_t bdev; - int len; + int len = XFS_FSS_TO_BB(mp, 1); + DEFINE_SINGLE_BUF_MAP(map, XFS_SB_DADDR, len); if (tp == NULL) return libxfs_getsb(mp, flags); - bdev.dev = mp->m_dev; - len = XFS_FSS_TO_BB(mp, 1); - bp = xfs_trans_buf_item_match(tp, &bdev, XFS_SB_DADDR, len); + bp = xfs_trans_buf_item_match(tp, mp->m_dev, &map, 1); if (bp != NULL) { ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); @@ -465,24 +541,24 @@ } int -libxfs_trans_read_buf( +libxfs_trans_read_buf_map( xfs_mount_t *mp, xfs_trans_t *tp, - dev_t dev, - xfs_daddr_t blkno, - int len, + struct xfs_buftarg *btp, + struct xfs_buf_map *map, + int nmaps, uint flags, - xfs_buf_t **bpp) + xfs_buf_t **bpp, + const struct xfs_buf_ops *ops) { xfs_buf_t *bp; xfs_buf_log_item_t *bip; - xfs_buftarg_t bdev; int error; *bpp = NULL; if (tp == NULL) { - bp = libxfs_readbuf(dev, blkno, len, flags); + bp = libxfs_readbuf_map(btp, map, nmaps, flags, ops); if (!bp) { return (flags & XBF_TRYLOCK) ? EAGAIN : XFS_ERROR(ENOMEM); @@ -492,8 +568,7 @@ goto done; } - bdev.dev = dev; - bp = xfs_trans_buf_item_match(tp, &bdev, blkno, len); + bp = xfs_trans_buf_item_match(tp, btp, map, nmaps); if (bp != NULL) { ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); @@ -502,7 +577,7 @@ goto done; } - bp = libxfs_readbuf(dev, blkno, len, flags); + bp = libxfs_readbuf_map(btp, map, nmaps, flags, ops); if (!bp) { return (flags & XBF_TRYLOCK) ? EAGAIN : XFS_ERROR(ENOMEM); @@ -582,26 +657,25 @@ xfs_mount_t *mp; xfs_buf_t *bp; int error; - extern kmem_zone_t *xfs_ili_zone; ip = iip->ili_inode; mp = iip->ili_item.li_mountp; ASSERT(ip != NULL); - if (!(iip->ili_format.ilf_fields & XFS_ILOG_ALL)) { + if (!(iip->ili_fields & XFS_ILOG_ALL)) { ip->i_transp = NULL; /* disassociate from transaction */ iip->ili_flags = 0; /* reset all flags */ - goto ili_done; + return; } /* * Get the buffer containing the on-disk inode. */ - error = xfs_itobp(mp, NULL, ip, &dip, &bp, 0); + error = xfs_imap_to_bp(mp, NULL, &ip->i_imap, &dip, &bp, 0, 0); if (error) { - fprintf(stderr, _("%s: warning - itobp failed (%d)\n"), + fprintf(stderr, _("%s: warning - imap_to_bp failed (%d)\n"), progname, error); - goto ili_done; + return; } XFS_BUF_SET_FSPRIVATE(bp, iip); @@ -609,7 +683,7 @@ if (error) { fprintf(stderr, _("%s: warning - iflush_int failed (%d)\n"), progname, error); - goto ili_done; + return; } ip->i_transp = NULL; /* disassociate from transaction */ @@ -617,22 +691,9 @@ XFS_BUF_SET_FSPRIVATE2(bp, NULL); /* remove xact ptr */ libxfs_writebuf(bp, 0); #ifdef XACT_DEBUG - fprintf(stderr, "flushing dirty inode %llu, buffer %p (hold=%u)\n", - ip->i_ino, bp, iip->ili_lock_flags); + fprintf(stderr, "flushing dirty inode %llu, buffer %p\n", + ip->i_ino, bp); #endif -ili_done: - if (iip->ili_lock_flags) { - iip->ili_lock_flags = 0; - return; - } else { - libxfs_iput(ip, 0); - } - - if (ip->i_itemp) - kmem_zone_free(xfs_ili_zone, ip->i_itemp); - else - ASSERT(0); - ip->i_itemp = NULL; } static void @@ -674,6 +735,7 @@ struct xfs_log_item *lip = lidp->lid_item; xfs_trans_del_item(lip); + if (lip->li_type == XFS_LI_BUF) buf_item_done((xfs_buf_log_item_t *)lip); else if (lip->li_type == XFS_LI_INODE) @@ -712,10 +774,6 @@ ip->i_transp = NULL; iip->ili_flags = 0; - if (!iip->ili_lock_flags) - libxfs_iput(ip, 0); - else - iip->ili_lock_flags = 0; } /* diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/util.c xfsprogs-3.2.1ubuntu1/libxfs/util.c --- xfsprogs-3.1.9ubuntu2/libxfs/util.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/util.c 2014-06-19 22:42:17.000000000 +0000 @@ -22,6 +22,113 @@ #include /* + * Calculate the worst case log unit reservation for a given superblock + * configuration. Copied and munged from the kernel code, and assumes a + * worse case header usage (maximum log buffer sizes) + */ +int +xfs_log_calc_unit_res( + struct xfs_mount *mp, + int unit_bytes) +{ + int iclog_space; + int iclog_header_size; + int iclog_size; + uint num_headers; + + if (xfs_sb_version_haslogv2(&mp->m_sb)) { + iclog_size = XLOG_MAX_RECORD_BSIZE; + iclog_header_size = BBTOB(iclog_size / XLOG_HEADER_CYCLE_SIZE); + } else { + iclog_size = XLOG_BIG_RECORD_BSIZE; + iclog_header_size = BBSIZE; + } + + /* + * Permanent reservations have up to 'cnt'-1 active log operations + * in the log. A unit in this case is the amount of space for one + * of these log operations. Normal reservations have a cnt of 1 + * and their unit amount is the total amount of space required. + * + * The following lines of code account for non-transaction data + * which occupy space in the on-disk log. + * + * Normal form of a transaction is: + * ... + * and then there are LR hdrs, split-recs and roundoff at end of syncs. + * + * We need to account for all the leadup data and trailer data + * around the transaction data. + * And then we need to account for the worst case in terms of using + * more space. + * The worst case will happen if: + * - the placement of the transaction happens to be such that the + * roundoff is at its maximum + * - the transaction data is synced before the commit record is synced + * i.e. | + * Therefore the commit record is in its own Log Record. + * This can happen as the commit record is called with its + * own region to xlog_write(). + * This then means that in the worst case, roundoff can happen for + * the commit-rec as well. + * The commit-rec is smaller than padding in this scenario and so it is + * not added separately. + */ + + /* for trans header */ + unit_bytes += sizeof(xlog_op_header_t); + unit_bytes += sizeof(xfs_trans_header_t); + + /* for start-rec */ + unit_bytes += sizeof(xlog_op_header_t); + + /* + * for LR headers - the space for data in an iclog is the size minus + * the space used for the headers. If we use the iclog size, then we + * undercalculate the number of headers required. + * + * Furthermore - the addition of op headers for split-recs might + * increase the space required enough to require more log and op + * headers, so take that into account too. + * + * IMPORTANT: This reservation makes the assumption that if this + * transaction is the first in an iclog and hence has the LR headers + * accounted to it, then the remaining space in the iclog is + * exclusively for this transaction. i.e. if the transaction is larger + * than the iclog, it will be the only thing in that iclog. + * Fundamentally, this means we must pass the entire log vector to + * xlog_write to guarantee this. + */ + iclog_space = iclog_size - iclog_header_size; + num_headers = howmany(unit_bytes, iclog_space); + + /* for split-recs - ophdrs added when data split over LRs */ + unit_bytes += sizeof(xlog_op_header_t) * num_headers; + + /* add extra header reservations if we overrun */ + while (!num_headers || + howmany(unit_bytes, iclog_space) > num_headers) { + unit_bytes += sizeof(xlog_op_header_t); + num_headers++; + } + unit_bytes += iclog_header_size * num_headers; + + /* for commit-rec LR header - note: padding will subsume the ophdr */ + unit_bytes += iclog_header_size; + + /* for roundoff padding for transaction data and one for commit record */ + if (xfs_sb_version_haslogv2(&mp->m_sb) && mp->m_sb.sb_logsunit > 1) { + /* log su roundoff */ + unit_bytes += 2 * mp->m_sb.sb_logsunit; + } else { + /* BB roundoff */ + unit_bytes += 2 * BBSIZE; + } + + return unit_bytes; +} + +/* * Change the requested timestamp in the given inode. * * This was once shared with the kernel, but has diverged to the point @@ -47,130 +154,10 @@ ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec; ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec; } -} - -/* - * Given a mount structure and an inode number, return a pointer - * to a newly allocated in-core inode coresponding to the given - * inode number. - * - * Initialize the inode's attributes and extent pointers if it - * already has them (it will not if the inode has no links). - * - * NOTE: this has slightly different behaviour to the kernel in - * that this version requires the already allocated *ip being - * passed in while the kernel version does the allocation and - * returns it in **ip. - */ -int -libxfs_iread( - xfs_mount_t *mp, - xfs_trans_t *tp, - xfs_ino_t ino, - xfs_inode_t *ip, - xfs_daddr_t bno) -{ - xfs_buf_t *bp; - xfs_dinode_t *dip; - int error; - - ip->i_ino = ino; - ip->i_mount = mp; - - /* - * Fill in the location information in the in-core inode. - */ - error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, 0); - if (error) - return error; - - /* - * Get pointers to the on-disk inode and the buffer containing it. - */ - error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp, XBF_LOCK, 0); - if (error) - return error; - dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset); - - /* - * If we got something that isn't an inode it means someone - * (nfs or dmi) has a stale handle. - */ - if (be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC) { - xfs_trans_brelse(tp, bp); - return EINVAL; + if (flags & XFS_ICHGTIME_CREATE) { + ip->i_d.di_crtime.t_sec = (__int32_t)tv.tv_sec; + ip->i_d.di_crtime.t_nsec = (__int32_t)tv.tv_nsec; } - - /* - * If the on-disk inode is already linked to a directory - * entry, copy all of the inode into the in-core inode. - * xfs_iformat() handles copying in the inode format - * specific information. - * Otherwise, just get the truly permanent information. - */ - if (dip->di_mode) { - xfs_dinode_from_disk(&ip->i_d, dip); - error = xfs_iformat(ip, dip); - if (error) { - xfs_trans_brelse(tp, bp); - return error; - } - } else { - ip->i_d.di_magic = be16_to_cpu(dip->di_magic); - ip->i_d.di_version = dip->di_version; - ip->i_d.di_gen = be32_to_cpu(dip->di_gen); - ip->i_d.di_flushiter = be16_to_cpu(dip->di_flushiter); - /* - * Make sure to pull in the mode here as well in - * case the inode is released without being used. - * This ensures that xfs_inactive() will see that - * the inode is already free and not try to mess - * with the uninitialized part of it. - */ - ip->i_d.di_mode = 0; - /* - * Initialize the per-fork minima and maxima for a new - * inode here. xfs_iformat will do it for old inodes. - */ - ip->i_df.if_ext_max = - XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); - } - - /* - * The inode format changed when we moved the link count and - * made it 32 bits long. If this is an old format inode, - * convert it in memory to look like a new one. If it gets - * flushed to disk we will convert back before flushing or - * logging it. We zero out the new projid_lo/hi field and the old link - * count field. We'll handle clearing the pad field (the remains - * of the old uuid field) when we actually convert the inode to - * the new format. We don't change the version number so that we - * can distinguish this from a real new format inode. - */ - if (ip->i_d.di_version == 1) { - ip->i_d.di_nlink = ip->i_d.di_onlink; - ip->i_d.di_onlink = 0; - xfs_set_projid(&ip->i_d, 0); - } - - ip->i_delayed_blks = 0; - ip->i_size = ip->i_d.di_size; - - /* - * Use xfs_trans_brelse() to release the buffer containing the - * on-disk inode, because it was acquired with xfs_trans_read_buf() - * in xfs_itobp() above. If tp is NULL, this is just a normal - * brelse(). If we're within a transaction, then xfs_trans_brelse() - * will only release the buffer if it is not dirty within the - * transaction. It will be OK to release the buffer in this case, - * because inodes on disk are never destroyed and we will be - * locking the new in-core inode before putting it in the hash - * table where other processes can find it. Thus we don't have - * to worry about the inode being changed just because we released - * the buffer. - */ - xfs_trans_brelse(tp, bp); - return 0; } /* @@ -193,7 +180,6 @@ struct fsxattr *fsx, int okalloc, xfs_buf_t **ialloc_context, - boolean_t *call_again, xfs_inode_t **ipp) { xfs_ino_t ino; @@ -206,10 +192,10 @@ * the on-disk inode to be allocated. */ error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc, - ialloc_context, call_again, &ino); + ialloc_context, &ino); if (error != 0) return error; - if (*call_again || ino == NULLFSINO) { + if (*ialloc_context || ino == NULLFSINO) { *ipp = NULL; return 0; } @@ -228,6 +214,7 @@ ip->i_d.di_gid = cr->cr_gid; xfs_set_projid(&ip->i_d, pip ? 0 : fsx->fsx_projid); memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); + xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD); /* * If the superblock version is up to where we support new format @@ -253,7 +240,6 @@ ip->i_d.di_size = 0; ip->i_d.di_nextents = 0; ASSERT(ip->i_d.di_nblocks == 0); - xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG|XFS_ICHGTIME_MOD); /* * di_gen will have been taken care of in xfs_iread. */ @@ -261,12 +247,25 @@ ip->i_d.di_dmevmask = 0; ip->i_d.di_dmstate = 0; ip->i_d.di_flags = pip ? 0 : fsx->fsx_xflags; + + if (ip->i_d.di_version == 3) { + ASSERT(ip->i_d.di_ino == ino); + ASSERT(uuid_equal(&ip->i_d.di_uuid, &mp->m_sb.sb_uuid)); + ip->i_d.di_crc = 0; + ip->i_d.di_changecount = 1; + ip->i_d.di_lsn = 0; + ip->i_d.di_flags2 = 0; + memset(&(ip->i_d.di_pad2[0]), 0, sizeof(ip->i_d.di_pad2)); + ip->i_d.di_crtime = ip->i_d.di_mtime; + } + flags = XFS_ILOG_CORE; switch (mode & S_IFMT) { case S_IFIFO: case S_IFSOCK: /* doesn't make sense to set an rdev for these */ rdev = 0; + /* FALLTHROUGH */ case S_IFCHR: case S_IFBLK: ip->i_d.di_format = XFS_DINODE_FMT_DEV; @@ -420,6 +419,10 @@ ASSERT(ip->i_d.di_nextents+ip->i_d.di_anextents <= ip->i_d.di_nblocks); ASSERT(ip->i_d.di_forkoff <= mp->m_sb.sb_inodesize); + /* bump the change count on v3 inodes */ + if (ip->i_d.di_version == 3) + ip->i_d.di_changecount++; + /* * Copy the dirty parts of the inode into the on-disk * inode. We always copy out the core of the inode, @@ -455,7 +458,7 @@ dip->di_onlink = 0; memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); memset(&(dip->di_pad[0]), 0, sizeof(dip->di_pad)); - ASSERT(xfs_get_projid(ip->i_d) == 0); + ASSERT(xfs_get_projid(&ip->i_d) == 0); } } @@ -463,6 +466,13 @@ if (XFS_IFORK_Q(ip)) xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK, bp); + /* update the lsn in the on disk inode if required */ + if (ip->i_d.di_version == 3) + dip->di_lsn = cpu_to_be64(iip->ili_item.li_lsn); + + /* generate the checksum. */ + xfs_dinode_calc_crc(mp, dip); + return 0; } @@ -560,7 +570,7 @@ error = 0; imapp = &imaps[0]; reccount = 1; - xfs_bmapi_flags = XFS_BMAPI_WRITE | (alloc_type ? XFS_BMAPI_PREALLOC : 0); + xfs_bmapi_flags = alloc_type ? XFS_BMAPI_PREALLOC : 0; mp = ip->i_mount; startoffset_fsb = XFS_B_TO_FSBT(mp, offset); allocatesize_fsb = XFS_B_TO_FSB(mp, count); @@ -571,24 +581,33 @@ tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); resblks = (uint)XFS_DIOSTRAT_SPACE_RES(mp, datablocks); - error = xfs_trans_reserve(tp, resblks, 0, 0, 0, 0); - if (error) + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, + resblks, 0); + /* + * Check for running out of space + */ + if (error) { + /* + * Free the transaction structure. + */ + ASSERT(error == ENOSPC); + xfs_trans_cancel(tp, 0); break; + } xfs_trans_ijoin(tp, ip, 0); - xfs_trans_ihold(tp, ip); xfs_bmap_init(&free_list, &firstfsb); - error = xfs_bmapi(tp, ip, startoffset_fsb, allocatesize_fsb, + error = xfs_bmapi_write(tp, ip, startoffset_fsb, allocatesize_fsb, xfs_bmapi_flags, &firstfsb, 0, imapp, &reccount, &free_list); if (error) - break; + goto error0; /* complete the transaction */ error = xfs_bmap_finish(&tp, &free_list, &committed); if (error) - break; + goto error0; error = xfs_trans_commit(tp, 0); if (error) @@ -602,6 +621,11 @@ allocatesize_fsb -= allocated_fsb; } return error; + +error0: /* Cancel bmap, cancel trans */ + xfs_bmap_cancel(&free_list); + xfs_trans_cancel(tp, 0); + return error; } unsigned int @@ -617,56 +641,6 @@ } /* - * Get a buffer for the dir/attr block, fill in the contents. - * Don't check magic number, the caller will (it's xfs_repair). - * - * Originally from xfs_da_btree.c in the kernel, but only used - * in userspace so it now resides here. - */ -int -libxfs_da_read_bufr( - xfs_trans_t *trans, - xfs_inode_t *dp, - xfs_dablk_t bno, - xfs_daddr_t mappedbno, - xfs_dabuf_t **bpp, - int whichfork) -{ - return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 2, - (inst_t *)__return_address); -} - -/* - * Hold dabuf at transaction commit. - * - * Originally from xfs_da_btree.c in the kernel, but only used - * in userspace so it now resides here. - */ -void -libxfs_da_bhold(xfs_trans_t *tp, xfs_dabuf_t *dabuf) -{ - int i; - - for (i = 0; i < dabuf->nbuf; i++) - xfs_trans_bhold(tp, dabuf->bps[i]); -} - -/* - * Join dabuf to transaction. - * - * Originally from xfs_da_btree.c in the kernel, but only used - * in userspace so it now resides here. - */ -void -libxfs_da_bjoin(xfs_trans_t *tp, xfs_dabuf_t *dabuf) -{ - int i; - - for (i = 0; i < dabuf->nbuf; i++) - xfs_trans_bjoin(tp, dabuf->bps[i]); -} - -/* * Wrapper around call to libxfs_ialloc. Takes care of committing and * allocating a new transaction as needed. * @@ -684,34 +658,43 @@ struct fsxattr *fsx, xfs_inode_t **ipp) { - boolean_t call_again; - int i; xfs_buf_t *ialloc_context; xfs_inode_t *ip; xfs_trans_t *ntp; int error; - call_again = B_FALSE; ialloc_context = (xfs_buf_t *)0; error = libxfs_ialloc(*tp, pip, mode, nlink, rdev, cr, fsx, - 1, &ialloc_context, &call_again, &ip); - if (error) + 1, &ialloc_context, &ip); + if (error) { + *ipp = NULL; return error; + } + if (!ialloc_context && !ip) { + *ipp = NULL; + return XFS_ERROR(ENOSPC); + } + + if (ialloc_context) { + struct xfs_trans_res tres; - if (call_again) { xfs_trans_bhold(*tp, ialloc_context); + tres.tr_logres = (*tp)->t_log_res; + tres.tr_logcount = (*tp)->t_log_count; + ntp = xfs_trans_dup(*tp); xfs_trans_commit(*tp, 0); *tp = ntp; - if ((i = xfs_trans_reserve(*tp, 0, 0, 0, 0, 0))) { + tres.tr_logflags = XFS_TRANS_PERM_LOG_RES; + error = xfs_trans_reserve(*tp, &tres, 0, 0); + if (error) { fprintf(stderr, _("%s: cannot reserve space: %s\n"), - progname, strerror(i)); + progname, strerror(error)); exit(1); } xfs_trans_bjoin(*tp, ialloc_context); error = libxfs_ialloc(*tp, pip, mode, nlink, rdev, cr, - fsx, 1, &ialloc_context, - &call_again, &ip); + fsx, 1, &ialloc_context, &ip); if (!ip) error = ENOSPC; if (error) @@ -761,3 +744,16 @@ fputs("\n", stderr); va_end(ap); } + +/* + * Warnings specifically for verifier errors. Differentiate CRC vs. invalid + * values, and omit the stack trace unless the error level is tuned high. + */ +void +xfs_verifier_error( + struct xfs_buf *bp) +{ + xfs_alert(NULL, "Metadata %s detected at block 0x%llx/0x%x", + bp->b_error == EFSBADCRC ? "CRC error" : "corruption", + bp->b_bn, BBTOB(bp->b_length)); +} diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_alloc_btree.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_alloc_btree.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_alloc_btree.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_alloc_btree.c 2014-05-02 00:09:16.000000000 +0000 @@ -75,6 +75,8 @@ return 0; } + xfs_extent_busy_reuse(cur->bc_mp, cur->bc_private.a.agno, bno, 1, false); + xfs_trans_agbtree_delta(cur->bc_tp, 1); new->s = cpu_to_be32(bno); @@ -89,7 +91,6 @@ struct xfs_buf *bp) { struct xfs_buf *agbp = cur->bc_private.a.agbp; - struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); xfs_agblock_t bno; int error; @@ -98,19 +99,11 @@ if (error) return error; - /* - * Since blocks move to the free list without the coordination used in - * xfs_bmap_finish, we can't allow block to be available for - * reallocation and non-transaction writing (user data) until we know - * that the transaction that moved it to the free list is permanently - * on disk. We track the blocks by declaring these blocks as "busy"; - * the busy list is maintained on a per-ag basis and each transaction - * records which entries should be removed when the iclog commits to - * disk. If a busy block is allocated, the iclog is pushed up to the - * LSN that freed the block. - */ - xfs_alloc_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1); + xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1, + XFS_EXTENT_BUSY_SKIP_DISCARD); xfs_trans_agbtree_delta(cur->bc_tp, -1); + + xfs_trans_binval(cur->bc_tp, bp); return 0; } @@ -260,7 +253,122 @@ return (__int64_t)be32_to_cpu(kp->ar_startblock) - rec->ar_startblock; } -#ifdef DEBUG +static bool +xfs_allocbt_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); + struct xfs_perag *pag = bp->b_pag; + unsigned int level; + + /* + * magic number and level verification + * + * During growfs operations, we can't verify the exact level or owner as + * the perag is not fully initialised and hence not attached to the + * buffer. In this case, check against the maximum tree depth. + * + * Similarly, during log recovery we will have a perag structure + * attached, but the agf information will not yet have been initialised + * from the on disk AGF. Again, we can only check against maximum limits + * in this case. + */ + level = be16_to_cpu(block->bb_level); + switch (block->bb_magic) { + case cpu_to_be32(XFS_ABTB_CRC_MAGIC): + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return false; + if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) + return false; + if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) + return false; + if (pag && + be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + return false; + /* fall through */ + case cpu_to_be32(XFS_ABTB_MAGIC): + if (pag && pag->pagf_init) { + if (level >= pag->pagf_levels[XFS_BTNUM_BNOi]) + return false; + } else if (level >= mp->m_ag_maxlevels) + return false; + break; + case cpu_to_be32(XFS_ABTC_CRC_MAGIC): + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return false; + if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) + return false; + if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) + return false; + if (pag && + be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + return false; + /* fall through */ + case cpu_to_be32(XFS_ABTC_MAGIC): + if (pag && pag->pagf_init) { + if (level >= pag->pagf_levels[XFS_BTNUM_CNTi]) + return false; + } else if (level >= mp->m_ag_maxlevels) + return false; + break; + default: + return false; + } + + /* numrecs verification */ + if (be16_to_cpu(block->bb_numrecs) > mp->m_alloc_mxr[level != 0]) + return false; + + /* sibling pointer verification */ + if (!block->bb_u.s.bb_leftsib || + (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks && + block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK))) + return false; + if (!block->bb_u.s.bb_rightsib || + (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks && + block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK))) + return false; + + return true; +} + +static void +xfs_allocbt_read_verify( + struct xfs_buf *bp) +{ + if (!xfs_btree_sblock_verify_crc(bp)) + xfs_buf_ioerror(bp, EFSBADCRC); + else if (!xfs_allocbt_verify(bp)) + xfs_buf_ioerror(bp, EFSCORRUPTED); + + if (bp->b_error) { + trace_xfs_btree_corrupt(bp, _RET_IP_); + xfs_verifier_error(bp); + } +} + +static void +xfs_allocbt_write_verify( + struct xfs_buf *bp) +{ + if (!xfs_allocbt_verify(bp)) { + trace_xfs_btree_corrupt(bp, _RET_IP_); + xfs_buf_ioerror(bp, EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + xfs_btree_sblock_calc_crc(bp); + +} + +const struct xfs_buf_ops xfs_allocbt_buf_ops = { + .verify_read = xfs_allocbt_read_verify, + .verify_write = xfs_allocbt_write_verify, +}; + + +#if defined(DEBUG) || defined(XFS_WARN) STATIC int xfs_allocbt_keys_inorder( struct xfs_btree_cur *cur, @@ -381,8 +489,8 @@ .init_rec_from_cur = xfs_allocbt_init_rec_from_cur, .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur, .key_diff = xfs_allocbt_key_diff, - -#ifdef DEBUG + .buf_ops = &xfs_allocbt_buf_ops, +#if defined(DEBUG) || defined(XFS_WARN) .keys_inorder = xfs_allocbt_keys_inorder, .recs_inorder = xfs_allocbt_recs_inorder, #endif @@ -415,17 +523,23 @@ cur->bc_tp = tp; cur->bc_mp = mp; - cur->bc_nlevels = be32_to_cpu(agf->agf_levels[btnum]); cur->bc_btnum = btnum; cur->bc_blocklog = mp->m_sb.sb_blocklog; - cur->bc_ops = &xfs_allocbt_ops; - if (btnum == XFS_BTNUM_CNT) + + if (btnum == XFS_BTNUM_CNT) { + cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]); cur->bc_flags = XFS_BTREE_LASTREC_UPDATE; + } else { + cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]); + } cur->bc_private.a.agbp = agbp; cur->bc_private.a.agno = agno; + if (xfs_sb_version_hascrc(&mp->m_sb)) + cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; + return cur; } diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_alloc.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_alloc.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_alloc.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_alloc.c 2014-05-02 00:09:16.000000000 +0000 @@ -22,19 +22,11 @@ #define XFSA_FIXUP_BNO_OK 1 #define XFSA_FIXUP_CNT_OK 2 -/* - * Prototypes for per-ag allocation routines - */ - STATIC int xfs_alloc_ag_vextent_exact(xfs_alloc_arg_t *); STATIC int xfs_alloc_ag_vextent_near(xfs_alloc_arg_t *); STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *); STATIC int xfs_alloc_ag_vextent_small(xfs_alloc_arg_t *, - xfs_btree_cur_t *, xfs_agblock_t *, xfs_extlen_t *, int *); - -/* - * Internal functions. - */ + xfs_btree_cur_t *, xfs_agblock_t *, xfs_extlen_t *, int *); /* * Lookup the record equal to [bno, len] in the btree given by cur. @@ -55,7 +47,7 @@ * Lookup the first record greater than or equal to [bno, len] * in the btree given by cur. */ -STATIC int /* error */ +int /* error */ xfs_alloc_lookup_ge( struct xfs_btree_cur *cur, /* btree cursor */ xfs_agblock_t bno, /* starting block of extent */ @@ -71,7 +63,7 @@ * Lookup the first record less than or equal to [bno, len] * in the btree given by cur. */ -STATIC int /* error */ +int /* error */ xfs_alloc_lookup_le( struct xfs_btree_cur *cur, /* btree cursor */ xfs_agblock_t bno, /* starting block of extent */ @@ -104,7 +96,7 @@ /* * Get the data from the pointed-to record. */ -STATIC int /* error */ +int /* error */ xfs_alloc_get_rec( struct xfs_btree_cur *cur, /* btree cursor */ xfs_agblock_t *bno, /* output: starting block of extent */ @@ -128,27 +120,28 @@ */ STATIC void xfs_alloc_compute_aligned( + xfs_alloc_arg_t *args, /* allocation argument structure */ xfs_agblock_t foundbno, /* starting block in found extent */ xfs_extlen_t foundlen, /* length in found extent */ - xfs_extlen_t alignment, /* alignment for allocation */ - xfs_extlen_t minlen, /* minimum length for allocation */ xfs_agblock_t *resbno, /* result block number */ xfs_extlen_t *reslen) /* result length */ { xfs_agblock_t bno; - xfs_extlen_t diff; xfs_extlen_t len; - if (alignment > 1 && foundlen >= minlen) { - bno = roundup(foundbno, alignment); - diff = bno - foundbno; - len = diff >= foundlen ? 0 : foundlen - diff; + /* Trim busy sections out of found extent */ + xfs_extent_busy_trim(args, foundbno, foundlen, &bno, &len); + + if (args->alignment > 1 && len >= args->minlen) { + xfs_agblock_t aligned_bno = roundup(bno, args->alignment); + xfs_extlen_t diff = aligned_bno - bno; + + *resbno = aligned_bno; + *reslen = diff >= len ? 0 : len - diff; } else { - bno = foundbno; - len = foundlen; + *resbno = bno; + *reslen = len; } - *resbno = bno; - *reslen = len; } /* @@ -160,6 +153,7 @@ xfs_agblock_t wantbno, /* target starting block */ xfs_extlen_t wantlen, /* target length */ xfs_extlen_t alignment, /* target alignment */ + char userdata, /* are we allocating data? */ xfs_agblock_t freebno, /* freespace's starting block */ xfs_extlen_t freelen, /* freespace's length */ xfs_agblock_t *newbnop) /* result: best start block from free */ @@ -174,7 +168,14 @@ ASSERT(freelen >= wantlen); freeend = freebno + freelen; wantend = wantbno + wantlen; - if (freebno >= wantbno) { + /* + * We want to allocate from the start of a free extent if it is past + * the desired block or if we are allocating user data and the free + * extent is before desired block. The second case is there to allow + * for contiguous allocation from the remaining free space if the file + * grows in the short term. + */ + if (freebno >= wantbno || (userdata && freeend < wantend)) { if ((newbno1 = roundup(freebno, alignment)) >= freeend) newbno1 = NULLAGBLOCK; } else if (freeend >= wantend && alignment > 1) { @@ -262,7 +263,6 @@ return 1; agf = XFS_BUF_TO_AGF(args->agbp); diff = be32_to_cpu(agf->agf_freeblks) - + be32_to_cpu(agf->agf_flcount) - args->len - args->minleft; if (diff >= 0) return 1; @@ -418,6 +418,87 @@ return 0; } +static bool +xfs_agfl_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_agfl *agfl = XFS_BUF_TO_AGFL(bp); + int i; + + if (!uuid_equal(&agfl->agfl_uuid, &mp->m_sb.sb_uuid)) + return false; + if (be32_to_cpu(agfl->agfl_magicnum) != XFS_AGFL_MAGIC) + return false; + /* + * during growfs operations, the perag is not fully initialised, + * so we can't use it for any useful checking. growfs ensures we can't + * use it by using uncached buffers that don't have the perag attached + * so we can detect and avoid this problem. + */ + if (bp->b_pag && be32_to_cpu(agfl->agfl_seqno) != bp->b_pag->pag_agno) + return false; + + for (i = 0; i < XFS_AGFL_SIZE(mp); i++) { + if (be32_to_cpu(agfl->agfl_bno[i]) != NULLAGBLOCK && + be32_to_cpu(agfl->agfl_bno[i]) >= mp->m_sb.sb_agblocks) + return false; + } + return true; +} + +static void +xfs_agfl_read_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + + /* + * There is no verification of non-crc AGFLs because mkfs does not + * initialise the AGFL to zero or NULL. Hence the only valid part of the + * AGFL is what the AGF says is active. We can't get to the AGF, so we + * can't verify just those entries are valid. + */ + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return; + + if (!xfs_buf_verify_cksum(bp, XFS_AGFL_CRC_OFF)) + xfs_buf_ioerror(bp, EFSBADCRC); + else if (!xfs_agfl_verify(bp)) + xfs_buf_ioerror(bp, EFSCORRUPTED); + + if (bp->b_error) + xfs_verifier_error(bp); +} + +static void +xfs_agfl_write_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_buf_log_item *bip = bp->b_fspriv; + + /* no verification of non-crc AGFLs */ + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return; + + if (!xfs_agfl_verify(bp)) { + xfs_buf_ioerror(bp, EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + + if (bip) + XFS_BUF_TO_AGFL(bp)->agfl_lsn = cpu_to_be64(bip->bli_item.li_lsn); + + xfs_buf_update_cksum(bp, XFS_AGFL_CRC_OFF); +} + +const struct xfs_buf_ops xfs_agfl_buf_ops = { + .verify_read = xfs_agfl_read_verify, + .verify_write = xfs_agfl_write_verify, +}; + /* * Read in the allocation group free block array. */ @@ -435,16 +516,36 @@ error = xfs_trans_read_buf( mp, tp, mp->m_ddev_targp, XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), - XFS_FSS_TO_BB(mp, 1), 0, &bp); + XFS_FSS_TO_BB(mp, 1), 0, &bp, &xfs_agfl_buf_ops); if (error) return error; - ASSERT(bp); - ASSERT(!XFS_BUF_GETERROR(bp)); - XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGFL, XFS_AGFL_REF); + ASSERT(!xfs_buf_geterror(bp)); + xfs_buf_set_ref(bp, XFS_AGFL_REF); *bpp = bp; return 0; } +STATIC int +xfs_alloc_update_counters( + struct xfs_trans *tp, + struct xfs_perag *pag, + struct xfs_buf *agbp, + long len) +{ + struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); + + pag->pagf_freeblks += len; + be32_add_cpu(&agf->agf_freeblks, len); + + xfs_trans_agblocks_delta(tp, len); + if (unlikely(be32_to_cpu(agf->agf_freeblks) > + be32_to_cpu(agf->agf_length))) + return EFSCORRUPTED; + + xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS); + return 0; +} + /* * Allocation group level functions. */ @@ -486,49 +587,36 @@ ASSERT(0); /* NOTREACHED */ } - if (error) + + if (error || args->agbno == NULLAGBLOCK) return error; - /* - * If the allocation worked, need to change the agf structure - * (and log it), and the superblock. - */ - if (args->agbno != NULLAGBLOCK) { - xfs_agf_t *agf; /* allocation group freelist header */ - long slen = (long)args->len; - ASSERT(args->len >= args->minlen && args->len <= args->maxlen); - ASSERT(!(args->wasfromfl) || !args->isfl); - ASSERT(args->agbno % args->alignment == 0); - if (!(args->wasfromfl)) { + ASSERT(args->len >= args->minlen); + ASSERT(args->len <= args->maxlen); + ASSERT(!args->wasfromfl || !args->isfl); + ASSERT(args->agbno % args->alignment == 0); + + if (!args->wasfromfl) { + error = xfs_alloc_update_counters(args->tp, args->pag, + args->agbp, + -((long)(args->len))); + if (error) + return error; - agf = XFS_BUF_TO_AGF(args->agbp); - be32_add_cpu(&agf->agf_freeblks, -(args->len)); - xfs_trans_agblocks_delta(args->tp, - -((long)(args->len))); - args->pag->pagf_freeblks -= args->len; - ASSERT(be32_to_cpu(agf->agf_freeblks) <= - be32_to_cpu(agf->agf_length)); - xfs_alloc_log_agf(args->tp, args->agbp, - XFS_AGF_FREEBLKS); - /* - * Search the busylist for these blocks and mark the - * transaction as synchronous if blocks are found. This - * avoids the need to block due to a synchronous log - * force to ensure correct ordering as the synchronous - * transaction will guarantee that for us. - */ - if (xfs_alloc_busy_search(args->mp, args->agno, - args->agbno, args->len)) - xfs_trans_set_sync(args->tp); - } - if (!args->isfl) - xfs_trans_mod_sb(args->tp, - args->wasdel ? XFS_TRANS_SB_RES_FDBLOCKS : - XFS_TRANS_SB_FDBLOCKS, -slen); - XFS_STATS_INC(xs_allocx); - XFS_STATS_ADD(xs_allocb, args->len); + ASSERT(!xfs_extent_busy_search(args->mp, args->agno, + args->agbno, args->len)); } - return 0; + + if (!args->isfl) { + xfs_trans_mod_sb(args->tp, args->wasdel ? + XFS_TRANS_SB_RES_FDBLOCKS : + XFS_TRANS_SB_FDBLOCKS, + -((long)(args->len))); + } + + XFS_STATS_INC(xs_allocx); + XFS_STATS_ADD(xs_allocb, args->len); + return error; } /* @@ -543,17 +631,16 @@ { xfs_btree_cur_t *bno_cur;/* by block-number btree cursor */ xfs_btree_cur_t *cnt_cur;/* by count btree cursor */ - xfs_agblock_t end; /* end of allocated extent */ int error; xfs_agblock_t fbno; /* start block of found extent */ - xfs_agblock_t fend; /* end block of found extent */ xfs_extlen_t flen; /* length of found extent */ + xfs_agblock_t tbno; /* start block of trimmed extent */ + xfs_extlen_t tlen; /* length of trimmed extent */ + xfs_agblock_t tend; /* end block of trimmed extent */ int i; /* success/failure of operation */ - xfs_agblock_t maxend; /* end of maximal extent */ - xfs_agblock_t minend; /* end of minimal extent */ - xfs_extlen_t rlen; /* length of returned extent */ ASSERT(args->alignment == 1); + /* * Allocate/initialize a cursor for the by-number freespace btree. */ @@ -579,14 +666,22 @@ goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); ASSERT(fbno <= args->agbno); - minend = args->agbno + args->minlen; - maxend = args->agbno + args->maxlen; - fend = fbno + flen; /* - * Give up if the freespace isn't long enough for the minimum request. + * Check for overlapping busy extents. + */ + xfs_extent_busy_trim(args, fbno, flen, &tbno, &tlen); + + /* + * Give up if the start of the extent is busy, or the freespace isn't + * long enough for the minimum request. */ - if (fend < minend) + if (tbno > args->agbno) + goto not_found; + if (tlen < args->minlen) + goto not_found; + tend = tbno + tlen; + if (tend < args->agbno + args->minlen) goto not_found; /* @@ -595,18 +690,16 @@ * * Fix the length according to mod and prod if given. */ - end = XFS_AGBLOCK_MIN(fend, maxend); - args->len = end - args->agbno; + args->len = XFS_AGBLOCK_MIN(tend, args->agbno + args->maxlen) + - args->agbno; xfs_alloc_fix_len(args); if (!xfs_alloc_fix_minleft(args)) goto not_found; - rlen = args->len; - ASSERT(args->agbno + rlen <= fend); - end = args->agbno + rlen; + ASSERT(args->agbno + args->len <= tend); /* - * We are allocating agbno for rlen [agbno .. end] + * We are allocating agbno for args->len * Allocate/initialize a cursor for the by-size btree. */ cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, @@ -619,8 +712,10 @@ xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR); goto error0; } + xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); + args->wasfromfl = 0; trace_xfs_alloc_exact_done(args); return 0; @@ -649,11 +744,11 @@ struct xfs_btree_cur **scur, /* searching cursor */ xfs_agblock_t gdiff, /* difference for search comparison */ xfs_agblock_t *sbno, /* extent found by search */ - xfs_extlen_t *slen, - xfs_extlen_t *slena, /* aligned length */ + xfs_extlen_t *slen, /* extent length */ + xfs_agblock_t *sbnoa, /* aligned extent found by search */ + xfs_extlen_t *slena, /* aligned extent length */ int dir) /* 0 = search right, 1 = search left */ { - xfs_agblock_t bno; xfs_agblock_t new; xfs_agblock_t sdiff; int error; @@ -671,17 +766,16 @@ if (error) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); - xfs_alloc_compute_aligned(*sbno, *slen, args->alignment, - args->minlen, &bno, slena); + xfs_alloc_compute_aligned(args, *sbno, *slen, sbnoa, slena); /* * The good extent is closer than this one. */ if (!dir) { - if (bno >= args->agbno + gdiff) + if (*sbnoa >= args->agbno + gdiff) goto out_use_good; } else { - if (bno <= args->agbno - gdiff) + if (*sbnoa <= args->agbno - gdiff) goto out_use_good; } @@ -693,8 +787,9 @@ xfs_alloc_fix_len(args); sdiff = xfs_alloc_compute_diff(args->agbno, args->len, - args->alignment, *sbno, - *slen, &new); + args->alignment, + args->userdata, *sbnoa, + *slena, &new); /* * Choose closer size and invalidate other cursor. @@ -744,7 +839,7 @@ xfs_agblock_t gtbnoa; /* aligned ... */ xfs_extlen_t gtdiff; /* difference to right side entry */ xfs_extlen_t gtlen; /* length of right side entry */ - xfs_extlen_t gtlena = 0; /* aligned ... */ + xfs_extlen_t gtlena; /* aligned ... */ xfs_agblock_t gtnew; /* useful start bno of right side */ int error; /* error code */ int i; /* result code, temporary */ @@ -753,24 +848,32 @@ xfs_agblock_t ltbnoa; /* aligned ... */ xfs_extlen_t ltdiff; /* difference to left side entry */ xfs_extlen_t ltlen; /* length of left side entry */ - xfs_extlen_t ltlena = 0; /* aligned ... */ + xfs_extlen_t ltlena; /* aligned ... */ xfs_agblock_t ltnew; /* useful start bno of left side */ xfs_extlen_t rlen; /* length of returned extent */ -#if defined(DEBUG) && defined(__KERNEL__) + int forced = 0; +#ifdef DEBUG /* * Randomly don't execute the first algorithm. */ int dofirst; /* set to do first algorithm */ - dofirst = random32() & 1; + dofirst = prandom_u32() & 1; #endif + +restart: + bno_cur_lt = NULL; + bno_cur_gt = NULL; + ltlen = 0; + gtlena = 0; + ltlena = 0; + /* * Get a cursor for the by-size btree. */ cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, args->agno, XFS_BTNUM_CNT); - ltlen = 0; - bno_cur_lt = bno_cur_gt = NULL; + /* * See if there are any free extents as big as maxlen. */ @@ -786,11 +889,13 @@ goto error0; if (i == 0 || ltlen == 0) { xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); + trace_xfs_alloc_near_noentry(args); return 0; } ASSERT(i == 1); } args->wasfromfl = 0; + /* * First algorithm. * If the requested extent is large wrt the freespaces available @@ -807,8 +912,8 @@ xfs_extlen_t blen=0; xfs_agblock_t bnew=0; -#if defined(DEBUG) && defined(__KERNEL__) - if (!dofirst) +#ifdef DEBUG + if (dofirst) break; #endif /* @@ -844,8 +949,8 @@ if ((error = xfs_alloc_get_rec(cnt_cur, <bno, <len, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); - xfs_alloc_compute_aligned(ltbno, ltlen, args->alignment, - args->minlen, <bnoa, <lena); + xfs_alloc_compute_aligned(args, ltbno, ltlen, + <bnoa, <lena); if (ltlena < args->minlen) continue; args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); @@ -854,7 +959,8 @@ if (args->len < blen) continue; ltdiff = xfs_alloc_compute_diff(args->agbno, args->len, - args->alignment, ltbno, ltlen, <new); + args->alignment, args->userdata, ltbnoa, + ltlena, <new); if (ltnew != NULLAGBLOCK && (args->len > blen || ltdiff < bdiff)) { bdiff = ltdiff; @@ -965,8 +1071,8 @@ if ((error = xfs_alloc_get_rec(bno_cur_lt, <bno, <len, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); - xfs_alloc_compute_aligned(ltbno, ltlen, args->alignment, - args->minlen, <bnoa, <lena); + xfs_alloc_compute_aligned(args, ltbno, ltlen, + <bnoa, <lena); if (ltlena >= args->minlen) break; if ((error = xfs_btree_decrement(bno_cur_lt, 0, &i))) @@ -981,8 +1087,8 @@ if ((error = xfs_alloc_get_rec(bno_cur_gt, >bno, >len, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); - xfs_alloc_compute_aligned(gtbno, gtlen, args->alignment, - args->minlen, >bnoa, >lena); + xfs_alloc_compute_aligned(args, gtbno, gtlen, + >bnoa, >lena); if (gtlena >= args->minlen) break; if ((error = xfs_btree_increment(bno_cur_gt, 0, &i))) @@ -1005,13 +1111,14 @@ */ args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); xfs_alloc_fix_len(args); - rlen = args->len; ltdiff = xfs_alloc_compute_diff(args->agbno, args->len, - args->alignment, ltbno, ltlen, <new); + args->alignment, args->userdata, ltbnoa, + ltlena, <new); error = xfs_alloc_find_best_extent(args, &bno_cur_lt, &bno_cur_gt, - ltdiff, >bno, >len, >lena, + ltdiff, >bno, >len, + >bnoa, >lena, 0 /* search right */); } else { ASSERT(gtlena >= args->minlen); @@ -1022,11 +1129,13 @@ args->len = XFS_EXTLEN_MIN(gtlena, args->maxlen); xfs_alloc_fix_len(args); gtdiff = xfs_alloc_compute_diff(args->agbno, args->len, - args->alignment, gtbno, gtlen, >new); + args->alignment, args->userdata, gtbnoa, + gtlena, >new); error = xfs_alloc_find_best_extent(args, &bno_cur_gt, &bno_cur_lt, - gtdiff, <bno, <len, <lena, + gtdiff, <bno, <len, + <bnoa, <lena, 1 /* search left */); } @@ -1038,6 +1147,13 @@ * If we couldn't get anything, give up. */ if (bno_cur_lt == NULL && bno_cur_gt == NULL) { + xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); + + if (!forced++) { + trace_xfs_alloc_near_busy(args); + xfs_log_force(args->mp, XFS_LOG_SYNC); + goto restart; + } trace_xfs_alloc_size_neither(args); args->agbno = NULLAGBLOCK; return 0; @@ -1072,12 +1188,13 @@ return 0; } rlen = args->len; - (void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment, ltbno, - ltlen, <new); + (void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment, + args->userdata, ltbnoa, ltlena, <new); ASSERT(ltnew >= ltbno); - ASSERT(ltnew + rlen <= ltbno + ltlen); + ASSERT(ltnew + rlen <= ltbnoa + ltlena); ASSERT(ltnew + rlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); args->agbno = ltnew; + if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno, ltlen, ltnew, rlen, XFSA_FIXUP_BNO_OK))) goto error0; @@ -1120,26 +1237,35 @@ int i; /* temp status variable */ xfs_agblock_t rbno; /* returned block number */ xfs_extlen_t rlen; /* length of returned extent */ + int forced = 0; +restart: /* * Allocate and initialize a cursor for the by-size btree. */ cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, args->agno, XFS_BTNUM_CNT); bno_cur = NULL; + /* * Look for an entry >= maxlen+alignment-1 blocks. */ if ((error = xfs_alloc_lookup_ge(cnt_cur, 0, args->maxlen + args->alignment - 1, &i))) goto error0; + /* - * If none, then pick up the last entry in the tree unless the - * tree is empty. - */ - if (!i) { - if ((error = xfs_alloc_ag_vextent_small(args, cnt_cur, &fbno, - &flen, &i))) + * If none or we have busy extents that we cannot allocate from, then + * we have to settle for a smaller extent. In the case that there are + * no large extents, this will return the last entry in the tree unless + * the tree is empty. In the case that there are only busy large + * extents, this will return the largest small extent unless there + * are no smaller extents available. + */ + if (!i || forced > 1) { + error = xfs_alloc_ag_vextent_small(args, cnt_cur, + &fbno, &flen, &i); + if (error) goto error0; if (i == 0 || flen == 0) { xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); @@ -1147,23 +1273,56 @@ return 0; } ASSERT(i == 1); + xfs_alloc_compute_aligned(args, fbno, flen, &rbno, &rlen); + } else { + /* + * Search for a non-busy extent that is large enough. + * If we are at low space, don't check, or if we fall of + * the end of the btree, turn off the busy check and + * restart. + */ + for (;;) { + error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, &i); + if (error) + goto error0; + XFS_WANT_CORRUPTED_GOTO(i == 1, error0); + + xfs_alloc_compute_aligned(args, fbno, flen, + &rbno, &rlen); + + if (rlen >= args->maxlen) + break; + + error = xfs_btree_increment(cnt_cur, 0, &i); + if (error) + goto error0; + if (i == 0) { + /* + * Our only valid extents must have been busy. + * Make it unbusy by forcing the log out and + * retrying. If we've been here before, forcing + * the log isn't making the extents available, + * which means they have probably been freed in + * this transaction. In that case, we have to + * give up on them and we'll attempt a minlen + * allocation the next time around. + */ + xfs_btree_del_cursor(cnt_cur, + XFS_BTREE_NOERROR); + trace_xfs_alloc_size_busy(args); + if (!forced++) + xfs_log_force(args->mp, XFS_LOG_SYNC); + goto restart; + } + } } - /* - * There's a freespace as big as maxlen+alignment-1, get it. - */ - else { - if ((error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, &i))) - goto error0; - XFS_WANT_CORRUPTED_GOTO(i == 1, error0); - } + /* * In the first case above, we got the last entry in the * by-size btree. Now we check to see if the space hits maxlen * once aligned; if not, we search left for something better. * This can't happen in the second case above. */ - xfs_alloc_compute_aligned(fbno, flen, args->alignment, args->minlen, - &rbno, &rlen); rlen = XFS_EXTLEN_MIN(args->maxlen, rlen); XFS_WANT_CORRUPTED_GOTO(rlen == 0 || (rlen <= flen && rbno + rlen <= fbno + flen), error0); @@ -1188,8 +1347,8 @@ XFS_WANT_CORRUPTED_GOTO(i == 1, error0); if (flen < bestrlen) break; - xfs_alloc_compute_aligned(fbno, flen, args->alignment, - args->minlen, &rbno, &rlen); + xfs_alloc_compute_aligned(args, fbno, flen, + &rbno, &rlen); rlen = XFS_EXTLEN_MIN(args->maxlen, rlen); XFS_WANT_CORRUPTED_GOTO(rlen == 0 || (rlen <= flen && rbno + rlen <= fbno + flen), @@ -1217,13 +1376,19 @@ * Fix up the length. */ args->len = rlen; - xfs_alloc_fix_len(args); - if (rlen < args->minlen || !xfs_alloc_fix_minleft(args)) { - xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); - trace_xfs_alloc_size_nominleft(args); - args->agbno = NULLAGBLOCK; - return 0; + if (rlen < args->minlen) { + if (!forced++) { + xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); + trace_xfs_alloc_size_busy(args); + xfs_log_force(args->mp, XFS_LOG_SYNC); + goto restart; + } + goto out_nominleft; } + xfs_alloc_fix_len(args); + + if (!xfs_alloc_fix_minleft(args)) + goto out_nominleft; rlen = args->len; XFS_WANT_CORRUPTED_GOTO(rlen <= flen, error0); /* @@ -1253,6 +1418,12 @@ if (bno_cur) xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR); return error; + +out_nominleft: + xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); + trace_xfs_alloc_size_nominleft(args); + args->agbno = NULLAGBLOCK; + return 0; } /* @@ -1292,6 +1463,9 @@ if (error) goto error0; if (fbno != NULLAGBLOCK) { + xfs_extent_busy_reuse(args->mp, args->agno, fbno, 1, + args->userdata); + if (args->userdata) { xfs_buf_t *bp; @@ -1367,6 +1541,7 @@ xfs_mount_t *mp; /* mount point struct for filesystem */ xfs_agblock_t nbno; /* new starting block of freespace */ xfs_extlen_t nlen; /* new length of freespace */ + xfs_perag_t *pag; /* per allocation group data */ mp = tp->t_mountp; /* @@ -1565,45 +1740,23 @@ XFS_WANT_CORRUPTED_GOTO(i == 1, error0); xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); cnt_cur = NULL; + /* * Update the freespace totals in the ag and superblock. */ - { - xfs_agf_t *agf; - xfs_perag_t *pag; /* per allocation group data */ - - pag = xfs_perag_get(mp, agno); - pag->pagf_freeblks += len; - xfs_perag_put(pag); - - agf = XFS_BUF_TO_AGF(agbp); - be32_add_cpu(&agf->agf_freeblks, len); - xfs_trans_agblocks_delta(tp, len); - XFS_WANT_CORRUPTED_GOTO( - be32_to_cpu(agf->agf_freeblks) <= - be32_to_cpu(agf->agf_length), - error0); - xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS); - if (!isfl) - xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (long)len); - XFS_STATS_INC(xs_freex); - XFS_STATS_ADD(xs_freeb, len); - } + pag = xfs_perag_get(mp, agno); + error = xfs_alloc_update_counters(tp, pag, agbp, len); + xfs_perag_put(pag); + if (error) + goto error0; + + if (!isfl) + xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (long)len); + XFS_STATS_INC(xs_freex); + XFS_STATS_ADD(xs_freeb, len); trace_xfs_free_extent(mp, agno, bno, len, isfl, haveleft, haveright); - /* - * Since blocks move to the free list without the coordination - * used in xfs_bmap_finish, we can't allow block to be available - * for reallocation and non-transaction writing (user data) - * until we know that the transaction that moved it to the free - * list is permanently on disk. We track the blocks by declaring - * these blocks as "busy"; the busy list is maintained on a per-ag - * basis and each transaction records which entries should be removed - * when the iclog commits to disk. If a busy block is allocated, - * the iclog is pushed up to the LSN that freed the block. - */ - xfs_alloc_busy_insert(tp, agno, bno, len); return 0; error0: @@ -1788,12 +1941,11 @@ /* * Initialize the args structure. */ + memset(&targs, 0, sizeof(targs)); targs.tp = tp; targs.mp = mp; targs.agbp = agbp; targs.agno = args->agno; - targs.mod = targs.minleft = targs.wasdel = targs.userdata = - targs.minalignslop = 0; targs.alignment = targs.minlen = targs.prod = targs.isfl = 1; targs.type = XFS_ALLOCTYPE_THIS_AG; targs.pag = pag; @@ -1851,18 +2003,18 @@ int btreeblk) /* destination is a AGF btree */ { xfs_agf_t *agf; /* a.g. freespace structure */ - xfs_agfl_t *agfl; /* a.g. freelist structure */ xfs_buf_t *agflbp;/* buffer for a.g. freelist structure */ xfs_agblock_t bno; /* block number returned */ + __be32 *agfl_bno; int error; int logflags; - xfs_mount_t *mp; /* mount structure */ + xfs_mount_t *mp = tp->t_mountp; xfs_perag_t *pag; /* per allocation group data */ - agf = XFS_BUF_TO_AGF(agbp); /* * Freelist is empty, give up. */ + agf = XFS_BUF_TO_AGF(agbp); if (!agf->agf_flcount) { *bnop = NULLAGBLOCK; return 0; @@ -1870,15 +2022,17 @@ /* * Read the array of free blocks. */ - mp = tp->t_mountp; - if ((error = xfs_alloc_read_agfl(mp, tp, - be32_to_cpu(agf->agf_seqno), &agflbp))) + error = xfs_alloc_read_agfl(mp, tp, be32_to_cpu(agf->agf_seqno), + &agflbp); + if (error) return error; - agfl = XFS_BUF_TO_AGFL(agflbp); + + /* * Get the block number and update the data structures. */ - bno = be32_to_cpu(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)]); + agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp); + bno = be32_to_cpu(agfl_bno[be32_to_cpu(agf->agf_flfirst)]); be32_add_cpu(&agf->agf_flfirst, 1); xfs_trans_brelse(tp, agflbp); if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp)) @@ -1900,21 +2054,6 @@ xfs_alloc_log_agf(tp, agbp, logflags); *bnop = bno; - /* - * As blocks are freed, they are added to the per-ag busy list and - * remain there until the freeing transaction is committed to disk. - * Now that we have allocated blocks, this list must be searched to see - * if a block is being reused. If one is, then the freeing transaction - * must be pushed to disk before this transaction. - * - * We do this by setting the current transaction to a sync transaction - * which guarantees that the freeing transaction is on disk before this - * transaction. This is done instead of a synchronous log force here so - * that we don't sit and wait with the AGF locked in the transaction - * during the log force. - */ - if (xfs_alloc_busy_search(mp, be32_to_cpu(agf->agf_seqno), bno, 1)) - xfs_trans_set_sync(tp); return 0; } @@ -1942,11 +2081,14 @@ offsetof(xfs_agf_t, agf_freeblks), offsetof(xfs_agf_t, agf_longest), offsetof(xfs_agf_t, agf_btreeblks), + offsetof(xfs_agf_t, agf_uuid), sizeof(xfs_agf_t) }; trace_xfs_agf(tp->t_mountp, XFS_BUF_TO_AGF(bp), fields, _RET_IP_); + xfs_trans_buf_set_type(tp, bp, XFS_BLFT_AGF_BUF); + xfs_btree_offsets(fields, offsets, XFS_AGF_NUM_BITS, &first, &last); xfs_trans_log_buf(tp, bp, (uint)first, (uint)last); } @@ -1983,12 +2125,13 @@ int btreeblk) /* block came from a AGF btree */ { xfs_agf_t *agf; /* a.g. freespace structure */ - xfs_agfl_t *agfl; /* a.g. free block array */ __be32 *blockp;/* pointer to array entry */ int error; int logflags; xfs_mount_t *mp; /* mount structure */ xfs_perag_t *pag; /* per allocation group data */ + __be32 *agfl_bno; + int startoff; agf = XFS_BUF_TO_AGF(agbp); mp = tp->t_mountp; @@ -1996,7 +2139,6 @@ if (!agflbp && (error = xfs_alloc_read_agfl(mp, tp, be32_to_cpu(agf->agf_seqno), &agflbp))) return error; - agfl = XFS_BUF_TO_AGFL(agflbp); be32_add_cpu(&agf->agf_fllast, 1); if (be32_to_cpu(agf->agf_fllast) == XFS_AGFL_SIZE(mp)) agf->agf_fllast = 0; @@ -2017,16 +2159,101 @@ xfs_alloc_log_agf(tp, agbp, logflags); ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)); - blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)]; + + agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp); + blockp = &agfl_bno[be32_to_cpu(agf->agf_fllast)]; *blockp = cpu_to_be32(bno); + startoff = (char *)blockp - (char *)agflbp->b_addr; + xfs_alloc_log_agf(tp, agbp, logflags); - xfs_trans_log_buf(tp, agflbp, - (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl), - (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl + - sizeof(xfs_agblock_t) - 1)); + + xfs_trans_buf_set_type(tp, agflbp, XFS_BLFT_AGFL_BUF); + xfs_trans_log_buf(tp, agflbp, startoff, + startoff + sizeof(xfs_agblock_t) - 1); return 0; } +static bool +xfs_agf_verify( + struct xfs_mount *mp, + struct xfs_buf *bp) + { + struct xfs_agf *agf = XFS_BUF_TO_AGF(bp); + + if (xfs_sb_version_hascrc(&mp->m_sb) && + !uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_uuid)) + return false; + + if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) && + XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) && + be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) && + be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) && + be32_to_cpu(agf->agf_fllast) < XFS_AGFL_SIZE(mp) && + be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp))) + return false; + + /* + * during growfs operations, the perag is not fully initialised, + * so we can't use it for any useful checking. growfs ensures we can't + * use it by using uncached buffers that don't have the perag attached + * so we can detect and avoid this problem. + */ + if (bp->b_pag && be32_to_cpu(agf->agf_seqno) != bp->b_pag->pag_agno) + return false; + + if (xfs_sb_version_haslazysbcount(&mp->m_sb) && + be32_to_cpu(agf->agf_btreeblks) > be32_to_cpu(agf->agf_length)) + return false; + + return true;; + +} + +static void +xfs_agf_read_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + + if (xfs_sb_version_hascrc(&mp->m_sb) && + !xfs_buf_verify_cksum(bp, XFS_AGF_CRC_OFF)) + xfs_buf_ioerror(bp, EFSBADCRC); + else if (XFS_TEST_ERROR(!xfs_agf_verify(mp, bp), mp, + XFS_ERRTAG_ALLOC_READ_AGF, + XFS_RANDOM_ALLOC_READ_AGF)) + xfs_buf_ioerror(bp, EFSCORRUPTED); + + if (bp->b_error) + xfs_verifier_error(bp); +} + +static void +xfs_agf_write_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_buf_log_item *bip = bp->b_fspriv; + + if (!xfs_agf_verify(mp, bp)) { + xfs_buf_ioerror(bp, EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return; + + if (bip) + XFS_BUF_TO_AGF(bp)->agf_lsn = cpu_to_be64(bip->bli_item.li_lsn); + + xfs_buf_update_cksum(bp, XFS_AGF_CRC_OFF); +} + +const struct xfs_buf_ops xfs_agf_buf_ops = { + .verify_read = xfs_agf_read_verify, + .verify_write = xfs_agf_write_verify, +}; + /* * Read in the allocation group header (free/alloc section). */ @@ -2038,45 +2265,20 @@ int flags, /* XFS_BUF_ */ struct xfs_buf **bpp) /* buffer for the ag freelist header */ { - struct xfs_agf *agf; /* ag freelist header */ - int agf_ok; /* set if agf is consistent */ int error; ASSERT(agno != NULLAGNUMBER); error = xfs_trans_read_buf( mp, tp, mp->m_ddev_targp, XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), - XFS_FSS_TO_BB(mp, 1), flags, bpp); + XFS_FSS_TO_BB(mp, 1), flags, bpp, &xfs_agf_buf_ops); if (error) return error; if (!*bpp) return 0; - ASSERT(!XFS_BUF_GETERROR(*bpp)); - agf = XFS_BUF_TO_AGF(*bpp); - - /* - * Validate the magic number of the agf block. - */ - agf_ok = - be32_to_cpu(agf->agf_magicnum) == XFS_AGF_MAGIC && - XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) && - be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) && - be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) && - be32_to_cpu(agf->agf_fllast) < XFS_AGFL_SIZE(mp) && - be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp) && - be32_to_cpu(agf->agf_seqno) == agno; - if (xfs_sb_version_haslazysbcount(&mp->m_sb)) - agf_ok = agf_ok && be32_to_cpu(agf->agf_btreeblks) <= - be32_to_cpu(agf->agf_length); - if (unlikely(XFS_TEST_ERROR(!agf_ok, mp, XFS_ERRTAG_ALLOC_READ_AGF, - XFS_RANDOM_ALLOC_READ_AGF))) { - XFS_CORRUPTION_ERROR("xfs_alloc_read_agf", - XFS_ERRLEVEL_LOW, mp, agf); - xfs_trans_brelse(tp, *bpp); - return XFS_ERROR(EFSCORRUPTED); - } - XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_AGF, XFS_AGF_REF); + ASSERT(!(*bpp)->b_error); + xfs_buf_set_ref(*bpp, XFS_AGF_REF); return 0; } @@ -2104,7 +2306,7 @@ return error; if (!*bpp) return 0; - ASSERT(!XFS_BUF_GETERROR(*bpp)); + ASSERT(!(*bpp)->b_error); agf = XFS_BUF_TO_AGF(*bpp); pag = xfs_perag_get(mp, agno); @@ -2371,18 +2573,36 @@ memset(&args, 0, sizeof(xfs_alloc_arg_t)); args.tp = tp; args.mp = tp->t_mountp; + + /* + * validate that the block number is legal - the enables us to detect + * and handle a silent filesystem corruption rather than crashing. + */ args.agno = XFS_FSB_TO_AGNO(args.mp, bno); - ASSERT(args.agno < args.mp->m_sb.sb_agcount); + if (args.agno >= args.mp->m_sb.sb_agcount) + return EFSCORRUPTED; + args.agbno = XFS_FSB_TO_AGBNO(args.mp, bno); + if (args.agbno >= args.mp->m_sb.sb_agblocks) + return EFSCORRUPTED; + args.pag = xfs_perag_get(args.mp, args.agno); - if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING))) + ASSERT(args.pag); + + error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING); + if (error) goto error0; -#ifdef DEBUG - ASSERT(args.agbp != NULL); - ASSERT((args.agbno + len) <= - be32_to_cpu(XFS_BUF_TO_AGF(args.agbp)->agf_length)); -#endif + + /* validate the extent size is legal now we have the agf locked */ + if (args.agbno + len > + be32_to_cpu(XFS_BUF_TO_AGF(args.agbp)->agf_length)) { + error = EFSCORRUPTED; + goto error0; + } + error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); + if (!error) + xfs_extent_busy_insert(tp, args.agno, args.agbno, len, 0); error0: xfs_perag_put(args.pag); return error; diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_attr.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_attr.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_attr.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_attr.c 2013-10-10 21:07:17.000000000 +0000 @@ -49,13 +49,6 @@ STATIC int xfs_attr_fillstate(xfs_da_state_t *state); STATIC int xfs_attr_refillstate(xfs_da_state_t *state); -/* - * Routines to manipulate out-of-line attribute values. - */ -STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args); -STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args); - -#define ATTR_RMTVALUE_MAPSIZE 1 /* # of map entries at once */ STATIC int xfs_attr_name_to_xname( @@ -72,7 +65,7 @@ return 0; } -STATIC int +int xfs_inode_hasattr( struct xfs_inode *ip) { @@ -209,13 +202,14 @@ int valuelen, int flags) { - xfs_da_args_t args; - xfs_fsblock_t firstblock; - xfs_bmap_free_t flist; - int error, err2, committed; - xfs_mount_t *mp = dp->i_mount; - int rsvd = (flags & ATTR_ROOT) != 0; - int local; + xfs_da_args_t args; + xfs_fsblock_t firstblock; + xfs_bmap_free_t flist; + int error, err2, committed; + struct xfs_mount *mp = dp->i_mount; + struct xfs_trans_res tres; + int rsvd = (flags & ATTR_ROOT) != 0; + int local; /* * Attach the dquots to the inode. @@ -275,9 +269,12 @@ if (rsvd) args.trans->t_flags |= XFS_TRANS_RESERVE; - if ((error = xfs_trans_reserve(args.trans, args.total, - XFS_ATTRSET_LOG_RES(mp, args.total), 0, - XFS_TRANS_PERM_LOG_RES, XFS_ATTRSET_LOG_COUNT))) { + tres.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres + + M_RES(mp)->tr_attrsetrt.tr_logres * args.total; + tres.tr_logcount = XFS_ATTRSET_LOG_COUNT; + tres.tr_logflags = XFS_TRANS_PERM_LOG_RES; + error = xfs_trans_reserve(args.trans, &tres, args.total, 0); + if (error) { xfs_trans_cancel(args.trans, 0); return(error); } @@ -292,8 +289,7 @@ return (error); } - xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL); - xfs_trans_ihold(args.trans, dp); + xfs_trans_ijoin(args.trans, dp, 0); /* * If the attribute list is non-existent or a shortform list, @@ -362,10 +358,8 @@ * bmap_finish() may have committed the last trans and started * a new one. We need the inode to be in all transactions. */ - if (committed) { - xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL); - xfs_trans_ihold(args.trans, dp); - } + if (committed) + xfs_trans_ijoin(args.trans, dp, 0); /* * Commit the leaf transformation. We'll need another (linked) @@ -466,6 +460,13 @@ args.whichfork = XFS_ATTR_FORK; /* + * we have no control over the attribute names that userspace passes us + * to remove, so we have to allow the name lookup prior to attribute + * removal to fail. + */ + args.op_flags = XFS_DA_OP_OKNOENT; + + /* * Attach the dquots to the inode. */ error = xfs_qm_dqattach(dp, 0); @@ -492,11 +493,9 @@ if (flags & ATTR_ROOT) args.trans->t_flags |= XFS_TRANS_RESERVE; - if ((error = xfs_trans_reserve(args.trans, - XFS_ATTRRM_SPACE_RES(mp), - XFS_ATTRRM_LOG_RES(mp), - 0, XFS_TRANS_PERM_LOG_RES, - XFS_ATTRRM_LOG_COUNT))) { + error = xfs_trans_reserve(args.trans, &M_RES(mp)->tr_attrrm, + XFS_ATTRRM_SPACE_RES(mp), 0); + if (error) { xfs_trans_cancel(args.trans, 0); return(error); } @@ -506,8 +505,7 @@ * No need to make quota reservations here. We expect to release some * blocks not allocate in the common case. */ - xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL); - xfs_trans_ihold(args.trans, dp); + xfs_trans_ijoin(args.trans, dp, 0); /* * Decide on what work routines to call based on the inode size. @@ -587,6 +585,7 @@ return xfs_attr_remove_int(dp, &xname, flags); } + /*======================================================================== * External routines when attribute list is inside the inode *========================================================================*/ @@ -600,6 +599,8 @@ { int newsize, forkoff, retval; + trace_xfs_attr_sf_addname(args); + retval = xfs_attr_shortform_lookup(args); if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) { return(retval); @@ -640,33 +641,36 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) { xfs_inode_t *dp; - xfs_dabuf_t *bp; + struct xfs_buf *bp; int retval, error, committed, forkoff; + trace_xfs_attr_leaf_addname(args); + /* * Read the (only) block in the attribute list in. */ dp = args->dp; args->blkno = 0; - error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, - XFS_ATTR_FORK); + error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp); if (error) - return(error); - ASSERT(bp != NULL); + return error; /* * Look up the given attribute in the leaf block. Figure out if * the given flags produce an error or call for an atomic rename. */ - retval = xfs_attr_leaf_lookup_int(bp, args); + retval = xfs_attr3_leaf_lookup_int(bp, args); if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) { - xfs_da_brelse(args->trans, bp); - return(retval); + xfs_trans_brelse(args->trans, bp); + return retval; } else if (retval == EEXIST) { if (args->flags & ATTR_CREATE) { /* pure create op */ - xfs_da_brelse(args->trans, bp); - return(retval); + xfs_trans_brelse(args->trans, bp); + return retval; } + + trace_xfs_attr_leaf_replace(args); + args->op_flags |= XFS_DA_OP_RENAME; /* an atomic rename */ args->blkno2 = args->blkno; /* set 2nd entry info*/ args->index2 = args->index; @@ -678,8 +682,7 @@ * Add the attribute to the leaf block, transitioning to a Btree * if required. */ - retval = xfs_attr_leaf_add(bp, args); - xfs_da_buf_done(bp); + retval = xfs_attr3_leaf_add(bp, args); if (retval == ENOSPC) { /* * Promote the attribute list to the Btree format, then @@ -687,7 +690,7 @@ * can manage its own transactions. */ xfs_bmap_init(args->flist, args->firstblock); - error = xfs_attr_leaf_to_node(args); + error = xfs_attr3_leaf_to_node(args); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, &committed); @@ -703,10 +706,8 @@ * bmap_finish() may have committed the last trans and started * a new one. We need the inode to be in all transactions. */ - if (committed) { - xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); - xfs_trans_ihold(args->trans, dp); - } + if (committed) + xfs_trans_ijoin(args->trans, dp, 0); /* * Commit the current trans (including the inode) and start @@ -754,7 +755,7 @@ * In a separate transaction, set the incomplete flag on the * "old" attr and clear the incomplete flag on the "new" attr. */ - error = xfs_attr_leaf_flipflags(args); + error = xfs_attr3_leaf_flipflags(args); if (error) return(error); @@ -776,19 +777,19 @@ * Read in the block containing the "old" attr, then * remove the "old" attr from that block (neat, huh!) */ - error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, - &bp, XFS_ATTR_FORK); + error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, + -1, &bp); if (error) - return(error); - ASSERT(bp != NULL); - (void)xfs_attr_leaf_remove(bp, args); + return error; + + xfs_attr3_leaf_remove(bp, args); /* * If the result is small enough, shrink it all into the inode. */ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { xfs_bmap_init(args->flist, args->firstblock); - error = xfs_attr_leaf_to_shortform(bp, args, forkoff); + error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (!error) { error = xfs_bmap_finish(&args->trans, @@ -807,12 +808,9 @@ * and started a new one. We need the inode to be * in all transactions. */ - if (committed) { - xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); - xfs_trans_ihold(args->trans, dp); - } - } else - xfs_da_buf_done(bp); + if (committed) + xfs_trans_ijoin(args->trans, dp, 0); + } /* * Commit the remove and start the next trans in series. @@ -823,9 +821,9 @@ /* * Added a "remote" value, just clear the incomplete flag. */ - error = xfs_attr_leaf_clearflag(args); + error = xfs_attr3_leaf_clearflag(args); } - return(error); + return error; } /* @@ -838,35 +836,34 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) { xfs_inode_t *dp; - xfs_dabuf_t *bp; + struct xfs_buf *bp; int error, committed, forkoff; + trace_xfs_attr_leaf_removename(args); + /* * Remove the attribute. */ dp = args->dp; args->blkno = 0; - error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, - XFS_ATTR_FORK); - if (error) { - return(error); - } + error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp); + if (error) + return error; - ASSERT(bp != NULL); - error = xfs_attr_leaf_lookup_int(bp, args); + error = xfs_attr3_leaf_lookup_int(bp, args); if (error == ENOATTR) { - xfs_da_brelse(args->trans, bp); - return(error); + xfs_trans_brelse(args->trans, bp); + return error; } - (void)xfs_attr_leaf_remove(bp, args); + xfs_attr3_leaf_remove(bp, args); /* * If the result is small enough, shrink it all into the inode. */ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { xfs_bmap_init(args->flist, args->firstblock); - error = xfs_attr_leaf_to_shortform(bp, args, forkoff); + error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, @@ -876,20 +873,17 @@ ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); - return(error); + return error; } /* * bmap_finish() may have committed the last trans and started * a new one. We need the inode to be in all transactions. */ - if (committed) { - xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); - xfs_trans_ihold(args->trans, dp); - } - } else - xfs_da_buf_done(bp); - return(0); + if (committed) + xfs_trans_ijoin(args->trans, dp, 0); + } + return 0; } /* @@ -901,27 +895,27 @@ STATIC int xfs_attr_leaf_get(xfs_da_args_t *args) { - xfs_dabuf_t *bp; + struct xfs_buf *bp; int error; + trace_xfs_attr_leaf_get(args); + args->blkno = 0; - error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, - XFS_ATTR_FORK); + error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp); if (error) - return(error); - ASSERT(bp != NULL); + return error; - error = xfs_attr_leaf_lookup_int(bp, args); + error = xfs_attr3_leaf_lookup_int(bp, args); if (error != EEXIST) { - xfs_da_brelse(args->trans, bp); - return(error); + xfs_trans_brelse(args->trans, bp); + return error; } - error = xfs_attr_leaf_getvalue(bp, args); - xfs_da_brelse(args->trans, bp); + error = xfs_attr3_leaf_getvalue(bp, args); + xfs_trans_brelse(args->trans, bp); if (!error && (args->rmtblkno > 0) && !(args->flags & ATTR_KERNOVAL)) { error = xfs_attr_rmtval_get(args); } - return(error); + return error; } /*======================================================================== @@ -947,6 +941,8 @@ xfs_mount_t *mp; int committed, retval, error; + trace_xfs_attr_node_addname(args); + /* * Fill in bucket of arguments/results/context to carry around. */ @@ -963,7 +959,7 @@ * Search to see if name already exists, and get back a pointer * to where it should go. */ - error = xfs_da_node_lookup_int(state, &retval); + error = xfs_da3_node_lookup_int(state, &retval); if (error) goto out; blk = &state->path.blk[ state->path.active-1 ]; @@ -973,6 +969,9 @@ } else if (retval == EEXIST) { if (args->flags & ATTR_CREATE) goto out; + + trace_xfs_attr_node_replace(args); + args->op_flags |= XFS_DA_OP_RENAME; /* atomic rename op */ args->blkno2 = args->blkno; /* set 2nd entry info*/ args->index2 = args->index; @@ -982,7 +981,7 @@ args->rmtblkcnt = 0; } - retval = xfs_attr_leaf_add(blk->bp, state->args); + retval = xfs_attr3_leaf_add(blk->bp, state->args); if (retval == ENOSPC) { if (state->path.active == 1) { /* @@ -991,8 +990,9 @@ * have been a b-tree. */ xfs_da_state_free(state); + state = NULL; xfs_bmap_init(args->flist, args->firstblock); - error = xfs_attr_leaf_to_node(args); + error = xfs_attr3_leaf_to_node(args); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, @@ -1010,10 +1010,8 @@ * and started a new one. We need the inode to be * in all transactions. */ - if (committed) { - xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); - xfs_trans_ihold(args->trans, dp); - } + if (committed) + xfs_trans_ijoin(args->trans, dp, 0); /* * Commit the node conversion and start the next @@ -1033,7 +1031,7 @@ * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields. */ xfs_bmap_init(args->flist, args->firstblock); - error = xfs_da_split(state); + error = xfs_da3_split(state); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, &committed); @@ -1049,15 +1047,13 @@ * bmap_finish() may have committed the last trans and started * a new one. We need the inode to be in all transactions. */ - if (committed) { - xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); - xfs_trans_ihold(args->trans, dp); - } + if (committed) + xfs_trans_ijoin(args->trans, dp, 0); } else { /* * Addition succeeded, update Btree hashvals. */ - xfs_da_fixhashpath(state, &state->path); + xfs_da3_fixhashpath(state, &state->path); } /* @@ -1098,7 +1094,7 @@ * In a separate transaction, set the incomplete flag on the * "old" attr and clear the incomplete flag on the "new" attr. */ - error = xfs_attr_leaf_flipflags(args); + error = xfs_attr3_leaf_flipflags(args); if (error) goto out; @@ -1128,7 +1124,7 @@ state->blocksize = state->mp->m_sb.sb_blocksize; state->node_ents = state->mp->m_attr_node_ents; state->inleaf = 0; - error = xfs_da_node_lookup_int(state, &retval); + error = xfs_da3_node_lookup_int(state, &retval); if (error) goto out; @@ -1137,15 +1133,15 @@ */ blk = &state->path.blk[ state->path.active-1 ]; ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC); - error = xfs_attr_leaf_remove(blk->bp, args); - xfs_da_fixhashpath(state, &state->path); + error = xfs_attr3_leaf_remove(blk->bp, args); + xfs_da3_fixhashpath(state, &state->path); /* * Check to see if the tree needs to be collapsed. */ if (retval && (state->path.active > 1)) { xfs_bmap_init(args->flist, args->firstblock); - error = xfs_da_join(state); + error = xfs_da3_join(state); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, @@ -1163,10 +1159,8 @@ * and started a new one. We need the inode to be * in all transactions. */ - if (committed) { - xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); - xfs_trans_ihold(args->trans, dp); - } + if (committed) + xfs_trans_ijoin(args->trans, dp, 0); } /* @@ -1180,7 +1174,7 @@ /* * Added a "remote" value, just clear the incomplete flag. */ - error = xfs_attr_leaf_clearflag(args); + error = xfs_attr3_leaf_clearflag(args); if (error) goto out; } @@ -1207,9 +1201,11 @@ xfs_da_state_t *state; xfs_da_state_blk_t *blk; xfs_inode_t *dp; - xfs_dabuf_t *bp; + struct xfs_buf *bp; int retval, error, committed, forkoff; + trace_xfs_attr_node_removename(args); + /* * Tie a string around our finger to remind us where we are. */ @@ -1223,7 +1219,7 @@ /* * Search to see if name exists, and get back a pointer to it. */ - error = xfs_da_node_lookup_int(state, &retval); + error = xfs_da3_node_lookup_int(state, &retval); if (error || (retval != EEXIST)) { if (error == 0) error = retval; @@ -1252,7 +1248,7 @@ * Mark the attribute as INCOMPLETE, then bunmapi() the * remote value. */ - error = xfs_attr_leaf_setflag(args); + error = xfs_attr3_leaf_setflag(args); if (error) goto out; error = xfs_attr_rmtval_remove(args); @@ -1273,15 +1269,15 @@ */ blk = &state->path.blk[ state->path.active-1 ]; ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC); - retval = xfs_attr_leaf_remove(blk->bp, args); - xfs_da_fixhashpath(state, &state->path); + retval = xfs_attr3_leaf_remove(blk->bp, args); + xfs_da3_fixhashpath(state, &state->path); /* * Check to see if the tree needs to be collapsed. */ if (retval && (state->path.active > 1)) { xfs_bmap_init(args->flist, args->firstblock); - error = xfs_da_join(state); + error = xfs_da3_join(state); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, &committed); @@ -1297,10 +1293,8 @@ * bmap_finish() may have committed the last trans and started * a new one. We need the inode to be in all transactions. */ - if (committed) { - xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); - xfs_trans_ihold(args->trans, dp); - } + if (committed) + xfs_trans_ijoin(args->trans, dp, 0); /* * Commit the Btree join operation and start a new trans. @@ -1319,20 +1313,15 @@ */ ASSERT(state->path.active == 1); ASSERT(state->path.blk[0].bp); - xfs_da_buf_done(state->path.blk[0].bp); state->path.blk[0].bp = NULL; - error = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, - XFS_ATTR_FORK); + error = xfs_attr3_leaf_read(args->trans, args->dp, 0, -1, &bp); if (error) goto out; - ASSERT(be16_to_cpu(((xfs_attr_leafblock_t *) - bp->data)->hdr.info.magic) - == XFS_ATTR_LEAF_MAGIC); if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { xfs_bmap_init(args->flist, args->firstblock); - error = xfs_attr_leaf_to_shortform(bp, args, forkoff); + error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (!error) { error = xfs_bmap_finish(&args->trans, @@ -1351,12 +1340,10 @@ * and started a new one. We need the inode to be * in all transactions. */ - if (committed) { - xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); - xfs_trans_ihold(args->trans, dp); - } + if (committed) + xfs_trans_ijoin(args->trans, dp, 0); } else - xfs_da_brelse(args->trans, bp); + xfs_trans_brelse(args->trans, bp); } error = 0; @@ -1378,6 +1365,8 @@ xfs_da_state_blk_t *blk; int level; + trace_xfs_attr_fillstate(state->args); + /* * Roll down the "path" in the state structure, storing the on-disk * block number for those buffers in the "path". @@ -1386,8 +1375,7 @@ ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); for (blk = path->blk, level = 0; level < path->active; blk++, level++) { if (blk->bp) { - blk->disk_blkno = xfs_da_blkno(blk->bp); - xfs_da_buf_done(blk->bp); + blk->disk_blkno = XFS_BUF_ADDR(blk->bp); blk->bp = NULL; } else { blk->disk_blkno = 0; @@ -1402,8 +1390,7 @@ ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); for (blk = path->blk, level = 0; level < path->active; blk++, level++) { if (blk->bp) { - blk->disk_blkno = xfs_da_blkno(blk->bp); - xfs_da_buf_done(blk->bp); + blk->disk_blkno = XFS_BUF_ADDR(blk->bp); blk->bp = NULL; } else { blk->disk_blkno = 0; @@ -1426,6 +1413,8 @@ xfs_da_state_blk_t *blk; int level, error; + trace_xfs_attr_refillstate(state->args); + /* * Roll down the "path" in the state structure, storing the on-disk * block number for those buffers in the "path". @@ -1434,7 +1423,7 @@ ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); for (blk = path->blk, level = 0; level < path->active; blk++, level++) { if (blk->disk_blkno) { - error = xfs_da_read_buf(state->args->trans, + error = xfs_da3_node_read(state->args->trans, state->args->dp, blk->blkno, blk->disk_blkno, &blk->bp, XFS_ATTR_FORK); @@ -1453,7 +1442,7 @@ ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); for (blk = path->blk, level = 0; level < path->active; blk++, level++) { if (blk->disk_blkno) { - error = xfs_da_read_buf(state->args->trans, + error = xfs_da3_node_read(state->args->trans, state->args->dp, blk->blkno, blk->disk_blkno, &blk->bp, XFS_ATTR_FORK); @@ -1482,6 +1471,8 @@ int error, retval; int i; + trace_xfs_attr_node_get(args); + state = xfs_da_state_alloc(); state->args = args; state->mp = args->dp->i_mount; @@ -1491,7 +1482,7 @@ /* * Search to see if name exists, and get back a pointer to it. */ - error = xfs_da_node_lookup_int(state, &retval); + error = xfs_da3_node_lookup_int(state, &retval); if (error) { retval = error; } else if (retval == EEXIST) { @@ -1502,7 +1493,7 @@ /* * Get the value, local or "remote" */ - retval = xfs_attr_leaf_getvalue(blk->bp, args); + retval = xfs_attr3_leaf_getvalue(blk->bp, args); if (!retval && (args->rmtblkno > 0) && !(args->flags & ATTR_KERNOVAL)) { retval = xfs_attr_rmtval_get(args); @@ -1513,306 +1504,10 @@ * If not in a transaction, we have to release all the buffers. */ for (i = 0; i < state->path.active; i++) { - xfs_da_brelse(args->trans, state->path.blk[i].bp); + xfs_trans_brelse(args->trans, state->path.blk[i].bp); state->path.blk[i].bp = NULL; } xfs_da_state_free(state); return(retval); } - -/*======================================================================== - * External routines for manipulating out-of-line attribute values. - *========================================================================*/ - -/* - * Read the value associated with an attribute from the out-of-line buffer - * that we stored it in. - */ -int -xfs_attr_rmtval_get(xfs_da_args_t *args) -{ - xfs_bmbt_irec_t map[ATTR_RMTVALUE_MAPSIZE]; - xfs_mount_t *mp; - xfs_daddr_t dblkno; - void *dst; - xfs_buf_t *bp; - int nmap, error, tmp, valuelen, blkcnt, i; - xfs_dablk_t lblkno; - - ASSERT(!(args->flags & ATTR_KERNOVAL)); - - mp = args->dp->i_mount; - dst = args->value; - valuelen = args->valuelen; - lblkno = args->rmtblkno; - while (valuelen > 0) { - nmap = ATTR_RMTVALUE_MAPSIZE; - error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno, - args->rmtblkcnt, - XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, - NULL, 0, map, &nmap, NULL); - if (error) - return(error); - ASSERT(nmap >= 1); - - for (i = 0; (i < nmap) && (valuelen > 0); i++) { - ASSERT((map[i].br_startblock != DELAYSTARTBLOCK) && - (map[i].br_startblock != HOLESTARTBLOCK)); - dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock); - blkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount); - error = xfs_read_buf(mp, mp->m_ddev_targp, dblkno, - blkcnt, XBF_LOCK | XBF_DONT_BLOCK, - &bp); - if (error) - return(error); - - tmp = (valuelen < XFS_BUF_SIZE(bp)) - ? valuelen : XFS_BUF_SIZE(bp); - xfs_buf_iomove(bp, 0, tmp, dst, XBRW_READ); - xfs_buf_relse(bp); - dst += tmp; - valuelen -= tmp; - - lblkno += map[i].br_blockcount; - } - } - ASSERT(valuelen == 0); - return(0); -} - -/* - * Write the value associated with an attribute into the out-of-line buffer - * that we have defined for it. - */ -STATIC int -xfs_attr_rmtval_set(xfs_da_args_t *args) -{ - xfs_mount_t *mp; - xfs_fileoff_t lfileoff; - xfs_inode_t *dp; - xfs_bmbt_irec_t map; - xfs_daddr_t dblkno; - void *src; - xfs_buf_t *bp; - xfs_dablk_t lblkno; - int blkcnt, valuelen, nmap, error, tmp, committed; - - dp = args->dp; - mp = dp->i_mount; - src = args->value; - - /* - * Find a "hole" in the attribute address space large enough for - * us to drop the new attribute's value into. - */ - blkcnt = XFS_B_TO_FSB(mp, args->valuelen); - lfileoff = 0; - error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff, - XFS_ATTR_FORK); - if (error) { - return(error); - } - args->rmtblkno = lblkno = (xfs_dablk_t)lfileoff; - args->rmtblkcnt = blkcnt; - - /* - * Roll through the "value", allocating blocks on disk as required. - */ - while (blkcnt > 0) { - /* - * Allocate a single extent, up to the size of the value. - */ - xfs_bmap_init(args->flist, args->firstblock); - nmap = 1; - error = xfs_bmapi(args->trans, dp, (xfs_fileoff_t)lblkno, - blkcnt, - XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA | - XFS_BMAPI_WRITE, - args->firstblock, args->total, &map, &nmap, - args->flist); - if (!error) { - error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } - if (error) { - ASSERT(committed); - args->trans = NULL; - xfs_bmap_cancel(args->flist); - return(error); - } - - /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) { - xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); - xfs_trans_ihold(args->trans, dp); - } - - ASSERT(nmap == 1); - ASSERT((map.br_startblock != DELAYSTARTBLOCK) && - (map.br_startblock != HOLESTARTBLOCK)); - lblkno += map.br_blockcount; - blkcnt -= map.br_blockcount; - - /* - * Start the next trans in the chain. - */ - error = xfs_trans_roll(&args->trans, dp); - if (error) - return (error); - } - - /* - * Roll through the "value", copying the attribute value to the - * already-allocated blocks. Blocks are written synchronously - * so that we can know they are all on disk before we turn off - * the INCOMPLETE flag. - */ - lblkno = args->rmtblkno; - valuelen = args->valuelen; - while (valuelen > 0) { - /* - * Try to remember where we decided to put the value. - */ - xfs_bmap_init(args->flist, args->firstblock); - nmap = 1; - error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno, - args->rmtblkcnt, - XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, - args->firstblock, 0, &map, &nmap, - NULL); - if (error) { - return(error); - } - ASSERT(nmap == 1); - ASSERT((map.br_startblock != DELAYSTARTBLOCK) && - (map.br_startblock != HOLESTARTBLOCK)); - - dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock), - blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); - - bp = xfs_buf_get(mp->m_ddev_targp, dblkno, blkcnt, - XBF_LOCK | XBF_DONT_BLOCK); - ASSERT(bp); - ASSERT(!XFS_BUF_GETERROR(bp)); - - tmp = (valuelen < XFS_BUF_SIZE(bp)) ? valuelen : - XFS_BUF_SIZE(bp); - xfs_buf_iomove(bp, 0, tmp, src, XBRW_WRITE); - if (tmp < XFS_BUF_SIZE(bp)) - xfs_buf_zero(bp, tmp, XFS_BUF_SIZE(bp) - tmp); - if ((error = xfs_bwrite(mp, bp))) {/* GROT: NOTE: synchronous write */ - return (error); - } - src += tmp; - valuelen -= tmp; - - lblkno += map.br_blockcount; - } - ASSERT(valuelen == 0); - return(0); -} - -/* - * Remove the value associated with an attribute by deleting the - * out-of-line buffer that it is stored on. - */ -STATIC int -xfs_attr_rmtval_remove(xfs_da_args_t *args) -{ - xfs_mount_t *mp; - xfs_bmbt_irec_t map; - xfs_buf_t *bp; - xfs_daddr_t dblkno; - xfs_dablk_t lblkno; - int valuelen, blkcnt, nmap, error, done, committed; - - mp = args->dp->i_mount; - - /* - * Roll through the "value", invalidating the attribute value's - * blocks. - */ - lblkno = args->rmtblkno; - valuelen = args->rmtblkcnt; - while (valuelen > 0) { - /* - * Try to remember where we decided to put the value. - */ - xfs_bmap_init(args->flist, args->firstblock); - nmap = 1; - error = xfs_bmapi(NULL, args->dp, (xfs_fileoff_t)lblkno, - args->rmtblkcnt, - XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, - args->firstblock, 0, &map, &nmap, - args->flist); - if (error) { - return(error); - } - ASSERT(nmap == 1); - ASSERT((map.br_startblock != DELAYSTARTBLOCK) && - (map.br_startblock != HOLESTARTBLOCK)); - - dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock), - blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); - - /* - * If the "remote" value is in the cache, remove it. - */ - bp = xfs_incore(mp->m_ddev_targp, dblkno, blkcnt, XBF_TRYLOCK); - if (bp) { - XFS_BUF_STALE(bp); - XFS_BUF_UNDELAYWRITE(bp); - xfs_buf_relse(bp); - bp = NULL; - } - - valuelen -= map.br_blockcount; - - lblkno += map.br_blockcount; - } - - /* - * Keep de-allocating extents until the remote-value region is gone. - */ - lblkno = args->rmtblkno; - blkcnt = args->rmtblkcnt; - done = 0; - while (!done) { - xfs_bmap_init(args->flist, args->firstblock); - error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, - XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, - 1, args->firstblock, args->flist, - &done); - if (!error) { - error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } - if (error) { - ASSERT(committed); - args->trans = NULL; - xfs_bmap_cancel(args->flist); - return(error); - } - - /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) { - xfs_trans_ijoin(args->trans, args->dp, XFS_ILOCK_EXCL); - xfs_trans_ihold(args->trans, args->dp); - } - - /* - * Close out trans and start the next one in the chain. - */ - error = xfs_trans_roll(&args->trans, args->dp); - if (error) - return (error); - } - return(0); -} diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_attr_leaf.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_attr_leaf.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_attr_leaf.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_attr_leaf.c 2014-05-02 00:09:16.000000000 +0000 @@ -1,5 +1,6 @@ /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * Copyright (c) 2013 Red Hat, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -31,31 +32,219 @@ /* * Routines used for growing the Btree. */ -STATIC int xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t which_block, - xfs_dabuf_t **bpp); -STATIC int xfs_attr_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args, - int freemap_index); -STATIC void xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer); -STATIC void xfs_attr_leaf_rebalance(xfs_da_state_t *state, +STATIC int xfs_attr3_leaf_create(struct xfs_da_args *args, + xfs_dablk_t which_block, struct xfs_buf **bpp); +STATIC int xfs_attr3_leaf_add_work(struct xfs_buf *leaf_buffer, + struct xfs_attr3_icleaf_hdr *ichdr, + struct xfs_da_args *args, int freemap_index); +STATIC void xfs_attr3_leaf_compact(struct xfs_da_args *args, + struct xfs_attr3_icleaf_hdr *ichdr, + struct xfs_buf *leaf_buffer); +STATIC void xfs_attr3_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, xfs_da_state_blk_t *blk2); -STATIC int xfs_attr_leaf_figure_balance(xfs_da_state_t *state, - xfs_da_state_blk_t *leaf_blk_1, - xfs_da_state_blk_t *leaf_blk_2, - int *number_entries_in_blk1, - int *number_usedbytes_in_blk1); - +STATIC int xfs_attr3_leaf_figure_balance(xfs_da_state_t *state, + xfs_da_state_blk_t *leaf_blk_1, + struct xfs_attr3_icleaf_hdr *ichdr1, + xfs_da_state_blk_t *leaf_blk_2, + struct xfs_attr3_icleaf_hdr *ichdr2, + int *number_entries_in_blk1, + int *number_usedbytes_in_blk1); /* * Utility routines. */ -STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf, - int src_start, - xfs_attr_leafblock_t *dst_leaf, - int dst_start, int move_count, - xfs_mount_t *mp); +STATIC void xfs_attr3_leaf_moveents(struct xfs_attr_leafblock *src_leaf, + struct xfs_attr3_icleaf_hdr *src_ichdr, int src_start, + struct xfs_attr_leafblock *dst_leaf, + struct xfs_attr3_icleaf_hdr *dst_ichdr, int dst_start, + int move_count, struct xfs_mount *mp); STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); +void +xfs_attr3_leaf_hdr_from_disk( + struct xfs_attr3_icleaf_hdr *to, + struct xfs_attr_leafblock *from) +{ + int i; + + ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC) || + from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)); + + if (from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)) { + struct xfs_attr3_leaf_hdr *hdr3 = (struct xfs_attr3_leaf_hdr *)from; + + to->forw = be32_to_cpu(hdr3->info.hdr.forw); + to->back = be32_to_cpu(hdr3->info.hdr.back); + to->magic = be16_to_cpu(hdr3->info.hdr.magic); + to->count = be16_to_cpu(hdr3->count); + to->usedbytes = be16_to_cpu(hdr3->usedbytes); + to->firstused = be16_to_cpu(hdr3->firstused); + to->holes = hdr3->holes; + + for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { + to->freemap[i].base = be16_to_cpu(hdr3->freemap[i].base); + to->freemap[i].size = be16_to_cpu(hdr3->freemap[i].size); + } + return; + } + to->forw = be32_to_cpu(from->hdr.info.forw); + to->back = be32_to_cpu(from->hdr.info.back); + to->magic = be16_to_cpu(from->hdr.info.magic); + to->count = be16_to_cpu(from->hdr.count); + to->usedbytes = be16_to_cpu(from->hdr.usedbytes); + to->firstused = be16_to_cpu(from->hdr.firstused); + to->holes = from->hdr.holes; + + for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { + to->freemap[i].base = be16_to_cpu(from->hdr.freemap[i].base); + to->freemap[i].size = be16_to_cpu(from->hdr.freemap[i].size); + } +} + +void +xfs_attr3_leaf_hdr_to_disk( + struct xfs_attr_leafblock *to, + struct xfs_attr3_icleaf_hdr *from) +{ + int i; + + ASSERT(from->magic == XFS_ATTR_LEAF_MAGIC || + from->magic == XFS_ATTR3_LEAF_MAGIC); + + if (from->magic == XFS_ATTR3_LEAF_MAGIC) { + struct xfs_attr3_leaf_hdr *hdr3 = (struct xfs_attr3_leaf_hdr *)to; + + hdr3->info.hdr.forw = cpu_to_be32(from->forw); + hdr3->info.hdr.back = cpu_to_be32(from->back); + hdr3->info.hdr.magic = cpu_to_be16(from->magic); + hdr3->count = cpu_to_be16(from->count); + hdr3->usedbytes = cpu_to_be16(from->usedbytes); + hdr3->firstused = cpu_to_be16(from->firstused); + hdr3->holes = from->holes; + hdr3->pad1 = 0; + + for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { + hdr3->freemap[i].base = cpu_to_be16(from->freemap[i].base); + hdr3->freemap[i].size = cpu_to_be16(from->freemap[i].size); + } + return; + } + to->hdr.info.forw = cpu_to_be32(from->forw); + to->hdr.info.back = cpu_to_be32(from->back); + to->hdr.info.magic = cpu_to_be16(from->magic); + to->hdr.count = cpu_to_be16(from->count); + to->hdr.usedbytes = cpu_to_be16(from->usedbytes); + to->hdr.firstused = cpu_to_be16(from->firstused); + to->hdr.holes = from->holes; + to->hdr.pad1 = 0; + + for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { + to->hdr.freemap[i].base = cpu_to_be16(from->freemap[i].base); + to->hdr.freemap[i].size = cpu_to_be16(from->freemap[i].size); + } +} + +static bool +xfs_attr3_leaf_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_attr_leafblock *leaf = bp->b_addr; + struct xfs_attr3_icleaf_hdr ichdr; + + xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + struct xfs_da3_node_hdr *hdr3 = bp->b_addr; + + if (ichdr.magic != XFS_ATTR3_LEAF_MAGIC) + return false; + + if (!uuid_equal(&hdr3->info.uuid, &mp->m_sb.sb_uuid)) + return false; + if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn) + return false; + } else { + if (ichdr.magic != XFS_ATTR_LEAF_MAGIC) + return false; + } + if (ichdr.count == 0) + return false; + + /* XXX: need to range check rest of attr header values */ + /* XXX: hash order check? */ + + return true; +} + +static void +xfs_attr3_leaf_write_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_attr3_leaf_hdr *hdr3 = bp->b_addr; + + if (!xfs_attr3_leaf_verify(bp)) { + xfs_buf_ioerror(bp, EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return; + + if (bip) + hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn); + + xfs_buf_update_cksum(bp, XFS_ATTR3_LEAF_CRC_OFF); +} + +/* + * leaf/node format detection on trees is sketchy, so a node read can be done on + * leaf level blocks when detection identifies the tree as a node format tree + * incorrectly. In this case, we need to swap the verifier to match the correct + * format of the block being read. + */ +static void +xfs_attr3_leaf_read_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + + if (xfs_sb_version_hascrc(&mp->m_sb) && + !xfs_buf_verify_cksum(bp, XFS_ATTR3_LEAF_CRC_OFF)) + xfs_buf_ioerror(bp, EFSBADCRC); + else if (!xfs_attr3_leaf_verify(bp)) + xfs_buf_ioerror(bp, EFSCORRUPTED); + + if (bp->b_error) + xfs_verifier_error(bp); +} + +const struct xfs_buf_ops xfs_attr3_leaf_buf_ops = { + .verify_read = xfs_attr3_leaf_read_verify, + .verify_write = xfs_attr3_leaf_write_verify, +}; + +int +xfs_attr3_leaf_read( + struct xfs_trans *tp, + struct xfs_inode *dp, + xfs_dablk_t bno, + xfs_daddr_t mappedbno, + struct xfs_buf **bpp) +{ + int err; + + err = xfs_da_read_buf(tp, dp, bno, mappedbno, bpp, + XFS_ATTR_FORK, &xfs_attr3_leaf_buf_ops); + if (!err && tp) + xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_ATTR_LEAF_BUF); + return err; +} + /*======================================================================== * Namespace helper routines *========================================================================*/ @@ -78,6 +267,7 @@ /* * Query whether the requested number of additional bytes of extended * attribute space will be able to fit inline. + * * Returns zero if not, else the di_forkoff fork offset to be used in the * literal area for attribute data once the new bytes have been added. * @@ -90,10 +280,11 @@ int offset; int minforkoff; /* lower limit on valid forkoff locations */ int maxforkoff; /* upper limit on valid forkoff locations */ - int dsize; + int dsize; xfs_mount_t *mp = dp->i_mount; - offset = (XFS_LITINO(mp) - bytes) >> 3; /* rounded down */ + /* rounded down */ + offset = (XFS_LITINO(mp, dp->i_d.di_version) - bytes) >> 3; switch (dp->i_d.di_format) { case XFS_DINODE_FMT_DEV: @@ -104,60 +295,74 @@ return (offset >= minforkoff) ? minforkoff : 0; } - if (!(mp->m_flags & XFS_MOUNT_ATTR2)) { - if (bytes <= XFS_IFORK_ASIZE(dp)) - return dp->i_d.di_forkoff; + /* + * If the requested numbers of bytes is smaller or equal to the + * current attribute fork size we can always proceed. + * + * Note that if_bytes in the data fork might actually be larger than + * the current data fork size is due to delalloc extents. In that + * case either the extent count will go down when they are converted + * to real extents, or the delalloc conversion will take care of the + * literal area rebalancing. + */ + if (bytes <= XFS_IFORK_ASIZE(dp)) + return dp->i_d.di_forkoff; + + /* + * For attr2 we can try to move the forkoff if there is space in the + * literal area, but for the old format we are done if there is no + * space in the fixed attribute fork. + */ + if (!(mp->m_flags & XFS_MOUNT_ATTR2)) return 0; - } dsize = dp->i_df.if_bytes; - + switch (dp->i_d.di_format) { case XFS_DINODE_FMT_EXTENTS: - /* + /* * If there is no attr fork and the data fork is extents, - * determine if creating the default attr fork will result - * in the extents form migrating to btree. If so, the - * minimum offset only needs to be the space required for + * determine if creating the default attr fork will result + * in the extents form migrating to btree. If so, the + * minimum offset only needs to be the space required for * the btree root. - */ + */ if (!dp->i_d.di_forkoff && dp->i_df.if_bytes > xfs_default_attroffset(dp)) dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS); break; - case XFS_DINODE_FMT_BTREE: /* - * If have data btree then keep forkoff if we have one, - * otherwise we are adding a new attr, so then we set - * minforkoff to where the btree root can finish so we have + * If we have a data btree then keep forkoff if we have one, + * otherwise we are adding a new attr, so then we set + * minforkoff to where the btree root can finish so we have * plenty of room for attrs */ if (dp->i_d.di_forkoff) { - if (offset < dp->i_d.di_forkoff) + if (offset < dp->i_d.di_forkoff) return 0; - else - return dp->i_d.di_forkoff; - } else - dsize = XFS_BMAP_BROOT_SPACE(dp->i_df.if_broot); + return dp->i_d.di_forkoff; + } + dsize = XFS_BMAP_BROOT_SPACE(mp, dp->i_df.if_broot); break; } - - /* - * A data fork btree root must have space for at least + + /* + * A data fork btree root must have space for at least * MINDBTPTRS key/ptr pairs if the data fork is small or empty. */ minforkoff = MAX(dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS)); minforkoff = roundup(minforkoff, 8) >> 3; /* attr fork btree root can have at least this many key/ptr pairs */ - maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS); + maxforkoff = XFS_LITINO(mp, dp->i_d.di_version) - + XFS_BMDR_SPACE_CALC(MINABTPTRS); maxforkoff = maxforkoff >> 3; /* rounded down */ - if (offset >= minforkoff && offset < maxforkoff) - return offset; if (offset >= maxforkoff) return maxforkoff; + if (offset >= minforkoff) + return offset; return 0; } @@ -189,6 +394,8 @@ xfs_inode_t *dp; xfs_ifork_t *ifp; + trace_xfs_attr_sf_create(args); + dp = args->dp; ASSERT(dp != NULL); ifp = dp->i_afp; @@ -222,13 +429,11 @@ xfs_inode_t *dp; xfs_ifork_t *ifp; + trace_xfs_attr_sf_add(args); + dp = args->dp; mp = dp->i_mount; dp->i_d.di_forkoff = forkoff; - dp->i_df.if_ext_max = - XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t); - dp->i_afp->if_ext_max = - XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t); ifp = dp->i_afp; ASSERT(ifp->if_flags & XFS_IFINLINE); @@ -280,7 +485,6 @@ ASSERT(ip->i_d.di_anextents == 0); ASSERT(ip->i_afp == NULL); - ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); } @@ -296,6 +500,8 @@ xfs_mount_t *mp; xfs_inode_t *dp; + trace_xfs_attr_sf_remove(args); + dp = args->dp; mp = dp->i_mount; base = sizeof(xfs_attr_sf_hdr_t); @@ -343,10 +549,6 @@ (args->op_flags & XFS_DA_OP_ADDNAME) || !(mp->m_flags & XFS_MOUNT_ATTR2) || dp->i_d.di_format == XFS_DINODE_FMT_BTREE); - dp->i_afp->if_ext_max = - XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t); - dp->i_df.if_ext_max = - XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t); xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA); } @@ -368,6 +570,8 @@ int i; xfs_ifork_t *ifp; + trace_xfs_attr_sf_lookup(args); + ifp = args->dp->i_afp; ASSERT(ifp->if_flags & XFS_IFINLINE); sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; @@ -396,7 +600,7 @@ xfs_attr_sf_entry_t *sfe; int i; - ASSERT(args->dp->i_d.di_aformat == XFS_IFINLINE); + ASSERT(args->dp->i_afp->if_flags == XFS_IFINLINE); sf = (xfs_attr_shortform_t *)args->dp->i_afp->if_u1.if_data; sfe = &sf->list[0]; for (i = 0; i < sf->hdr.count; @@ -436,9 +640,11 @@ char *tmpbuffer; int error, i, size; xfs_dablk_t blkno; - xfs_dabuf_t *bp; + struct xfs_buf *bp; xfs_ifork_t *ifp; + trace_xfs_attr_sf_to_leaf(args); + dp = args->dp; ifp = dp->i_afp; sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; @@ -449,6 +655,8 @@ sf = (xfs_attr_shortform_t *)tmpbuffer; xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); + xfs_bmap_local_to_extents_empty(dp, XFS_ATTR_FORK); + bp = NULL; error = xfs_da_grow_inode(args, &blkno); if (error) { @@ -464,7 +672,7 @@ } ASSERT(blkno == 0); - error = xfs_attr_leaf_create(args, blkno, &bp); + error = xfs_attr3_leaf_create(args, blkno, &bp); if (error) { error = xfs_da_shrink_inode(args, 0, bp); bp = NULL; @@ -493,9 +701,9 @@ nargs.hashval = xfs_da_hashname(sfe->nameval, sfe->namelen); nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags); - error = xfs_attr_leaf_lookup_int(bp, &nargs); /* set a->index */ + error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */ ASSERT(error == ENOATTR); - error = xfs_attr_leaf_add(bp, &nargs); + error = xfs_attr3_leaf_add(bp, &nargs); ASSERT(error != ENOSPC); if (error) goto out; @@ -504,8 +712,6 @@ error = 0; out: - if(bp) - xfs_da_buf_done(bp); kmem_free(tmpbuffer); return(error); } @@ -515,62 +721,76 @@ * a shortform attribute list. */ int -xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp) +xfs_attr_shortform_allfit( + struct xfs_buf *bp, + struct xfs_inode *dp) { - xfs_attr_leafblock_t *leaf; - xfs_attr_leaf_entry_t *entry; + struct xfs_attr_leafblock *leaf; + struct xfs_attr_leaf_entry *entry; xfs_attr_leaf_name_local_t *name_loc; - int bytes, i; + struct xfs_attr3_icleaf_hdr leafhdr; + int bytes; + int i; + + leaf = bp->b_addr; + xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf); + entry = xfs_attr3_leaf_entryp(leaf); - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - - entry = &leaf->entries[0]; bytes = sizeof(struct xfs_attr_sf_hdr); - for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { + for (i = 0; i < leafhdr.count; entry++, i++) { if (entry->flags & XFS_ATTR_INCOMPLETE) continue; /* don't copy partial entries */ if (!(entry->flags & XFS_ATTR_LOCAL)) return(0); - name_loc = xfs_attr_leaf_name_local(leaf, i); + name_loc = xfs_attr3_leaf_name_local(leaf, i); if (name_loc->namelen >= XFS_ATTR_SF_ENTSIZE_MAX) return(0); if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX) return(0); - bytes += sizeof(struct xfs_attr_sf_entry)-1 + bytes += sizeof(struct xfs_attr_sf_entry) - 1 + name_loc->namelen + be16_to_cpu(name_loc->valuelen); } if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) && (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && (bytes == sizeof(struct xfs_attr_sf_hdr))) - return(-1); - return(xfs_attr_shortform_bytesfit(dp, bytes)); + return -1; + return xfs_attr_shortform_bytesfit(dp, bytes); } /* * Convert a leaf attribute list to shortform attribute list */ int -xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff) -{ - xfs_attr_leafblock_t *leaf; - xfs_attr_leaf_entry_t *entry; - xfs_attr_leaf_name_local_t *name_loc; - xfs_da_args_t nargs; - xfs_inode_t *dp; - char *tmpbuffer; - int error, i; +xfs_attr3_leaf_to_shortform( + struct xfs_buf *bp, + struct xfs_da_args *args, + int forkoff) +{ + struct xfs_attr_leafblock *leaf; + struct xfs_attr3_icleaf_hdr ichdr; + struct xfs_attr_leaf_entry *entry; + struct xfs_attr_leaf_name_local *name_loc; + struct xfs_da_args nargs; + struct xfs_inode *dp = args->dp; + char *tmpbuffer; + int error; + int i; + + trace_xfs_attr_leaf_to_sf(args); - dp = args->dp; tmpbuffer = kmem_alloc(XFS_LBSIZE(dp->i_mount), KM_SLEEP); - ASSERT(tmpbuffer != NULL); + if (!tmpbuffer) + return ENOMEM; + + memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(dp->i_mount)); - ASSERT(bp != NULL); - memcpy(tmpbuffer, bp->data, XFS_LBSIZE(dp->i_mount)); leaf = (xfs_attr_leafblock_t *)tmpbuffer; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - memset(bp->data, 0, XFS_LBSIZE(dp->i_mount)); + xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); + entry = xfs_attr3_leaf_entryp(leaf); + + /* XXX (dgc): buffer is about to be marked stale - why zero it? */ + memset(bp->b_addr, 0, XFS_LBSIZE(dp->i_mount)); /* * Clean out the prior contents of the attribute list. @@ -599,14 +819,14 @@ nargs.whichfork = XFS_ATTR_FORK; nargs.trans = args->trans; nargs.op_flags = XFS_DA_OP_OKNOENT; - entry = &leaf->entries[0]; - for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { + + for (i = 0; i < ichdr.count; entry++, i++) { if (entry->flags & XFS_ATTR_INCOMPLETE) continue; /* don't copy partial entries */ if (!entry->nameidx) continue; ASSERT(entry->flags & XFS_ATTR_LOCAL); - name_loc = xfs_attr_leaf_name_local(leaf, i); + name_loc = xfs_attr3_leaf_name_local(leaf, i); nargs.name = name_loc->nameval; nargs.namelen = name_loc->namelen; nargs.value = &name_loc->nameval[nargs.namelen]; @@ -619,68 +839,77 @@ out: kmem_free(tmpbuffer); - return(error); + return error; } /* * Convert from using a single leaf to a root node and a leaf. */ int -xfs_attr_leaf_to_node(xfs_da_args_t *args) +xfs_attr3_leaf_to_node( + struct xfs_da_args *args) { - xfs_attr_leafblock_t *leaf; - xfs_da_intnode_t *node; - xfs_inode_t *dp; - xfs_dabuf_t *bp1, *bp2; - xfs_dablk_t blkno; - int error; + struct xfs_attr_leafblock *leaf; + struct xfs_attr3_icleaf_hdr icleafhdr; + struct xfs_attr_leaf_entry *entries; + struct xfs_da_node_entry *btree; + struct xfs_da3_icnode_hdr icnodehdr; + struct xfs_da_intnode *node; + struct xfs_inode *dp = args->dp; + struct xfs_mount *mp = dp->i_mount; + struct xfs_buf *bp1 = NULL; + struct xfs_buf *bp2 = NULL; + xfs_dablk_t blkno; + int error; + + trace_xfs_attr_leaf_to_node(args); - dp = args->dp; - bp1 = bp2 = NULL; error = xfs_da_grow_inode(args, &blkno); if (error) goto out; - error = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp1, - XFS_ATTR_FORK); + error = xfs_attr3_leaf_read(args->trans, dp, 0, -1, &bp1); if (error) goto out; - ASSERT(bp1 != NULL); - bp2 = NULL; - error = xfs_da_get_buf(args->trans, args->dp, blkno, -1, &bp2, - XFS_ATTR_FORK); + + error = xfs_da_get_buf(args->trans, dp, blkno, -1, &bp2, XFS_ATTR_FORK); if (error) goto out; - ASSERT(bp2 != NULL); - memcpy(bp2->data, bp1->data, XFS_LBSIZE(dp->i_mount)); - xfs_da_buf_done(bp1); - bp1 = NULL; - xfs_da_log_buf(args->trans, bp2, 0, XFS_LBSIZE(dp->i_mount) - 1); + + /* copy leaf to new buffer, update identifiers */ + xfs_trans_buf_set_type(args->trans, bp2, XFS_BLFT_ATTR_LEAF_BUF); + bp2->b_ops = bp1->b_ops; + memcpy(bp2->b_addr, bp1->b_addr, XFS_LBSIZE(mp)); + if (xfs_sb_version_hascrc(&mp->m_sb)) { + struct xfs_da3_blkinfo *hdr3 = bp2->b_addr; + hdr3->blkno = cpu_to_be64(bp2->b_bn); + } + xfs_trans_log_buf(args->trans, bp2, 0, XFS_LBSIZE(mp) - 1); /* * Set up the new root node. */ - error = xfs_da_node_create(args, 0, 1, &bp1, XFS_ATTR_FORK); + error = xfs_da3_node_create(args, 0, 1, &bp1, XFS_ATTR_FORK); if (error) goto out; - node = bp1->data; - leaf = bp2->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); + node = bp1->b_addr; + xfs_da3_node_hdr_from_disk(&icnodehdr, node); + btree = xfs_da3_node_tree_p(node); + + leaf = bp2->b_addr; + xfs_attr3_leaf_hdr_from_disk(&icleafhdr, leaf); + entries = xfs_attr3_leaf_entryp(leaf); + /* both on-disk, don't endian-flip twice */ - node->btree[0].hashval = - leaf->entries[be16_to_cpu(leaf->hdr.count)-1 ].hashval; - node->btree[0].before = cpu_to_be32(blkno); - node->hdr.count = cpu_to_be16(1); - xfs_da_log_buf(args->trans, bp1, 0, XFS_LBSIZE(dp->i_mount) - 1); + btree[0].hashval = entries[icleafhdr.count - 1].hashval; + btree[0].before = cpu_to_be32(blkno); + icnodehdr.count = 1; + xfs_da3_node_hdr_to_disk(node, &icnodehdr); + xfs_trans_log_buf(args->trans, bp1, 0, XFS_LBSIZE(mp) - 1); error = 0; out: - if (bp1) - xfs_da_buf_done(bp1); - if (bp2) - xfs_da_buf_done(bp2); - return(error); + return error; } - /*======================================================================== * Routines used for growing the Btree. *========================================================================*/ @@ -690,51 +919,69 @@ * or a leaf in a node attribute list. */ STATIC int -xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) -{ - xfs_attr_leafblock_t *leaf; - xfs_attr_leaf_hdr_t *hdr; - xfs_inode_t *dp; - xfs_dabuf_t *bp; - int error; +xfs_attr3_leaf_create( + struct xfs_da_args *args, + xfs_dablk_t blkno, + struct xfs_buf **bpp) +{ + struct xfs_attr_leafblock *leaf; + struct xfs_attr3_icleaf_hdr ichdr; + struct xfs_inode *dp = args->dp; + struct xfs_mount *mp = dp->i_mount; + struct xfs_buf *bp; + int error; + + trace_xfs_attr_leaf_create(args); - dp = args->dp; - ASSERT(dp != NULL); error = xfs_da_get_buf(args->trans, args->dp, blkno, -1, &bp, XFS_ATTR_FORK); if (error) - return(error); - ASSERT(bp != NULL); - leaf = bp->data; - memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount)); - hdr = &leaf->hdr; - hdr->info.magic = cpu_to_be16(XFS_ATTR_LEAF_MAGIC); - hdr->firstused = cpu_to_be16(XFS_LBSIZE(dp->i_mount)); - if (!hdr->firstused) { - hdr->firstused = cpu_to_be16( - XFS_LBSIZE(dp->i_mount) - XFS_ATTR_LEAF_NAME_ALIGN); - } - - hdr->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t)); - hdr->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr->firstused) - - sizeof(xfs_attr_leaf_hdr_t)); + return error; + bp->b_ops = &xfs_attr3_leaf_buf_ops; + xfs_trans_buf_set_type(args->trans, bp, XFS_BLFT_ATTR_LEAF_BUF); + leaf = bp->b_addr; + memset(leaf, 0, XFS_LBSIZE(mp)); + + memset(&ichdr, 0, sizeof(ichdr)); + ichdr.firstused = XFS_LBSIZE(mp); + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + struct xfs_da3_blkinfo *hdr3 = bp->b_addr; - xfs_da_log_buf(args->trans, bp, 0, XFS_LBSIZE(dp->i_mount) - 1); + ichdr.magic = XFS_ATTR3_LEAF_MAGIC; + + hdr3->blkno = cpu_to_be64(bp->b_bn); + hdr3->owner = cpu_to_be64(dp->i_ino); + uuid_copy(&hdr3->uuid, &mp->m_sb.sb_uuid); + + ichdr.freemap[0].base = sizeof(struct xfs_attr3_leaf_hdr); + } else { + ichdr.magic = XFS_ATTR_LEAF_MAGIC; + ichdr.freemap[0].base = sizeof(struct xfs_attr_leaf_hdr); + } + ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base; + + xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr); + xfs_trans_log_buf(args->trans, bp, 0, XFS_LBSIZE(mp) - 1); *bpp = bp; - return(0); + return 0; } /* * Split the leaf node, rebalance, then add the new entry. */ int -xfs_attr_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, - xfs_da_state_blk_t *newblk) +xfs_attr3_leaf_split( + struct xfs_da_state *state, + struct xfs_da_state_blk *oldblk, + struct xfs_da_state_blk *newblk) { xfs_dablk_t blkno; int error; + trace_xfs_attr_leaf_split(state->args); + /* * Allocate space for a new leaf node. */ @@ -742,7 +989,7 @@ error = xfs_da_grow_inode(state->args, &blkno); if (error) return(error); - error = xfs_attr_leaf_create(state->args, blkno, &newblk->bp); + error = xfs_attr3_leaf_create(state->args, blkno, &newblk->bp); if (error) return(error); newblk->blkno = blkno; @@ -752,8 +999,8 @@ * Rebalance the entries across the two leaves. * NOTE: rebalance() currently depends on the 2nd block being empty. */ - xfs_attr_leaf_rebalance(state, oldblk, newblk); - error = xfs_da_blk_link(state, oldblk, newblk); + xfs_attr3_leaf_rebalance(state, oldblk, newblk); + error = xfs_da3_blk_link(state, oldblk, newblk); if (error) return(error); @@ -764,10 +1011,13 @@ * * Insert the "new" entry in the correct block. */ - if (state->inleaf) - error = xfs_attr_leaf_add(oldblk->bp, state->args); - else - error = xfs_attr_leaf_add(newblk->bp, state->args); + if (state->inleaf) { + trace_xfs_attr_leaf_add_old(state->args); + error = xfs_attr3_leaf_add(oldblk->bp, state->args); + } else { + trace_xfs_attr_leaf_add_new(state->args); + error = xfs_attr3_leaf_add(newblk->bp, state->args); + } /* * Update last hashval in each block since we added the name. @@ -781,18 +1031,23 @@ * Add a name to the leaf attribute list structure. */ int -xfs_attr_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args) -{ - xfs_attr_leafblock_t *leaf; - xfs_attr_leaf_hdr_t *hdr; - xfs_attr_leaf_map_t *map; - int tablesize, entsize, sum, tmp, i; - - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - ASSERT((args->index >= 0) - && (args->index <= be16_to_cpu(leaf->hdr.count))); - hdr = &leaf->hdr; +xfs_attr3_leaf_add( + struct xfs_buf *bp, + struct xfs_da_args *args) +{ + struct xfs_attr_leafblock *leaf; + struct xfs_attr3_icleaf_hdr ichdr; + int tablesize; + int entsize; + int sum; + int tmp; + int i; + + trace_xfs_attr_leaf_add(args); + + leaf = bp->b_addr; + xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); + ASSERT(args->index >= 0 && args->index <= ichdr.count); entsize = xfs_attr_leaf_newentsize(args->namelen, args->valuelen, args->trans->t_mountp->m_sb.sb_blocksize, NULL); @@ -800,25 +1055,23 @@ * Search through freemap for first-fit on new name length. * (may need to figure in size of entry struct too) */ - tablesize = (be16_to_cpu(hdr->count) + 1) - * sizeof(xfs_attr_leaf_entry_t) - + sizeof(xfs_attr_leaf_hdr_t); - map = &hdr->freemap[XFS_ATTR_LEAF_MAPSIZE-1]; - for (sum = 0, i = XFS_ATTR_LEAF_MAPSIZE-1; i >= 0; map--, i--) { - if (tablesize > be16_to_cpu(hdr->firstused)) { - sum += be16_to_cpu(map->size); + tablesize = (ichdr.count + 1) * sizeof(xfs_attr_leaf_entry_t) + + xfs_attr3_leaf_hdr_size(leaf); + for (sum = 0, i = XFS_ATTR_LEAF_MAPSIZE - 1; i >= 0; i--) { + if (tablesize > ichdr.firstused) { + sum += ichdr.freemap[i].size; continue; } - if (!map->size) + if (!ichdr.freemap[i].size) continue; /* no space in this map */ tmp = entsize; - if (be16_to_cpu(map->base) < be16_to_cpu(hdr->firstused)) + if (ichdr.freemap[i].base < ichdr.firstused) tmp += sizeof(xfs_attr_leaf_entry_t); - if (be16_to_cpu(map->size) >= tmp) { - tmp = xfs_attr_leaf_add_work(bp, args, i); - return(tmp); + if (ichdr.freemap[i].size >= tmp) { + tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, i); + goto out_log_hdr; } - sum += be16_to_cpu(map->size); + sum += ichdr.freemap[i].size; } /* @@ -826,77 +1079,89 @@ * and we don't have enough freespace, then compaction will do us * no good and we should just give up. */ - if (!hdr->holes && (sum < entsize)) - return(XFS_ERROR(ENOSPC)); + if (!ichdr.holes && sum < entsize) + return XFS_ERROR(ENOSPC); /* * Compact the entries to coalesce free space. * This may change the hdr->count via dropping INCOMPLETE entries. */ - xfs_attr_leaf_compact(args->trans, bp); + xfs_attr3_leaf_compact(args, &ichdr, bp); /* * After compaction, the block is guaranteed to have only one * free region, in freemap[0]. If it is not big enough, give up. */ - if (be16_to_cpu(hdr->freemap[0].size) - < (entsize + sizeof(xfs_attr_leaf_entry_t))) - return(XFS_ERROR(ENOSPC)); + if (ichdr.freemap[0].size < (entsize + sizeof(xfs_attr_leaf_entry_t))) { + tmp = ENOSPC; + goto out_log_hdr; + } - return(xfs_attr_leaf_add_work(bp, args, 0)); + tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, 0); + +out_log_hdr: + xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr); + xfs_trans_log_buf(args->trans, bp, + XFS_DA_LOGRANGE(leaf, &leaf->hdr, + xfs_attr3_leaf_hdr_size(leaf))); + return tmp; } /* * Add a name to a leaf attribute list structure. */ STATIC int -xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) -{ - xfs_attr_leafblock_t *leaf; - xfs_attr_leaf_hdr_t *hdr; - xfs_attr_leaf_entry_t *entry; - xfs_attr_leaf_name_local_t *name_loc; - xfs_attr_leaf_name_remote_t *name_rmt; - xfs_attr_leaf_map_t *map; - xfs_mount_t *mp; - int tmp, i; - - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - hdr = &leaf->hdr; - ASSERT((mapindex >= 0) && (mapindex < XFS_ATTR_LEAF_MAPSIZE)); - ASSERT((args->index >= 0) && (args->index <= be16_to_cpu(hdr->count))); +xfs_attr3_leaf_add_work( + struct xfs_buf *bp, + struct xfs_attr3_icleaf_hdr *ichdr, + struct xfs_da_args *args, + int mapindex) +{ + struct xfs_attr_leafblock *leaf; + struct xfs_attr_leaf_entry *entry; + struct xfs_attr_leaf_name_local *name_loc; + struct xfs_attr_leaf_name_remote *name_rmt; + struct xfs_mount *mp; + int tmp; + int i; + + trace_xfs_attr_leaf_add_work(args); + + leaf = bp->b_addr; + ASSERT(mapindex >= 0 && mapindex < XFS_ATTR_LEAF_MAPSIZE); + ASSERT(args->index >= 0 && args->index <= ichdr->count); /* * Force open some space in the entry array and fill it in. */ - entry = &leaf->entries[args->index]; - if (args->index < be16_to_cpu(hdr->count)) { - tmp = be16_to_cpu(hdr->count) - args->index; + entry = &xfs_attr3_leaf_entryp(leaf)[args->index]; + if (args->index < ichdr->count) { + tmp = ichdr->count - args->index; tmp *= sizeof(xfs_attr_leaf_entry_t); - memmove((char *)(entry+1), (char *)entry, tmp); - xfs_da_log_buf(args->trans, bp, + memmove(entry + 1, entry, tmp); + xfs_trans_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); } - be16_add_cpu(&hdr->count, 1); + ichdr->count++; /* * Allocate space for the new string (at the end of the run). */ - map = &hdr->freemap[mapindex]; mp = args->trans->t_mountp; - ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp)); - ASSERT((be16_to_cpu(map->base) & 0x3) == 0); - ASSERT(be16_to_cpu(map->size) >= + ASSERT(ichdr->freemap[mapindex].base < XFS_LBSIZE(mp)); + ASSERT((ichdr->freemap[mapindex].base & 0x3) == 0); + ASSERT(ichdr->freemap[mapindex].size >= xfs_attr_leaf_newentsize(args->namelen, args->valuelen, mp->m_sb.sb_blocksize, NULL)); - ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); - ASSERT((be16_to_cpu(map->size) & 0x3) == 0); - be16_add_cpu(&map->size, - -xfs_attr_leaf_newentsize(args->namelen, args->valuelen, - mp->m_sb.sb_blocksize, &tmp)); - entry->nameidx = cpu_to_be16(be16_to_cpu(map->base) + - be16_to_cpu(map->size)); + ASSERT(ichdr->freemap[mapindex].size < XFS_LBSIZE(mp)); + ASSERT((ichdr->freemap[mapindex].size & 0x3) == 0); + + ichdr->freemap[mapindex].size -= + xfs_attr_leaf_newentsize(args->namelen, args->valuelen, + mp->m_sb.sb_blocksize, &tmp); + + entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base + + ichdr->freemap[mapindex].size); entry->hashval = cpu_to_be32(args->hashval); entry->flags = tmp ? XFS_ATTR_LOCAL : 0; entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags); @@ -907,16 +1172,14 @@ args->index2++; } } - xfs_da_log_buf(args->trans, bp, + xfs_trans_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); ASSERT((args->index == 0) || (be32_to_cpu(entry->hashval) >= be32_to_cpu((entry-1)->hashval))); - ASSERT((args->index == be16_to_cpu(hdr->count)-1) || + ASSERT((args->index == ichdr->count - 1) || (be32_to_cpu(entry->hashval) <= be32_to_cpu((entry+1)->hashval))); /* - * Copy the attribute name and value into the new space. - * * For "remote" attribute values, simply note that we need to * allocate space for the "remote" value. We can't actually * allocate the extents in this transaction, and we can't decide @@ -924,14 +1187,14 @@ * as part of this transaction (a split operation for example). */ if (entry->flags & XFS_ATTR_LOCAL) { - name_loc = xfs_attr_leaf_name_local(leaf, args->index); + name_loc = xfs_attr3_leaf_name_local(leaf, args->index); name_loc->namelen = args->namelen; name_loc->valuelen = cpu_to_be16(args->valuelen); memcpy((char *)name_loc->nameval, args->name, args->namelen); memcpy((char *)&name_loc->nameval[args->namelen], args->value, be16_to_cpu(name_loc->valuelen)); } else { - name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); + name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index); name_rmt->namelen = args->namelen; memcpy((char *)name_rmt->name, args->name, args->namelen); entry->flags |= XFS_ATTR_INCOMPLETE; @@ -939,87 +1202,132 @@ name_rmt->valuelen = 0; name_rmt->valueblk = 0; args->rmtblkno = 1; - args->rmtblkcnt = XFS_B_TO_FSB(mp, args->valuelen); + args->rmtblkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen); } - xfs_da_log_buf(args->trans, bp, - XFS_DA_LOGRANGE(leaf, xfs_attr_leaf_name(leaf, args->index), + xfs_trans_log_buf(args->trans, bp, + XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index), xfs_attr_leaf_entsize(leaf, args->index))); /* * Update the control info for this leaf node */ - if (be16_to_cpu(entry->nameidx) < be16_to_cpu(hdr->firstused)) { - /* both on-disk, don't endian-flip twice */ - hdr->firstused = entry->nameidx; - } - ASSERT(be16_to_cpu(hdr->firstused) >= - ((be16_to_cpu(hdr->count) * sizeof(*entry)) + sizeof(*hdr))); - tmp = (be16_to_cpu(hdr->count)-1) * sizeof(xfs_attr_leaf_entry_t) - + sizeof(xfs_attr_leaf_hdr_t); - map = &hdr->freemap[0]; - for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) { - if (be16_to_cpu(map->base) == tmp) { - be16_add_cpu(&map->base, sizeof(xfs_attr_leaf_entry_t)); - be16_add_cpu(&map->size, - -((int)sizeof(xfs_attr_leaf_entry_t))); - } - } - be16_add_cpu(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index)); - xfs_da_log_buf(args->trans, bp, - XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); - return(0); + if (be16_to_cpu(entry->nameidx) < ichdr->firstused) + ichdr->firstused = be16_to_cpu(entry->nameidx); + + ASSERT(ichdr->firstused >= ichdr->count * sizeof(xfs_attr_leaf_entry_t) + + xfs_attr3_leaf_hdr_size(leaf)); + tmp = (ichdr->count - 1) * sizeof(xfs_attr_leaf_entry_t) + + xfs_attr3_leaf_hdr_size(leaf); + + for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { + if (ichdr->freemap[i].base == tmp) { + ichdr->freemap[i].base += sizeof(xfs_attr_leaf_entry_t); + ichdr->freemap[i].size -= sizeof(xfs_attr_leaf_entry_t); + } + } + ichdr->usedbytes += xfs_attr_leaf_entsize(leaf, args->index); + return 0; } /* * Garbage collect a leaf attribute list block by copying it to a new buffer. */ STATIC void -xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp) -{ - xfs_attr_leafblock_t *leaf_s, *leaf_d; - xfs_attr_leaf_hdr_t *hdr_s, *hdr_d; - xfs_mount_t *mp; - char *tmpbuffer; +xfs_attr3_leaf_compact( + struct xfs_da_args *args, + struct xfs_attr3_icleaf_hdr *ichdr_dst, + struct xfs_buf *bp) +{ + struct xfs_attr_leafblock *leaf_src; + struct xfs_attr_leafblock *leaf_dst; + struct xfs_attr3_icleaf_hdr ichdr_src; + struct xfs_trans *trans = args->trans; + struct xfs_mount *mp = trans->t_mountp; + char *tmpbuffer; + + trace_xfs_attr_leaf_compact(args); - mp = trans->t_mountp; tmpbuffer = kmem_alloc(XFS_LBSIZE(mp), KM_SLEEP); - ASSERT(tmpbuffer != NULL); - memcpy(tmpbuffer, bp->data, XFS_LBSIZE(mp)); - memset(bp->data, 0, XFS_LBSIZE(mp)); + memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(mp)); + memset(bp->b_addr, 0, XFS_LBSIZE(mp)); + leaf_src = (xfs_attr_leafblock_t *)tmpbuffer; + leaf_dst = bp->b_addr; + + /* + * Copy the on-disk header back into the destination buffer to ensure + * all the information in the header that is not part of the incore + * header structure is preserved. + */ + memcpy(bp->b_addr, tmpbuffer, xfs_attr3_leaf_hdr_size(leaf_src)); + + /* Initialise the incore headers */ + ichdr_src = *ichdr_dst; /* struct copy */ + ichdr_dst->firstused = XFS_LBSIZE(mp); + ichdr_dst->usedbytes = 0; + ichdr_dst->count = 0; + ichdr_dst->holes = 0; + ichdr_dst->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_src); + ichdr_dst->freemap[0].size = ichdr_dst->firstused - + ichdr_dst->freemap[0].base; - /* - * Copy basic information - */ - leaf_s = (xfs_attr_leafblock_t *)tmpbuffer; - leaf_d = bp->data; - hdr_s = &leaf_s->hdr; - hdr_d = &leaf_d->hdr; - hdr_d->info = hdr_s->info; /* struct copy */ - hdr_d->firstused = cpu_to_be16(XFS_LBSIZE(mp)); - /* handle truncation gracefully */ - if (!hdr_d->firstused) { - hdr_d->firstused = cpu_to_be16( - XFS_LBSIZE(mp) - XFS_ATTR_LEAF_NAME_ALIGN); - } - hdr_d->usedbytes = 0; - hdr_d->count = 0; - hdr_d->holes = 0; - hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t)); - hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused) - - sizeof(xfs_attr_leaf_hdr_t)); + /* write the header back to initialise the underlying buffer */ + xfs_attr3_leaf_hdr_to_disk(leaf_dst, ichdr_dst); /* * Copy all entry's in the same (sorted) order, * but allocate name/value pairs packed and in sequence. */ - xfs_attr_leaf_moveents(leaf_s, 0, leaf_d, 0, - be16_to_cpu(hdr_s->count), mp); - xfs_da_log_buf(trans, bp, 0, XFS_LBSIZE(mp) - 1); + xfs_attr3_leaf_moveents(leaf_src, &ichdr_src, 0, leaf_dst, ichdr_dst, 0, + ichdr_src.count, mp); + /* + * this logs the entire buffer, but the caller must write the header + * back to the buffer when it is finished modifying it. + */ + xfs_trans_log_buf(trans, bp, 0, XFS_LBSIZE(mp) - 1); kmem_free(tmpbuffer); } /* + * Compare two leaf blocks "order". + * Return 0 unless leaf2 should go before leaf1. + */ +static int +xfs_attr3_leaf_order( + struct xfs_buf *leaf1_bp, + struct xfs_attr3_icleaf_hdr *leaf1hdr, + struct xfs_buf *leaf2_bp, + struct xfs_attr3_icleaf_hdr *leaf2hdr) +{ + struct xfs_attr_leaf_entry *entries1; + struct xfs_attr_leaf_entry *entries2; + + entries1 = xfs_attr3_leaf_entryp(leaf1_bp->b_addr); + entries2 = xfs_attr3_leaf_entryp(leaf2_bp->b_addr); + if (leaf1hdr->count > 0 && leaf2hdr->count > 0 && + ((be32_to_cpu(entries2[0].hashval) < + be32_to_cpu(entries1[0].hashval)) || + (be32_to_cpu(entries2[leaf2hdr->count - 1].hashval) < + be32_to_cpu(entries1[leaf1hdr->count - 1].hashval)))) { + return 1; + } + return 0; +} + +int +xfs_attr_leaf_order( + struct xfs_buf *leaf1_bp, + struct xfs_buf *leaf2_bp) +{ + struct xfs_attr3_icleaf_hdr ichdr1; + struct xfs_attr3_icleaf_hdr ichdr2; + + xfs_attr3_leaf_hdr_from_disk(&ichdr1, leaf1_bp->b_addr); + xfs_attr3_leaf_hdr_from_disk(&ichdr2, leaf2_bp->b_addr); + return xfs_attr3_leaf_order(leaf1_bp, &ichdr1, leaf2_bp, &ichdr2); +} + +/* * Redistribute the attribute list entries between two leaf nodes, * taking into account the size of the new entry. * @@ -1032,26 +1340,38 @@ * the "new" and "old" values can end up in different blocks. */ STATIC void -xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, - xfs_da_state_blk_t *blk2) -{ - xfs_da_args_t *args; - xfs_da_state_blk_t *tmp_blk; - xfs_attr_leafblock_t *leaf1, *leaf2; - xfs_attr_leaf_hdr_t *hdr1, *hdr2; - int count, totallen, max, space, swap; +xfs_attr3_leaf_rebalance( + struct xfs_da_state *state, + struct xfs_da_state_blk *blk1, + struct xfs_da_state_blk *blk2) +{ + struct xfs_da_args *args; + struct xfs_attr_leafblock *leaf1; + struct xfs_attr_leafblock *leaf2; + struct xfs_attr3_icleaf_hdr ichdr1; + struct xfs_attr3_icleaf_hdr ichdr2; + struct xfs_attr_leaf_entry *entries1; + struct xfs_attr_leaf_entry *entries2; + int count; + int totallen; + int max; + int space; + int swap; /* * Set up environment. */ ASSERT(blk1->magic == XFS_ATTR_LEAF_MAGIC); ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC); - leaf1 = blk1->bp->data; - leaf2 = blk2->bp->data; - ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); + leaf1 = blk1->bp->b_addr; + leaf2 = blk2->bp->b_addr; + xfs_attr3_leaf_hdr_from_disk(&ichdr1, leaf1); + xfs_attr3_leaf_hdr_from_disk(&ichdr2, leaf2); + ASSERT(ichdr2.count == 0); args = state->args; + trace_xfs_attr_leaf_rebalance(args); + /* * Check ordering of blocks, reverse if it makes things simpler. * @@ -1059,16 +1379,23 @@ * second block, this code should never set "swap". */ swap = 0; - if (xfs_attr_leaf_order(blk1->bp, blk2->bp)) { + if (xfs_attr3_leaf_order(blk1->bp, &ichdr1, blk2->bp, &ichdr2)) { + struct xfs_da_state_blk *tmp_blk; + struct xfs_attr3_icleaf_hdr tmp_ichdr; + tmp_blk = blk1; blk1 = blk2; blk2 = tmp_blk; - leaf1 = blk1->bp->data; - leaf2 = blk2->bp->data; + + /* struct copies to swap them rather than reconverting */ + tmp_ichdr = ichdr1; + ichdr1 = ichdr2; + ichdr2 = tmp_ichdr; + + leaf1 = blk1->bp->b_addr; + leaf2 = blk2->bp->b_addr; swap = 1; } - hdr1 = &leaf1->hdr; - hdr2 = &leaf2->hdr; /* * Examine entries until we reduce the absolute difference in @@ -1078,82 +1405,80 @@ * "inleaf" is true if the new entry should be inserted into blk1. * If "swap" is also true, then reverse the sense of "inleaf". */ - state->inleaf = xfs_attr_leaf_figure_balance(state, blk1, blk2, - &count, &totallen); + state->inleaf = xfs_attr3_leaf_figure_balance(state, blk1, &ichdr1, + blk2, &ichdr2, + &count, &totallen); if (swap) state->inleaf = !state->inleaf; /* * Move any entries required from leaf to leaf: */ - if (count < be16_to_cpu(hdr1->count)) { + if (count < ichdr1.count) { /* * Figure the total bytes to be added to the destination leaf. */ /* number entries being moved */ - count = be16_to_cpu(hdr1->count) - count; - space = be16_to_cpu(hdr1->usedbytes) - totallen; + count = ichdr1.count - count; + space = ichdr1.usedbytes - totallen; space += count * sizeof(xfs_attr_leaf_entry_t); /* * leaf2 is the destination, compact it if it looks tight. */ - max = be16_to_cpu(hdr2->firstused) - - sizeof(xfs_attr_leaf_hdr_t); - max -= be16_to_cpu(hdr2->count) * sizeof(xfs_attr_leaf_entry_t); - if (space > max) { - xfs_attr_leaf_compact(args->trans, blk2->bp); - } + max = ichdr2.firstused - xfs_attr3_leaf_hdr_size(leaf1); + max -= ichdr2.count * sizeof(xfs_attr_leaf_entry_t); + if (space > max) + xfs_attr3_leaf_compact(args, &ichdr2, blk2->bp); /* * Move high entries from leaf1 to low end of leaf2. */ - xfs_attr_leaf_moveents(leaf1, be16_to_cpu(hdr1->count) - count, - leaf2, 0, count, state->mp); + xfs_attr3_leaf_moveents(leaf1, &ichdr1, ichdr1.count - count, + leaf2, &ichdr2, 0, count, state->mp); - xfs_da_log_buf(args->trans, blk1->bp, 0, state->blocksize-1); - xfs_da_log_buf(args->trans, blk2->bp, 0, state->blocksize-1); - } else if (count > be16_to_cpu(hdr1->count)) { + } else if (count > ichdr1.count) { /* * I assert that since all callers pass in an empty * second buffer, this code should never execute. */ + ASSERT(0); /* * Figure the total bytes to be added to the destination leaf. */ /* number entries being moved */ - count -= be16_to_cpu(hdr1->count); - space = totallen - be16_to_cpu(hdr1->usedbytes); + count -= ichdr1.count; + space = totallen - ichdr1.usedbytes; space += count * sizeof(xfs_attr_leaf_entry_t); /* * leaf1 is the destination, compact it if it looks tight. */ - max = be16_to_cpu(hdr1->firstused) - - sizeof(xfs_attr_leaf_hdr_t); - max -= be16_to_cpu(hdr1->count) * sizeof(xfs_attr_leaf_entry_t); - if (space > max) { - xfs_attr_leaf_compact(args->trans, blk1->bp); - } + max = ichdr1.firstused - xfs_attr3_leaf_hdr_size(leaf1); + max -= ichdr1.count * sizeof(xfs_attr_leaf_entry_t); + if (space > max) + xfs_attr3_leaf_compact(args, &ichdr1, blk1->bp); /* * Move low entries from leaf2 to high end of leaf1. */ - xfs_attr_leaf_moveents(leaf2, 0, leaf1, - be16_to_cpu(hdr1->count), count, state->mp); - - xfs_da_log_buf(args->trans, blk1->bp, 0, state->blocksize-1); - xfs_da_log_buf(args->trans, blk2->bp, 0, state->blocksize-1); + xfs_attr3_leaf_moveents(leaf2, &ichdr2, 0, leaf1, &ichdr1, + ichdr1.count, count, state->mp); } + xfs_attr3_leaf_hdr_to_disk(leaf1, &ichdr1); + xfs_attr3_leaf_hdr_to_disk(leaf2, &ichdr2); + xfs_trans_log_buf(args->trans, blk1->bp, 0, state->blocksize-1); + xfs_trans_log_buf(args->trans, blk2->bp, 0, state->blocksize-1); + /* * Copy out last hashval in each block for B-tree code. */ - blk1->hashval = be32_to_cpu( - leaf1->entries[be16_to_cpu(leaf1->hdr.count)-1].hashval); - blk2->hashval = be32_to_cpu( - leaf2->entries[be16_to_cpu(leaf2->hdr.count)-1].hashval); + entries1 = xfs_attr3_leaf_entryp(leaf1); + entries2 = xfs_attr3_leaf_entryp(leaf2); + blk1->hashval = be32_to_cpu(entries1[ichdr1.count - 1].hashval); + blk2->hashval = be32_to_cpu(entries2[ichdr2.count - 1].hashval); /* * Adjust the expected index for insertion. @@ -1167,22 +1492,35 @@ * inserting. The index/blkno fields refer to the "old" entry, * while the index2/blkno2 fields refer to the "new" entry. */ - if (blk1->index > be16_to_cpu(leaf1->hdr.count)) { + if (blk1->index > ichdr1.count) { ASSERT(state->inleaf == 0); - blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count); + blk2->index = blk1->index - ichdr1.count; args->index = args->index2 = blk2->index; args->blkno = args->blkno2 = blk2->blkno; - } else if (blk1->index == be16_to_cpu(leaf1->hdr.count)) { + } else if (blk1->index == ichdr1.count) { if (state->inleaf) { args->index = blk1->index; args->blkno = blk1->blkno; args->index2 = 0; args->blkno2 = blk2->blkno; } else { - blk2->index = blk1->index - - be16_to_cpu(leaf1->hdr.count); - args->index = args->index2 = blk2->index; - args->blkno = args->blkno2 = blk2->blkno; + /* + * On a double leaf split, the original attr location + * is already stored in blkno2/index2, so don't + * overwrite it overwise we corrupt the tree. + */ + blk2->index = blk1->index - ichdr1.count; + args->index = blk2->index; + args->blkno = blk2->blkno; + if (!state->extravalid) { + /* + * set the new attr location to match the old + * one and let the higher level split code + * decide where in the leaf to place it. + */ + args->index2 = blk2->index; + args->blkno2 = blk2->blkno; + } } } else { ASSERT(state->inleaf == 1); @@ -1199,42 +1537,40 @@ * GROT: Do a double-split for this case? */ STATIC int -xfs_attr_leaf_figure_balance(xfs_da_state_t *state, - xfs_da_state_blk_t *blk1, - xfs_da_state_blk_t *blk2, - int *countarg, int *usedbytesarg) -{ - xfs_attr_leafblock_t *leaf1, *leaf2; - xfs_attr_leaf_hdr_t *hdr1, *hdr2; - xfs_attr_leaf_entry_t *entry; - int count, max, index, totallen, half; - int lastdelta, foundit, tmp; - - /* - * Set up environment. - */ - leaf1 = blk1->bp->data; - leaf2 = blk2->bp->data; - hdr1 = &leaf1->hdr; - hdr2 = &leaf2->hdr; - foundit = 0; - totallen = 0; +xfs_attr3_leaf_figure_balance( + struct xfs_da_state *state, + struct xfs_da_state_blk *blk1, + struct xfs_attr3_icleaf_hdr *ichdr1, + struct xfs_da_state_blk *blk2, + struct xfs_attr3_icleaf_hdr *ichdr2, + int *countarg, + int *usedbytesarg) +{ + struct xfs_attr_leafblock *leaf1 = blk1->bp->b_addr; + struct xfs_attr_leafblock *leaf2 = blk2->bp->b_addr; + struct xfs_attr_leaf_entry *entry; + int count; + int max; + int index; + int totallen = 0; + int half; + int lastdelta; + int foundit = 0; + int tmp; /* * Examine entries until we reduce the absolute difference in * byte usage between the two blocks to a minimum. */ - max = be16_to_cpu(hdr1->count) + be16_to_cpu(hdr2->count); - half = (max+1) * sizeof(*entry); - half += be16_to_cpu(hdr1->usedbytes) + - be16_to_cpu(hdr2->usedbytes) + - xfs_attr_leaf_newentsize( - state->args->namelen, - state->args->valuelen, - state->blocksize, NULL); + max = ichdr1->count + ichdr2->count; + half = (max + 1) * sizeof(*entry); + half += ichdr1->usedbytes + ichdr2->usedbytes + + xfs_attr_leaf_newentsize(state->args->namelen, + state->args->valuelen, + state->blocksize, NULL); half /= 2; lastdelta = state->blocksize; - entry = &leaf1->entries[0]; + entry = xfs_attr3_leaf_entryp(leaf1); for (count = index = 0; count < max; entry++, index++, count++) { #define XFS_ATTR_ABS(A) (((A) < 0) ? -(A) : (A)) @@ -1257,9 +1593,9 @@ /* * Wrap around into the second block if necessary. */ - if (count == be16_to_cpu(hdr1->count)) { + if (count == ichdr1->count) { leaf1 = leaf2; - entry = &leaf1->entries[0]; + entry = xfs_attr3_leaf_entryp(leaf1); index = 0; } @@ -1290,7 +1626,7 @@ *countarg = count; *usedbytesarg = totallen; - return(foundit); + return foundit; } /*======================================================================== @@ -1309,14 +1645,22 @@ * GROT: allow for INCOMPLETE entries in calculation. */ int -xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action) -{ - xfs_attr_leafblock_t *leaf; - xfs_da_state_blk_t *blk; - xfs_da_blkinfo_t *info; - int count, bytes, forward, error, retval, i; - xfs_dablk_t blkno; - xfs_dabuf_t *bp; +xfs_attr3_leaf_toosmall( + struct xfs_da_state *state, + int *action) +{ + struct xfs_attr_leafblock *leaf; + struct xfs_da_state_blk *blk; + struct xfs_attr3_icleaf_hdr ichdr; + struct xfs_buf *bp; + xfs_dablk_t blkno; + int bytes; + int forward; + int error; + int retval; + int i; + + trace_xfs_attr_leaf_toosmall(state->args); /* * Check for the degenerate case of the block being over 50% full. @@ -1324,13 +1668,11 @@ * to coalesce with a sibling. */ blk = &state->path.blk[ state->path.active-1 ]; - info = blk->bp->data; - ASSERT(be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC); - leaf = (xfs_attr_leafblock_t *)info; - count = be16_to_cpu(leaf->hdr.count); - bytes = sizeof(xfs_attr_leaf_hdr_t) + - count * sizeof(xfs_attr_leaf_entry_t) + - be16_to_cpu(leaf->hdr.usedbytes); + leaf = blk->bp->b_addr; + xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); + bytes = xfs_attr3_leaf_hdr_size(leaf) + + ichdr.count * sizeof(xfs_attr_leaf_entry_t) + + ichdr.usedbytes; if (bytes > (state->blocksize >> 1)) { *action = 0; /* blk over 50%, don't try to join */ return(0); @@ -1342,14 +1684,14 @@ * coalesce it with a sibling block. We choose (arbitrarily) * to merge with the forward block unless it is NULL. */ - if (count == 0) { + if (ichdr.count == 0) { /* * Make altpath point to the block we want to keep and * path point to the block we want to drop (this one). */ - forward = (info->forw != 0); + forward = (ichdr.forw != 0); memcpy(&state->altpath, &state->path, sizeof(state->path)); - error = xfs_da_path_shift(state, &state->altpath, forward, + error = xfs_da3_path_shift(state, &state->altpath, forward, 0, &retval); if (error) return(error); @@ -1358,7 +1700,7 @@ } else { *action = 2; } - return(0); + return 0; } /* @@ -1369,31 +1711,29 @@ * to shrink an attribute list over time. */ /* start with smaller blk num */ - forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back)); + forward = ichdr.forw < ichdr.back; for (i = 0; i < 2; forward = !forward, i++) { + struct xfs_attr3_icleaf_hdr ichdr2; if (forward) - blkno = be32_to_cpu(info->forw); + blkno = ichdr.forw; else - blkno = be32_to_cpu(info->back); + blkno = ichdr.back; if (blkno == 0) continue; - error = xfs_da_read_buf(state->args->trans, state->args->dp, - blkno, -1, &bp, XFS_ATTR_FORK); + error = xfs_attr3_leaf_read(state->args->trans, state->args->dp, + blkno, -1, &bp); if (error) return(error); - ASSERT(bp != NULL); - leaf = (xfs_attr_leafblock_t *)info; - count = be16_to_cpu(leaf->hdr.count); - bytes = state->blocksize - (state->blocksize>>2); - bytes -= be16_to_cpu(leaf->hdr.usedbytes); - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - count += be16_to_cpu(leaf->hdr.count); - bytes -= be16_to_cpu(leaf->hdr.usedbytes); - bytes -= count * sizeof(xfs_attr_leaf_entry_t); - bytes -= sizeof(xfs_attr_leaf_hdr_t); - xfs_da_brelse(state->args->trans, bp); + xfs_attr3_leaf_hdr_from_disk(&ichdr2, bp->b_addr); + + bytes = state->blocksize - (state->blocksize >> 2) - + ichdr.usedbytes - ichdr2.usedbytes - + ((ichdr.count + ichdr2.count) * + sizeof(xfs_attr_leaf_entry_t)) - + xfs_attr3_leaf_hdr_size(leaf); + + xfs_trans_brelse(state->args->trans, bp); if (bytes >= 0) break; /* fits with at least 25% to spare */ } @@ -1408,10 +1748,10 @@ */ memcpy(&state->altpath, &state->path, sizeof(state->path)); if (blkno < blk->blkno) { - error = xfs_da_path_shift(state, &state->altpath, forward, + error = xfs_da3_path_shift(state, &state->altpath, forward, 0, &retval); } else { - error = xfs_da_path_shift(state, &state->path, forward, + error = xfs_da3_path_shift(state, &state->path, forward, 0, &retval); } if (error) @@ -1431,28 +1771,35 @@ * If two leaves are 37% full, when combined they will leave 25% free. */ int -xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) -{ - xfs_attr_leafblock_t *leaf; - xfs_attr_leaf_hdr_t *hdr; - xfs_attr_leaf_map_t *map; - xfs_attr_leaf_entry_t *entry; - int before, after, smallest, entsize; - int tablesize, tmp, i; - xfs_mount_t *mp; +xfs_attr3_leaf_remove( + struct xfs_buf *bp, + struct xfs_da_args *args) +{ + struct xfs_attr_leafblock *leaf; + struct xfs_attr3_icleaf_hdr ichdr; + struct xfs_attr_leaf_entry *entry; + struct xfs_mount *mp = args->trans->t_mountp; + int before; + int after; + int smallest; + int entsize; + int tablesize; + int tmp; + int i; + + trace_xfs_attr_leaf_remove(args); + + leaf = bp->b_addr; + xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); + + ASSERT(ichdr.count > 0 && ichdr.count < XFS_LBSIZE(mp) / 8); + ASSERT(args->index >= 0 && args->index < ichdr.count); + ASSERT(ichdr.firstused >= ichdr.count * sizeof(*entry) + + xfs_attr3_leaf_hdr_size(leaf)); - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - hdr = &leaf->hdr; - mp = args->trans->t_mountp; - ASSERT((be16_to_cpu(hdr->count) > 0) - && (be16_to_cpu(hdr->count) < (XFS_LBSIZE(mp)/8))); - ASSERT((args->index >= 0) - && (args->index < be16_to_cpu(hdr->count))); - ASSERT(be16_to_cpu(hdr->firstused) >= - ((be16_to_cpu(hdr->count) * sizeof(*entry)) + sizeof(*hdr))); - entry = &leaf->entries[args->index]; - ASSERT(be16_to_cpu(entry->nameidx) >= be16_to_cpu(hdr->firstused)); + entry = &xfs_attr3_leaf_entryp(leaf)[args->index]; + + ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused); ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); /* @@ -1461,30 +1808,28 @@ * find smallest free region in case we need to replace it, * adjust any map that borders the entry table, */ - tablesize = be16_to_cpu(hdr->count) * sizeof(xfs_attr_leaf_entry_t) - + sizeof(xfs_attr_leaf_hdr_t); - map = &hdr->freemap[0]; - tmp = be16_to_cpu(map->size); + tablesize = ichdr.count * sizeof(xfs_attr_leaf_entry_t) + + xfs_attr3_leaf_hdr_size(leaf); + tmp = ichdr.freemap[0].size; before = after = -1; smallest = XFS_ATTR_LEAF_MAPSIZE - 1; entsize = xfs_attr_leaf_entsize(leaf, args->index); - for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) { - ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp)); - ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); - if (be16_to_cpu(map->base) == tablesize) { - be16_add_cpu(&map->base, - -((int)sizeof(xfs_attr_leaf_entry_t))); - be16_add_cpu(&map->size, sizeof(xfs_attr_leaf_entry_t)); + for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { + ASSERT(ichdr.freemap[i].base < XFS_LBSIZE(mp)); + ASSERT(ichdr.freemap[i].size < XFS_LBSIZE(mp)); + if (ichdr.freemap[i].base == tablesize) { + ichdr.freemap[i].base -= sizeof(xfs_attr_leaf_entry_t); + ichdr.freemap[i].size += sizeof(xfs_attr_leaf_entry_t); } - if ((be16_to_cpu(map->base) + be16_to_cpu(map->size)) - == be16_to_cpu(entry->nameidx)) { + if (ichdr.freemap[i].base + ichdr.freemap[i].size == + be16_to_cpu(entry->nameidx)) { before = i; - } else if (be16_to_cpu(map->base) - == (be16_to_cpu(entry->nameidx) + entsize)) { + } else if (ichdr.freemap[i].base == + (be16_to_cpu(entry->nameidx) + entsize)) { after = i; - } else if (be16_to_cpu(map->size) < tmp) { - tmp = be16_to_cpu(map->size); + } else if (ichdr.freemap[i].size < tmp) { + tmp = ichdr.freemap[i].size; smallest = i; } } @@ -1495,36 +1840,30 @@ */ if ((before >= 0) || (after >= 0)) { if ((before >= 0) && (after >= 0)) { - map = &hdr->freemap[before]; - be16_add_cpu(&map->size, entsize); - be16_add_cpu(&map->size, - be16_to_cpu(hdr->freemap[after].size)); - hdr->freemap[after].base = 0; - hdr->freemap[after].size = 0; + ichdr.freemap[before].size += entsize; + ichdr.freemap[before].size += ichdr.freemap[after].size; + ichdr.freemap[after].base = 0; + ichdr.freemap[after].size = 0; } else if (before >= 0) { - map = &hdr->freemap[before]; - be16_add_cpu(&map->size, entsize); + ichdr.freemap[before].size += entsize; } else { - map = &hdr->freemap[after]; - /* both on-disk, don't endian flip twice */ - map->base = entry->nameidx; - be16_add_cpu(&map->size, entsize); + ichdr.freemap[after].base = be16_to_cpu(entry->nameidx); + ichdr.freemap[after].size += entsize; } } else { /* * Replace smallest region (if it is smaller than free'd entry) */ - map = &hdr->freemap[smallest]; - if (be16_to_cpu(map->size) < entsize) { - map->base = cpu_to_be16(be16_to_cpu(entry->nameidx)); - map->size = cpu_to_be16(entsize); + if (ichdr.freemap[smallest].size < entsize) { + ichdr.freemap[smallest].base = be16_to_cpu(entry->nameidx); + ichdr.freemap[smallest].size = entsize; } } /* * Did we remove the first entry? */ - if (be16_to_cpu(entry->nameidx) == be16_to_cpu(hdr->firstused)) + if (be16_to_cpu(entry->nameidx) == ichdr.firstused) smallest = 1; else smallest = 0; @@ -1532,20 +1871,20 @@ /* * Compress the remaining entries and zero out the removed stuff. */ - memset(xfs_attr_leaf_name(leaf, args->index), 0, entsize); - be16_add_cpu(&hdr->usedbytes, -entsize); - xfs_da_log_buf(args->trans, bp, - XFS_DA_LOGRANGE(leaf, xfs_attr_leaf_name(leaf, args->index), + memset(xfs_attr3_leaf_name(leaf, args->index), 0, entsize); + ichdr.usedbytes -= entsize; + xfs_trans_log_buf(args->trans, bp, + XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index), entsize)); - tmp = (be16_to_cpu(hdr->count) - args->index) - * sizeof(xfs_attr_leaf_entry_t); - memmove((char *)entry, (char *)(entry+1), tmp); - be16_add_cpu(&hdr->count, -1); - xfs_da_log_buf(args->trans, bp, - XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); - entry = &leaf->entries[be16_to_cpu(hdr->count)]; - memset((char *)entry, 0, sizeof(xfs_attr_leaf_entry_t)); + tmp = (ichdr.count - args->index) * sizeof(xfs_attr_leaf_entry_t); + memmove(entry, entry + 1, tmp); + ichdr.count--; + xfs_trans_log_buf(args->trans, bp, + XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(xfs_attr_leaf_entry_t))); + + entry = &xfs_attr3_leaf_entryp(leaf)[ichdr.count]; + memset(entry, 0, sizeof(xfs_attr_leaf_entry_t)); /* * If we removed the first entry, re-find the first used byte @@ -1555,128 +1894,140 @@ */ if (smallest) { tmp = XFS_LBSIZE(mp); - entry = &leaf->entries[0]; - for (i = be16_to_cpu(hdr->count)-1; i >= 0; entry++, i--) { - ASSERT(be16_to_cpu(entry->nameidx) >= - be16_to_cpu(hdr->firstused)); + entry = xfs_attr3_leaf_entryp(leaf); + for (i = ichdr.count - 1; i >= 0; entry++, i--) { + ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused); ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); if (be16_to_cpu(entry->nameidx) < tmp) tmp = be16_to_cpu(entry->nameidx); } - hdr->firstused = cpu_to_be16(tmp); - if (!hdr->firstused) { - hdr->firstused = cpu_to_be16( - tmp - XFS_ATTR_LEAF_NAME_ALIGN); - } + ichdr.firstused = tmp; + if (!ichdr.firstused) + ichdr.firstused = tmp - XFS_ATTR_LEAF_NAME_ALIGN; } else { - hdr->holes = 1; /* mark as needing compaction */ + ichdr.holes = 1; /* mark as needing compaction */ } - xfs_da_log_buf(args->trans, bp, - XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); + xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr); + xfs_trans_log_buf(args->trans, bp, + XFS_DA_LOGRANGE(leaf, &leaf->hdr, + xfs_attr3_leaf_hdr_size(leaf))); /* * Check if leaf is less than 50% full, caller may want to * "join" the leaf with a sibling if so. */ - tmp = sizeof(xfs_attr_leaf_hdr_t); - tmp += be16_to_cpu(leaf->hdr.count) * sizeof(xfs_attr_leaf_entry_t); - tmp += be16_to_cpu(leaf->hdr.usedbytes); - return(tmp < mp->m_attr_magicpct); /* leaf is < 37% full */ + tmp = ichdr.usedbytes + xfs_attr3_leaf_hdr_size(leaf) + + ichdr.count * sizeof(xfs_attr_leaf_entry_t); + + return tmp < mp->m_attr_magicpct; /* leaf is < 37% full */ } /* * Move all the attribute list entries from drop_leaf into save_leaf. */ void -xfs_attr_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, - xfs_da_state_blk_t *save_blk) -{ - xfs_attr_leafblock_t *drop_leaf, *save_leaf, *tmp_leaf; - xfs_attr_leaf_hdr_t *drop_hdr, *save_hdr, *tmp_hdr; - xfs_mount_t *mp; - char *tmpbuffer; - - /* - * Set up environment. - */ - mp = state->mp; - ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC); - ASSERT(save_blk->magic == XFS_ATTR_LEAF_MAGIC); - drop_leaf = drop_blk->bp->data; - save_leaf = save_blk->bp->data; - ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - drop_hdr = &drop_leaf->hdr; - save_hdr = &save_leaf->hdr; +xfs_attr3_leaf_unbalance( + struct xfs_da_state *state, + struct xfs_da_state_blk *drop_blk, + struct xfs_da_state_blk *save_blk) +{ + struct xfs_attr_leafblock *drop_leaf = drop_blk->bp->b_addr; + struct xfs_attr_leafblock *save_leaf = save_blk->bp->b_addr; + struct xfs_attr3_icleaf_hdr drophdr; + struct xfs_attr3_icleaf_hdr savehdr; + struct xfs_attr_leaf_entry *entry; + struct xfs_mount *mp = state->mp; + + trace_xfs_attr_leaf_unbalance(state->args); + + drop_leaf = drop_blk->bp->b_addr; + save_leaf = save_blk->bp->b_addr; + xfs_attr3_leaf_hdr_from_disk(&drophdr, drop_leaf); + xfs_attr3_leaf_hdr_from_disk(&savehdr, save_leaf); + entry = xfs_attr3_leaf_entryp(drop_leaf); /* * Save last hashval from dying block for later Btree fixup. */ - drop_blk->hashval = be32_to_cpu( - drop_leaf->entries[be16_to_cpu(drop_leaf->hdr.count)-1].hashval); + drop_blk->hashval = be32_to_cpu(entry[drophdr.count - 1].hashval); /* * Check if we need a temp buffer, or can we do it in place. * Note that we don't check "leaf" for holes because we will * always be dropping it, toosmall() decided that for us already. */ - if (save_hdr->holes == 0) { + if (savehdr.holes == 0) { /* * dest leaf has no holes, so we add there. May need * to make some room in the entry array. */ - if (xfs_attr_leaf_order(save_blk->bp, drop_blk->bp)) { - xfs_attr_leaf_moveents(drop_leaf, 0, save_leaf, 0, - be16_to_cpu(drop_hdr->count), mp); + if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, + drop_blk->bp, &drophdr)) { + xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, + save_leaf, &savehdr, 0, + drophdr.count, mp); } else { - xfs_attr_leaf_moveents(drop_leaf, 0, save_leaf, - be16_to_cpu(save_hdr->count), - be16_to_cpu(drop_hdr->count), mp); + xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, + save_leaf, &savehdr, + savehdr.count, drophdr.count, mp); } } else { /* * Destination has holes, so we make a temporary copy * of the leaf and add them both to that. */ - tmpbuffer = kmem_alloc(state->blocksize, KM_SLEEP); - ASSERT(tmpbuffer != NULL); - memset(tmpbuffer, 0, state->blocksize); - tmp_leaf = (xfs_attr_leafblock_t *)tmpbuffer; - tmp_hdr = &tmp_leaf->hdr; - tmp_hdr->info = save_hdr->info; /* struct copy */ - tmp_hdr->count = 0; - tmp_hdr->firstused = cpu_to_be16(state->blocksize); - if (!tmp_hdr->firstused) { - tmp_hdr->firstused = cpu_to_be16( - state->blocksize - XFS_ATTR_LEAF_NAME_ALIGN); - } - tmp_hdr->usedbytes = 0; - if (xfs_attr_leaf_order(save_blk->bp, drop_blk->bp)) { - xfs_attr_leaf_moveents(drop_leaf, 0, tmp_leaf, 0, - be16_to_cpu(drop_hdr->count), mp); - xfs_attr_leaf_moveents(save_leaf, 0, tmp_leaf, - be16_to_cpu(tmp_leaf->hdr.count), - be16_to_cpu(save_hdr->count), mp); + struct xfs_attr_leafblock *tmp_leaf; + struct xfs_attr3_icleaf_hdr tmphdr; + + tmp_leaf = kmem_zalloc(state->blocksize, KM_SLEEP); + + /* + * Copy the header into the temp leaf so that all the stuff + * not in the incore header is present and gets copied back in + * once we've moved all the entries. + */ + memcpy(tmp_leaf, save_leaf, xfs_attr3_leaf_hdr_size(save_leaf)); + + memset(&tmphdr, 0, sizeof(tmphdr)); + tmphdr.magic = savehdr.magic; + tmphdr.forw = savehdr.forw; + tmphdr.back = savehdr.back; + tmphdr.firstused = state->blocksize; + + /* write the header to the temp buffer to initialise it */ + xfs_attr3_leaf_hdr_to_disk(tmp_leaf, &tmphdr); + + if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, + drop_blk->bp, &drophdr)) { + xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, + tmp_leaf, &tmphdr, 0, + drophdr.count, mp); + xfs_attr3_leaf_moveents(save_leaf, &savehdr, 0, + tmp_leaf, &tmphdr, tmphdr.count, + savehdr.count, mp); } else { - xfs_attr_leaf_moveents(save_leaf, 0, tmp_leaf, 0, - be16_to_cpu(save_hdr->count), mp); - xfs_attr_leaf_moveents(drop_leaf, 0, tmp_leaf, - be16_to_cpu(tmp_leaf->hdr.count), - be16_to_cpu(drop_hdr->count), mp); - } - memcpy((char *)save_leaf, (char *)tmp_leaf, state->blocksize); - kmem_free(tmpbuffer); + xfs_attr3_leaf_moveents(save_leaf, &savehdr, 0, + tmp_leaf, &tmphdr, 0, + savehdr.count, mp); + xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, + tmp_leaf, &tmphdr, tmphdr.count, + drophdr.count, mp); + } + memcpy(save_leaf, tmp_leaf, state->blocksize); + savehdr = tmphdr; /* struct copy */ + kmem_free(tmp_leaf); } - xfs_da_log_buf(state->args->trans, save_blk->bp, 0, + xfs_attr3_leaf_hdr_to_disk(save_leaf, &savehdr); + xfs_trans_log_buf(state->args->trans, save_blk->bp, 0, state->blocksize - 1); /* * Copy out last hashval in each block for B-tree code. */ - save_blk->hashval = be32_to_cpu( - save_leaf->entries[be16_to_cpu(save_leaf->hdr.count)-1].hashval); + entry = xfs_attr3_leaf_entryp(save_leaf); + save_blk->hashval = be32_to_cpu(entry[savehdr.count - 1].hashval); } /*======================================================================== @@ -1697,27 +2048,33 @@ * Don't change the args->value unless we find the attribute. */ int -xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) -{ - xfs_attr_leafblock_t *leaf; - xfs_attr_leaf_entry_t *entry; - xfs_attr_leaf_name_local_t *name_loc; - xfs_attr_leaf_name_remote_t *name_rmt; - int probe, span; - xfs_dahash_t hashval; - - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - ASSERT(be16_to_cpu(leaf->hdr.count) - < (XFS_LBSIZE(args->dp->i_mount)/8)); +xfs_attr3_leaf_lookup_int( + struct xfs_buf *bp, + struct xfs_da_args *args) +{ + struct xfs_attr_leafblock *leaf; + struct xfs_attr3_icleaf_hdr ichdr; + struct xfs_attr_leaf_entry *entry; + struct xfs_attr_leaf_entry *entries; + struct xfs_attr_leaf_name_local *name_loc; + struct xfs_attr_leaf_name_remote *name_rmt; + xfs_dahash_t hashval; + int probe; + int span; + + trace_xfs_attr_leaf_lookup(args); + + leaf = bp->b_addr; + xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); + entries = xfs_attr3_leaf_entryp(leaf); + ASSERT(ichdr.count < XFS_LBSIZE(args->dp->i_mount) / 8); /* * Binary search. (note: small blocks will skip this loop) */ hashval = args->hashval; - probe = span = be16_to_cpu(leaf->hdr.count) / 2; - for (entry = &leaf->entries[probe]; span > 4; - entry = &leaf->entries[probe]) { + probe = span = ichdr.count / 2; + for (entry = &entries[probe]; span > 4; entry = &entries[probe]) { span /= 2; if (be32_to_cpu(entry->hashval) < hashval) probe += span; @@ -1726,35 +2083,31 @@ else break; } - ASSERT((probe >= 0) && - (!leaf->hdr.count - || (probe < be16_to_cpu(leaf->hdr.count)))); - ASSERT((span <= 4) || (be32_to_cpu(entry->hashval) == hashval)); + ASSERT(probe >= 0 && (!ichdr.count || probe < ichdr.count)); + ASSERT(span <= 4 || be32_to_cpu(entry->hashval) == hashval); /* * Since we may have duplicate hashval's, find the first matching * hashval in the leaf. */ - while ((probe > 0) && (be32_to_cpu(entry->hashval) >= hashval)) { + while (probe > 0 && be32_to_cpu(entry->hashval) >= hashval) { entry--; probe--; } - while ((probe < be16_to_cpu(leaf->hdr.count)) && - (be32_to_cpu(entry->hashval) < hashval)) { + while (probe < ichdr.count && + be32_to_cpu(entry->hashval) < hashval) { entry++; probe++; } - if ((probe == be16_to_cpu(leaf->hdr.count)) || - (be32_to_cpu(entry->hashval) != hashval)) { + if (probe == ichdr.count || be32_to_cpu(entry->hashval) != hashval) { args->index = probe; - return(XFS_ERROR(ENOATTR)); + return XFS_ERROR(ENOATTR); } /* * Duplicate keys may be present, so search all of them for a match. */ - for ( ; (probe < be16_to_cpu(leaf->hdr.count)) && - (be32_to_cpu(entry->hashval) == hashval); + for (; probe < ichdr.count && (be32_to_cpu(entry->hashval) == hashval); entry++, probe++) { /* * GROT: Add code to remove incomplete entries. @@ -1768,33 +2121,36 @@ continue; } if (entry->flags & XFS_ATTR_LOCAL) { - name_loc = xfs_attr_leaf_name_local(leaf, probe); + name_loc = xfs_attr3_leaf_name_local(leaf, probe); if (name_loc->namelen != args->namelen) continue; - if (memcmp(args->name, (char *)name_loc->nameval, args->namelen) != 0) + if (memcmp(args->name, name_loc->nameval, + args->namelen) != 0) continue; if (!xfs_attr_namesp_match(args->flags, entry->flags)) continue; args->index = probe; - return(XFS_ERROR(EEXIST)); + return XFS_ERROR(EEXIST); } else { - name_rmt = xfs_attr_leaf_name_remote(leaf, probe); + name_rmt = xfs_attr3_leaf_name_remote(leaf, probe); if (name_rmt->namelen != args->namelen) continue; - if (memcmp(args->name, (char *)name_rmt->name, - args->namelen) != 0) + if (memcmp(args->name, name_rmt->name, + args->namelen) != 0) continue; if (!xfs_attr_namesp_match(args->flags, entry->flags)) continue; args->index = probe; + args->valuelen = be32_to_cpu(name_rmt->valuelen); args->rmtblkno = be32_to_cpu(name_rmt->valueblk); - args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, - be32_to_cpu(name_rmt->valuelen)); - return(XFS_ERROR(EEXIST)); + args->rmtblkcnt = xfs_attr3_rmt_blocks( + args->dp->i_mount, + args->valuelen); + return XFS_ERROR(EEXIST); } } args->index = probe; - return(XFS_ERROR(ENOATTR)); + return XFS_ERROR(ENOATTR); } /* @@ -1802,54 +2158,57 @@ * list structure. */ int -xfs_attr_leaf_getvalue(xfs_dabuf_t *bp, xfs_da_args_t *args) -{ - int valuelen; - xfs_attr_leafblock_t *leaf; - xfs_attr_leaf_entry_t *entry; - xfs_attr_leaf_name_local_t *name_loc; - xfs_attr_leaf_name_remote_t *name_rmt; - - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - ASSERT(be16_to_cpu(leaf->hdr.count) - < (XFS_LBSIZE(args->dp->i_mount)/8)); - ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); +xfs_attr3_leaf_getvalue( + struct xfs_buf *bp, + struct xfs_da_args *args) +{ + struct xfs_attr_leafblock *leaf; + struct xfs_attr3_icleaf_hdr ichdr; + struct xfs_attr_leaf_entry *entry; + struct xfs_attr_leaf_name_local *name_loc; + struct xfs_attr_leaf_name_remote *name_rmt; + int valuelen; + + leaf = bp->b_addr; + xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); + ASSERT(ichdr.count < XFS_LBSIZE(args->dp->i_mount) / 8); + ASSERT(args->index < ichdr.count); - entry = &leaf->entries[args->index]; + entry = &xfs_attr3_leaf_entryp(leaf)[args->index]; if (entry->flags & XFS_ATTR_LOCAL) { - name_loc = xfs_attr_leaf_name_local(leaf, args->index); + name_loc = xfs_attr3_leaf_name_local(leaf, args->index); ASSERT(name_loc->namelen == args->namelen); ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0); valuelen = be16_to_cpu(name_loc->valuelen); if (args->flags & ATTR_KERNOVAL) { args->valuelen = valuelen; - return(0); + return 0; } if (args->valuelen < valuelen) { args->valuelen = valuelen; - return(XFS_ERROR(ERANGE)); + return XFS_ERROR(ERANGE); } args->valuelen = valuelen; memcpy(args->value, &name_loc->nameval[args->namelen], valuelen); } else { - name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); + name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index); ASSERT(name_rmt->namelen == args->namelen); ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0); valuelen = be32_to_cpu(name_rmt->valuelen); args->rmtblkno = be32_to_cpu(name_rmt->valueblk); - args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, valuelen); + args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount, + valuelen); if (args->flags & ATTR_KERNOVAL) { args->valuelen = valuelen; - return(0); + return 0; } if (args->valuelen < valuelen) { args->valuelen = valuelen; - return(XFS_ERROR(ERANGE)); + return XFS_ERROR(ERANGE); } args->valuelen = valuelen; } - return(0); + return 0; } /*======================================================================== @@ -1862,13 +2221,21 @@ */ /*ARGSUSED*/ STATIC void -xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s, - xfs_attr_leafblock_t *leaf_d, int start_d, - int count, xfs_mount_t *mp) -{ - xfs_attr_leaf_hdr_t *hdr_s, *hdr_d; - xfs_attr_leaf_entry_t *entry_s, *entry_d; - int desti, tmp, i; +xfs_attr3_leaf_moveents( + struct xfs_attr_leafblock *leaf_s, + struct xfs_attr3_icleaf_hdr *ichdr_s, + int start_s, + struct xfs_attr_leafblock *leaf_d, + struct xfs_attr3_icleaf_hdr *ichdr_d, + int start_d, + int count, + struct xfs_mount *mp) +{ + struct xfs_attr_leaf_entry *entry_s; + struct xfs_attr_leaf_entry *entry_d; + int desti; + int tmp; + int i; /* * Check for nothing to do. @@ -1879,45 +2246,41 @@ /* * Set up environment. */ - ASSERT(be16_to_cpu(leaf_s->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - ASSERT(be16_to_cpu(leaf_d->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - hdr_s = &leaf_s->hdr; - hdr_d = &leaf_d->hdr; - ASSERT((be16_to_cpu(hdr_s->count) > 0) && - (be16_to_cpu(hdr_s->count) < (XFS_LBSIZE(mp)/8))); - ASSERT(be16_to_cpu(hdr_s->firstused) >= - ((be16_to_cpu(hdr_s->count) - * sizeof(*entry_s))+sizeof(*hdr_s))); - ASSERT(be16_to_cpu(hdr_d->count) < (XFS_LBSIZE(mp)/8)); - ASSERT(be16_to_cpu(hdr_d->firstused) >= - ((be16_to_cpu(hdr_d->count) - * sizeof(*entry_d))+sizeof(*hdr_d))); - - ASSERT(start_s < be16_to_cpu(hdr_s->count)); - ASSERT(start_d <= be16_to_cpu(hdr_d->count)); - ASSERT(count <= be16_to_cpu(hdr_s->count)); + ASSERT(ichdr_s->magic == XFS_ATTR_LEAF_MAGIC || + ichdr_s->magic == XFS_ATTR3_LEAF_MAGIC); + ASSERT(ichdr_s->magic == ichdr_d->magic); + ASSERT(ichdr_s->count > 0 && ichdr_s->count < XFS_LBSIZE(mp) / 8); + ASSERT(ichdr_s->firstused >= (ichdr_s->count * sizeof(*entry_s)) + + xfs_attr3_leaf_hdr_size(leaf_s)); + ASSERT(ichdr_d->count < XFS_LBSIZE(mp) / 8); + ASSERT(ichdr_d->firstused >= (ichdr_d->count * sizeof(*entry_d)) + + xfs_attr3_leaf_hdr_size(leaf_d)); + + ASSERT(start_s < ichdr_s->count); + ASSERT(start_d <= ichdr_d->count); + ASSERT(count <= ichdr_s->count); + /* * Move the entries in the destination leaf up to make a hole? */ - if (start_d < be16_to_cpu(hdr_d->count)) { - tmp = be16_to_cpu(hdr_d->count) - start_d; + if (start_d < ichdr_d->count) { + tmp = ichdr_d->count - start_d; tmp *= sizeof(xfs_attr_leaf_entry_t); - entry_s = &leaf_d->entries[start_d]; - entry_d = &leaf_d->entries[start_d + count]; - memmove((char *)entry_d, (char *)entry_s, tmp); + entry_s = &xfs_attr3_leaf_entryp(leaf_d)[start_d]; + entry_d = &xfs_attr3_leaf_entryp(leaf_d)[start_d + count]; + memmove(entry_d, entry_s, tmp); } /* * Copy all entry's in the same (sorted) order, * but allocate attribute info packed and in sequence. */ - entry_s = &leaf_s->entries[start_s]; - entry_d = &leaf_d->entries[start_d]; + entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s]; + entry_d = &xfs_attr3_leaf_entryp(leaf_d)[start_d]; desti = start_d; for (i = 0; i < count; entry_s++, entry_d++, desti++, i++) { - ASSERT(be16_to_cpu(entry_s->nameidx) - >= be16_to_cpu(hdr_s->firstused)); + ASSERT(be16_to_cpu(entry_s->nameidx) >= ichdr_s->firstused); tmp = xfs_attr_leaf_entsize(leaf_s, start_s + i); #ifdef GROT /* @@ -1926,36 +2289,34 @@ * off for 6.2, should be revisited later. */ if (entry_s->flags & XFS_ATTR_INCOMPLETE) { /* skip partials? */ - memset(xfs_attr_leaf_name(leaf_s, start_s + i), 0, tmp); - be16_add_cpu(&hdr_s->usedbytes, -tmp); - be16_add_cpu(&hdr_s->count, -1); + memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp); + ichdr_s->usedbytes -= tmp; + ichdr_s->count -= 1; entry_d--; /* to compensate for ++ in loop hdr */ desti--; if ((start_s + i) < offset) result++; /* insertion index adjustment */ } else { #endif /* GROT */ - be16_add_cpu(&hdr_d->firstused, -tmp); + ichdr_d->firstused -= tmp; /* both on-disk, don't endian flip twice */ entry_d->hashval = entry_s->hashval; - /* both on-disk, don't endian flip twice */ - entry_d->nameidx = hdr_d->firstused; + entry_d->nameidx = cpu_to_be16(ichdr_d->firstused); entry_d->flags = entry_s->flags; ASSERT(be16_to_cpu(entry_d->nameidx) + tmp <= XFS_LBSIZE(mp)); - memmove(xfs_attr_leaf_name(leaf_d, desti), - xfs_attr_leaf_name(leaf_s, start_s + i), tmp); + memmove(xfs_attr3_leaf_name(leaf_d, desti), + xfs_attr3_leaf_name(leaf_s, start_s + i), tmp); ASSERT(be16_to_cpu(entry_s->nameidx) + tmp <= XFS_LBSIZE(mp)); - memset(xfs_attr_leaf_name(leaf_s, start_s + i), 0, tmp); - be16_add_cpu(&hdr_s->usedbytes, -tmp); - be16_add_cpu(&hdr_d->usedbytes, tmp); - be16_add_cpu(&hdr_s->count, -1); - be16_add_cpu(&hdr_d->count, 1); - tmp = be16_to_cpu(hdr_d->count) - * sizeof(xfs_attr_leaf_entry_t) - + sizeof(xfs_attr_leaf_hdr_t); - ASSERT(be16_to_cpu(hdr_d->firstused) >= tmp); + memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp); + ichdr_s->usedbytes -= tmp; + ichdr_d->usedbytes += tmp; + ichdr_s->count -= 1; + ichdr_d->count += 1; + tmp = ichdr_d->count * sizeof(xfs_attr_leaf_entry_t) + + xfs_attr3_leaf_hdr_size(leaf_d); + ASSERT(ichdr_d->firstused >= tmp); #ifdef GROT } #endif /* GROT */ @@ -1964,86 +2325,60 @@ /* * Zero out the entries we just copied. */ - if (start_s == be16_to_cpu(hdr_s->count)) { + if (start_s == ichdr_s->count) { tmp = count * sizeof(xfs_attr_leaf_entry_t); - entry_s = &leaf_s->entries[start_s]; + entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s]; ASSERT(((char *)entry_s + tmp) <= ((char *)leaf_s + XFS_LBSIZE(mp))); - memset((char *)entry_s, 0, tmp); + memset(entry_s, 0, tmp); } else { /* * Move the remaining entries down to fill the hole, * then zero the entries at the top. */ - tmp = be16_to_cpu(hdr_s->count) - count; - tmp *= sizeof(xfs_attr_leaf_entry_t); - entry_s = &leaf_s->entries[start_s + count]; - entry_d = &leaf_s->entries[start_s]; - memmove((char *)entry_d, (char *)entry_s, tmp); + tmp = (ichdr_s->count - count) * sizeof(xfs_attr_leaf_entry_t); + entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s + count]; + entry_d = &xfs_attr3_leaf_entryp(leaf_s)[start_s]; + memmove(entry_d, entry_s, tmp); tmp = count * sizeof(xfs_attr_leaf_entry_t); - entry_s = &leaf_s->entries[be16_to_cpu(hdr_s->count)]; + entry_s = &xfs_attr3_leaf_entryp(leaf_s)[ichdr_s->count]; ASSERT(((char *)entry_s + tmp) <= ((char *)leaf_s + XFS_LBSIZE(mp))); - memset((char *)entry_s, 0, tmp); + memset(entry_s, 0, tmp); } /* * Fill in the freemap information */ - hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t)); - be16_add_cpu(&hdr_d->freemap[0].base, be16_to_cpu(hdr_d->count) * - sizeof(xfs_attr_leaf_entry_t)); - hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused) - - be16_to_cpu(hdr_d->freemap[0].base)); - hdr_d->freemap[1].base = 0; - hdr_d->freemap[2].base = 0; - hdr_d->freemap[1].size = 0; - hdr_d->freemap[2].size = 0; - hdr_s->holes = 1; /* leaf may not be compact */ -} - -/* - * Compare two leaf blocks "order". - * Return 0 unless leaf2 should go before leaf1. - */ -int -xfs_attr_leaf_order(xfs_dabuf_t *leaf1_bp, xfs_dabuf_t *leaf2_bp) -{ - xfs_attr_leafblock_t *leaf1, *leaf2; - - leaf1 = leaf1_bp->data; - leaf2 = leaf2_bp->data; - ASSERT((be16_to_cpu(leaf1->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC) && - (be16_to_cpu(leaf2->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC)); - if ((be16_to_cpu(leaf1->hdr.count) > 0) && - (be16_to_cpu(leaf2->hdr.count) > 0) && - ((be32_to_cpu(leaf2->entries[0].hashval) < - be32_to_cpu(leaf1->entries[0].hashval)) || - (be32_to_cpu(leaf2->entries[ - be16_to_cpu(leaf2->hdr.count)-1].hashval) < - be32_to_cpu(leaf1->entries[ - be16_to_cpu(leaf1->hdr.count)-1].hashval)))) { - return(1); - } - return(0); + ichdr_d->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_d); + ichdr_d->freemap[0].base += ichdr_d->count * sizeof(xfs_attr_leaf_entry_t); + ichdr_d->freemap[0].size = ichdr_d->firstused - ichdr_d->freemap[0].base; + ichdr_d->freemap[1].base = 0; + ichdr_d->freemap[2].base = 0; + ichdr_d->freemap[1].size = 0; + ichdr_d->freemap[2].size = 0; + ichdr_s->holes = 1; /* leaf may not be compact */ } /* * Pick up the last hashvalue from a leaf block. */ xfs_dahash_t -xfs_attr_leaf_lasthash(xfs_dabuf_t *bp, int *count) +xfs_attr_leaf_lasthash( + struct xfs_buf *bp, + int *count) { - xfs_attr_leafblock_t *leaf; + struct xfs_attr3_icleaf_hdr ichdr; + struct xfs_attr_leaf_entry *entries; - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); + xfs_attr3_leaf_hdr_from_disk(&ichdr, bp->b_addr); + entries = xfs_attr3_leaf_entryp(bp->b_addr); if (count) - *count = be16_to_cpu(leaf->hdr.count); - if (!leaf->hdr.count) - return(0); - return be32_to_cpu(leaf->entries[be16_to_cpu(leaf->hdr.count)-1].hashval); + *count = ichdr.count; + if (!ichdr.count) + return 0; + return be32_to_cpu(entries[ichdr.count - 1].hashval); } /* @@ -2053,20 +2388,21 @@ STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index) { + struct xfs_attr_leaf_entry *entries; xfs_attr_leaf_name_local_t *name_loc; xfs_attr_leaf_name_remote_t *name_rmt; int size; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - if (leaf->entries[index].flags & XFS_ATTR_LOCAL) { - name_loc = xfs_attr_leaf_name_local(leaf, index); + entries = xfs_attr3_leaf_entryp(leaf); + if (entries[index].flags & XFS_ATTR_LOCAL) { + name_loc = xfs_attr3_leaf_name_local(leaf, index); size = xfs_attr_leaf_entsize_local(name_loc->namelen, be16_to_cpu(name_loc->valuelen)); } else { - name_rmt = xfs_attr_leaf_name_remote(leaf, index); + name_rmt = xfs_attr3_leaf_name_remote(leaf, index); size = xfs_attr_leaf_entsize_remote(name_rmt->namelen); } - return(size); + return size; } /* @@ -2091,9 +2427,10 @@ *local = 0; } } - return(size); + return size; } + /*======================================================================== * Manage the INCOMPLETE flag in a leaf entry *========================================================================*/ @@ -2102,43 +2439,44 @@ * Clear the INCOMPLETE flag on an entry in a leaf block. */ int -xfs_attr_leaf_clearflag(xfs_da_args_t *args) +xfs_attr3_leaf_clearflag( + struct xfs_da_args *args) { - xfs_attr_leafblock_t *leaf; - xfs_attr_leaf_entry_t *entry; - xfs_attr_leaf_name_remote_t *name_rmt; - xfs_dabuf_t *bp; - int error; + struct xfs_attr_leafblock *leaf; + struct xfs_attr_leaf_entry *entry; + struct xfs_attr_leaf_name_remote *name_rmt; + struct xfs_buf *bp; + int error; #ifdef DEBUG + struct xfs_attr3_icleaf_hdr ichdr; xfs_attr_leaf_name_local_t *name_loc; int namelen; char *name; #endif /* DEBUG */ + trace_xfs_attr_leaf_clearflag(args); /* * Set up the operation. */ - error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, - XFS_ATTR_FORK); - if (error) { + error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp); + if (error) return(error); - } - ASSERT(bp != NULL); - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); - ASSERT(args->index >= 0); - entry = &leaf->entries[ args->index ]; + leaf = bp->b_addr; + entry = &xfs_attr3_leaf_entryp(leaf)[args->index]; ASSERT(entry->flags & XFS_ATTR_INCOMPLETE); #ifdef DEBUG + xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); + ASSERT(args->index < ichdr.count); + ASSERT(args->index >= 0); + if (entry->flags & XFS_ATTR_LOCAL) { - name_loc = xfs_attr_leaf_name_local(leaf, args->index); + name_loc = xfs_attr3_leaf_name_local(leaf, args->index); namelen = name_loc->namelen; name = (char *)name_loc->nameval; } else { - name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); + name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index); namelen = name_rmt->namelen; name = (char *)name_rmt->name; } @@ -2148,18 +2486,17 @@ #endif /* DEBUG */ entry->flags &= ~XFS_ATTR_INCOMPLETE; - xfs_da_log_buf(args->trans, bp, + xfs_trans_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); if (args->rmtblkno) { ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0); - name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); + name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index); name_rmt->valueblk = cpu_to_be32(args->rmtblkno); name_rmt->valuelen = cpu_to_be32(args->valuelen); - xfs_da_log_buf(args->trans, bp, + xfs_trans_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); } - xfs_da_buf_done(bp); /* * Commit the flag value change and start the next trans in series. @@ -2171,42 +2508,46 @@ * Set the INCOMPLETE flag on an entry in a leaf block. */ int -xfs_attr_leaf_setflag(xfs_da_args_t *args) +xfs_attr3_leaf_setflag( + struct xfs_da_args *args) { - xfs_attr_leafblock_t *leaf; - xfs_attr_leaf_entry_t *entry; - xfs_attr_leaf_name_remote_t *name_rmt; - xfs_dabuf_t *bp; + struct xfs_attr_leafblock *leaf; + struct xfs_attr_leaf_entry *entry; + struct xfs_attr_leaf_name_remote *name_rmt; + struct xfs_buf *bp; int error; +#ifdef DEBUG + struct xfs_attr3_icleaf_hdr ichdr; +#endif + + trace_xfs_attr_leaf_setflag(args); /* * Set up the operation. */ - error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, - XFS_ATTR_FORK); - if (error) { + error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp); + if (error) return(error); - } - ASSERT(bp != NULL); - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); + leaf = bp->b_addr; +#ifdef DEBUG + xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); + ASSERT(args->index < ichdr.count); ASSERT(args->index >= 0); - entry = &leaf->entries[ args->index ]; +#endif + entry = &xfs_attr3_leaf_entryp(leaf)[args->index]; ASSERT((entry->flags & XFS_ATTR_INCOMPLETE) == 0); entry->flags |= XFS_ATTR_INCOMPLETE; - xfs_da_log_buf(args->trans, bp, + xfs_trans_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); if ((entry->flags & XFS_ATTR_LOCAL) == 0) { - name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); + name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index); name_rmt->valueblk = 0; name_rmt->valuelen = 0; - xfs_da_log_buf(args->trans, bp, + xfs_trans_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); } - xfs_da_buf_done(bp); /* * Commit the flag value change and start the next trans in series. @@ -2222,71 +2563,76 @@ * Note that they could be in different blocks, or in the same block. */ int -xfs_attr_leaf_flipflags(xfs_da_args_t *args) +xfs_attr3_leaf_flipflags( + struct xfs_da_args *args) { - xfs_attr_leafblock_t *leaf1, *leaf2; - xfs_attr_leaf_entry_t *entry1, *entry2; - xfs_attr_leaf_name_remote_t *name_rmt; - xfs_dabuf_t *bp1, *bp2; + struct xfs_attr_leafblock *leaf1; + struct xfs_attr_leafblock *leaf2; + struct xfs_attr_leaf_entry *entry1; + struct xfs_attr_leaf_entry *entry2; + struct xfs_attr_leaf_name_remote *name_rmt; + struct xfs_buf *bp1; + struct xfs_buf *bp2; int error; #ifdef DEBUG + struct xfs_attr3_icleaf_hdr ichdr1; + struct xfs_attr3_icleaf_hdr ichdr2; xfs_attr_leaf_name_local_t *name_loc; int namelen1, namelen2; char *name1, *name2; #endif /* DEBUG */ + trace_xfs_attr_leaf_flipflags(args); + /* * Read the block containing the "old" attr */ - error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp1, - XFS_ATTR_FORK); - if (error) { - return(error); - } - ASSERT(bp1 != NULL); + error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp1); + if (error) + return error; /* * Read the block containing the "new" attr, if it is different */ if (args->blkno2 != args->blkno) { - error = xfs_da_read_buf(args->trans, args->dp, args->blkno2, - -1, &bp2, XFS_ATTR_FORK); - if (error) { - return(error); - } - ASSERT(bp2 != NULL); + error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno2, + -1, &bp2); + if (error) + return error; } else { bp2 = bp1; } - leaf1 = bp1->data; - ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - ASSERT(args->index < be16_to_cpu(leaf1->hdr.count)); + leaf1 = bp1->b_addr; + entry1 = &xfs_attr3_leaf_entryp(leaf1)[args->index]; + + leaf2 = bp2->b_addr; + entry2 = &xfs_attr3_leaf_entryp(leaf2)[args->index2]; + +#ifdef DEBUG + xfs_attr3_leaf_hdr_from_disk(&ichdr1, leaf1); + ASSERT(args->index < ichdr1.count); ASSERT(args->index >= 0); - entry1 = &leaf1->entries[ args->index ]; - leaf2 = bp2->data; - ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - ASSERT(args->index2 < be16_to_cpu(leaf2->hdr.count)); + xfs_attr3_leaf_hdr_from_disk(&ichdr2, leaf2); + ASSERT(args->index2 < ichdr2.count); ASSERT(args->index2 >= 0); - entry2 = &leaf2->entries[ args->index2 ]; -#ifdef DEBUG if (entry1->flags & XFS_ATTR_LOCAL) { - name_loc = xfs_attr_leaf_name_local(leaf1, args->index); + name_loc = xfs_attr3_leaf_name_local(leaf1, args->index); namelen1 = name_loc->namelen; name1 = (char *)name_loc->nameval; } else { - name_rmt = xfs_attr_leaf_name_remote(leaf1, args->index); + name_rmt = xfs_attr3_leaf_name_remote(leaf1, args->index); namelen1 = name_rmt->namelen; name1 = (char *)name_rmt->name; } if (entry2->flags & XFS_ATTR_LOCAL) { - name_loc = xfs_attr_leaf_name_local(leaf2, args->index2); + name_loc = xfs_attr3_leaf_name_local(leaf2, args->index2); namelen2 = name_loc->namelen; name2 = (char *)name_loc->nameval; } else { - name_rmt = xfs_attr_leaf_name_remote(leaf2, args->index2); + name_rmt = xfs_attr3_leaf_name_remote(leaf2, args->index2); namelen2 = name_rmt->namelen; name2 = (char *)name_rmt->name; } @@ -2299,35 +2645,32 @@ ASSERT((entry2->flags & XFS_ATTR_INCOMPLETE) == 0); entry1->flags &= ~XFS_ATTR_INCOMPLETE; - xfs_da_log_buf(args->trans, bp1, + xfs_trans_log_buf(args->trans, bp1, XFS_DA_LOGRANGE(leaf1, entry1, sizeof(*entry1))); if (args->rmtblkno) { ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0); - name_rmt = xfs_attr_leaf_name_remote(leaf1, args->index); + name_rmt = xfs_attr3_leaf_name_remote(leaf1, args->index); name_rmt->valueblk = cpu_to_be32(args->rmtblkno); name_rmt->valuelen = cpu_to_be32(args->valuelen); - xfs_da_log_buf(args->trans, bp1, + xfs_trans_log_buf(args->trans, bp1, XFS_DA_LOGRANGE(leaf1, name_rmt, sizeof(*name_rmt))); } entry2->flags |= XFS_ATTR_INCOMPLETE; - xfs_da_log_buf(args->trans, bp2, + xfs_trans_log_buf(args->trans, bp2, XFS_DA_LOGRANGE(leaf2, entry2, sizeof(*entry2))); if ((entry2->flags & XFS_ATTR_LOCAL) == 0) { - name_rmt = xfs_attr_leaf_name_remote(leaf2, args->index2); + name_rmt = xfs_attr3_leaf_name_remote(leaf2, args->index2); name_rmt->valueblk = 0; name_rmt->valuelen = 0; - xfs_da_log_buf(args->trans, bp2, + xfs_trans_log_buf(args->trans, bp2, XFS_DA_LOGRANGE(leaf2, name_rmt, sizeof(*name_rmt))); } - xfs_da_buf_done(bp1); - if (bp1 != bp2) - xfs_da_buf_done(bp2); /* * Commit the flag value change and start the next trans in series. */ error = xfs_trans_roll(&args->trans, args->dp); - return(error); + return error; } diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_attr_remote.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_attr_remote.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_attr_remote.c 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_attr_remote.c 2014-07-21 09:13:53.000000000 +0000 @@ -0,0 +1,599 @@ +/* + * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * Copyright (c) 2013 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include + +#define ATTR_RMTVALUE_MAPSIZE 1 /* # of map entries at once */ + +/* + * Each contiguous block has a header, so it is not just a simple attribute + * length to FSB conversion. + */ +int +xfs_attr3_rmt_blocks( + struct xfs_mount *mp, + int attrlen) +{ + if (xfs_sb_version_hascrc(&mp->m_sb)) { + int buflen = XFS_ATTR3_RMT_BUF_SPACE(mp, mp->m_sb.sb_blocksize); + return (attrlen + buflen - 1) / buflen; + } + return XFS_B_TO_FSB(mp, attrlen); +} + +/* + * Checking of the remote attribute header is split into two parts. The verifier + * does CRC, location and bounds checking, the unpacking function checks the + * attribute parameters and owner. + */ +static bool +xfs_attr3_rmt_hdr_ok( + struct xfs_mount *mp, + void *ptr, + xfs_ino_t ino, + uint32_t offset, + uint32_t size, + xfs_daddr_t bno) +{ + struct xfs_attr3_rmt_hdr *rmt = ptr; + + if (bno != be64_to_cpu(rmt->rm_blkno)) + return false; + if (offset != be32_to_cpu(rmt->rm_offset)) + return false; + if (size != be32_to_cpu(rmt->rm_bytes)) + return false; + if (ino != be64_to_cpu(rmt->rm_owner)) + return false; + + /* ok */ + return true; +} + +static bool +xfs_attr3_rmt_verify( + struct xfs_mount *mp, + void *ptr, + int fsbsize, + xfs_daddr_t bno) +{ + struct xfs_attr3_rmt_hdr *rmt = ptr; + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return false; + if (rmt->rm_magic != cpu_to_be32(XFS_ATTR3_RMT_MAGIC)) + return false; + if (!uuid_equal(&rmt->rm_uuid, &mp->m_sb.sb_uuid)) + return false; + if (be64_to_cpu(rmt->rm_blkno) != bno) + return false; + if (be32_to_cpu(rmt->rm_bytes) > fsbsize - sizeof(*rmt)) + return false; + if (be32_to_cpu(rmt->rm_offset) + + be32_to_cpu(rmt->rm_bytes) > XATTR_SIZE_MAX) + return false; + if (rmt->rm_owner == 0) + return false; + + return true; +} + +static void +xfs_attr3_rmt_read_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + char *ptr; + int len; + xfs_daddr_t bno; + + /* no verification of non-crc buffers */ + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return; + + ptr = bp->b_addr; + bno = bp->b_bn; + len = BBTOB(bp->b_length); + ASSERT(len >= XFS_LBSIZE(mp)); + + while (len > 0) { + if (!xfs_verify_cksum(ptr, XFS_LBSIZE(mp), + XFS_ATTR3_RMT_CRC_OFF)) { + xfs_buf_ioerror(bp, EFSBADCRC); + break; + } + if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) { + xfs_buf_ioerror(bp, EFSCORRUPTED); + break; + } + len -= XFS_LBSIZE(mp); + ptr += XFS_LBSIZE(mp); + bno += mp->m_bsize; + } + + if (bp->b_error) + xfs_verifier_error(bp); + else + ASSERT(len == 0); +} + +static void +xfs_attr3_rmt_write_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_buf_log_item *bip = bp->b_fspriv; + char *ptr; + int len; + xfs_daddr_t bno; + + /* no verification of non-crc buffers */ + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return; + + ptr = bp->b_addr; + bno = bp->b_bn; + len = BBTOB(bp->b_length); + ASSERT(len >= XFS_LBSIZE(mp)); + + while (len > 0) { + if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) { + xfs_buf_ioerror(bp, EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + if (bip) { + struct xfs_attr3_rmt_hdr *rmt; + + rmt = (struct xfs_attr3_rmt_hdr *)ptr; + rmt->rm_lsn = cpu_to_be64(bip->bli_item.li_lsn); + } + xfs_update_cksum(ptr, XFS_LBSIZE(mp), XFS_ATTR3_RMT_CRC_OFF); + + len -= XFS_LBSIZE(mp); + ptr += XFS_LBSIZE(mp); + bno += mp->m_bsize; + } + ASSERT(len == 0); +} + +const struct xfs_buf_ops xfs_attr3_rmt_buf_ops = { + .verify_read = xfs_attr3_rmt_read_verify, + .verify_write = xfs_attr3_rmt_write_verify, +}; + +STATIC int +xfs_attr3_rmt_hdr_set( + struct xfs_mount *mp, + void *ptr, + xfs_ino_t ino, + uint32_t offset, + uint32_t size, + xfs_daddr_t bno) +{ + struct xfs_attr3_rmt_hdr *rmt = ptr; + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return 0; + + rmt->rm_magic = cpu_to_be32(XFS_ATTR3_RMT_MAGIC); + rmt->rm_offset = cpu_to_be32(offset); + rmt->rm_bytes = cpu_to_be32(size); + uuid_copy(&rmt->rm_uuid, &mp->m_sb.sb_uuid); + rmt->rm_owner = cpu_to_be64(ino); + rmt->rm_blkno = cpu_to_be64(bno); + + return sizeof(struct xfs_attr3_rmt_hdr); +} + +/* + * Helper functions to copy attribute data in and out of the one disk extents + */ +STATIC int +xfs_attr_rmtval_copyout( + struct xfs_mount *mp, + struct xfs_buf *bp, + xfs_ino_t ino, + int *offset, + int *valuelen, + __uint8_t **dst) +{ + char *src = bp->b_addr; + xfs_daddr_t bno = bp->b_bn; + int len = BBTOB(bp->b_length); + + ASSERT(len >= XFS_LBSIZE(mp)); + + while (len > 0 && *valuelen > 0) { + int hdr_size = 0; + int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, XFS_LBSIZE(mp)); + + byte_cnt = min(*valuelen, byte_cnt); + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + if (!xfs_attr3_rmt_hdr_ok(mp, src, ino, *offset, + byte_cnt, bno)) { + xfs_alert(mp, +"remote attribute header mismatch bno/off/len/owner (0x%llx/0x%x/Ox%x/0x%llx)", + bno, *offset, byte_cnt, ino); + return EFSCORRUPTED; + } + hdr_size = sizeof(struct xfs_attr3_rmt_hdr); + } + + memcpy(*dst, src + hdr_size, byte_cnt); + + /* roll buffer forwards */ + len -= XFS_LBSIZE(mp); + src += XFS_LBSIZE(mp); + bno += mp->m_bsize; + + /* roll attribute data forwards */ + *valuelen -= byte_cnt; + *dst += byte_cnt; + *offset += byte_cnt; + } + return 0; +} + +STATIC void +xfs_attr_rmtval_copyin( + struct xfs_mount *mp, + struct xfs_buf *bp, + xfs_ino_t ino, + int *offset, + int *valuelen, + __uint8_t **src) +{ + char *dst = bp->b_addr; + xfs_daddr_t bno = bp->b_bn; + int len = BBTOB(bp->b_length); + + ASSERT(len >= XFS_LBSIZE(mp)); + + while (len > 0 && *valuelen > 0) { + int hdr_size; + int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, XFS_LBSIZE(mp)); + + byte_cnt = min(*valuelen, byte_cnt); + hdr_size = xfs_attr3_rmt_hdr_set(mp, dst, ino, *offset, + byte_cnt, bno); + + memcpy(dst + hdr_size, *src, byte_cnt); + + /* + * If this is the last block, zero the remainder of it. + * Check that we are actually the last block, too. + */ + if (byte_cnt + hdr_size < XFS_LBSIZE(mp)) { + ASSERT(*valuelen - byte_cnt == 0); + ASSERT(len == XFS_LBSIZE(mp)); + memset(dst + hdr_size + byte_cnt, 0, + XFS_LBSIZE(mp) - hdr_size - byte_cnt); + } + + /* roll buffer forwards */ + len -= XFS_LBSIZE(mp); + dst += XFS_LBSIZE(mp); + bno += mp->m_bsize; + + /* roll attribute data forwards */ + *valuelen -= byte_cnt; + *src += byte_cnt; + *offset += byte_cnt; + } +} + +/* + * Read the value associated with an attribute from the out-of-line buffer + * that we stored it in. + */ +int +xfs_attr_rmtval_get( + struct xfs_da_args *args) +{ + struct xfs_bmbt_irec map[ATTR_RMTVALUE_MAPSIZE]; + struct xfs_mount *mp = args->dp->i_mount; + struct xfs_buf *bp; + xfs_dablk_t lblkno = args->rmtblkno; + __uint8_t *dst = args->value; + int valuelen = args->valuelen; + int nmap; + int error; + int blkcnt = args->rmtblkcnt; + int i; + int offset = 0; + + trace_xfs_attr_rmtval_get(args); + + ASSERT(!(args->flags & ATTR_KERNOVAL)); + + while (valuelen > 0) { + nmap = ATTR_RMTVALUE_MAPSIZE; + error = xfs_bmapi_read(args->dp, (xfs_fileoff_t)lblkno, + blkcnt, map, &nmap, + XFS_BMAPI_ATTRFORK); + if (error) + return error; + ASSERT(nmap >= 1); + + for (i = 0; (i < nmap) && (valuelen > 0); i++) { + xfs_daddr_t dblkno; + int dblkcnt; + + ASSERT((map[i].br_startblock != DELAYSTARTBLOCK) && + (map[i].br_startblock != HOLESTARTBLOCK)); + dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock); + dblkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount); + error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, + dblkno, dblkcnt, 0, &bp, + &xfs_attr3_rmt_buf_ops); + if (error) + return error; + + error = xfs_attr_rmtval_copyout(mp, bp, args->dp->i_ino, + &offset, &valuelen, + &dst); + xfs_buf_relse(bp); + if (error) + return error; + + /* roll attribute extent map forwards */ + lblkno += map[i].br_blockcount; + blkcnt -= map[i].br_blockcount; + } + } + ASSERT(valuelen == 0); + return 0; +} + +/* + * Write the value associated with an attribute into the out-of-line buffer + * that we have defined for it. + */ +int +xfs_attr_rmtval_set( + struct xfs_da_args *args) +{ + struct xfs_inode *dp = args->dp; + struct xfs_mount *mp = dp->i_mount; + struct xfs_bmbt_irec map; + xfs_dablk_t lblkno; + xfs_fileoff_t lfileoff = 0; + __uint8_t *src = args->value; + int blkcnt; + int valuelen; + int nmap; + int error; + int offset = 0; + + trace_xfs_attr_rmtval_set(args); + + /* + * Find a "hole" in the attribute address space large enough for + * us to drop the new attribute's value into. Because CRC enable + * attributes have headers, we can't just do a straight byte to FSB + * conversion and have to take the header space into account. + */ + blkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen); + error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff, + XFS_ATTR_FORK); + if (error) + return error; + + args->rmtblkno = lblkno = (xfs_dablk_t)lfileoff; + args->rmtblkcnt = blkcnt; + + /* + * Roll through the "value", allocating blocks on disk as required. + */ + while (blkcnt > 0) { + int committed; + + /* + * Allocate a single extent, up to the size of the value. + */ + xfs_bmap_init(args->flist, args->firstblock); + nmap = 1; + error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno, + blkcnt, + XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, + args->firstblock, args->total, &map, &nmap, + args->flist); + if (!error) { + error = xfs_bmap_finish(&args->trans, args->flist, + &committed); + } + if (error) { + ASSERT(committed); + args->trans = NULL; + xfs_bmap_cancel(args->flist); + return(error); + } + + /* + * bmap_finish() may have committed the last trans and started + * a new one. We need the inode to be in all transactions. + */ + if (committed) + xfs_trans_ijoin(args->trans, dp, 0); + + ASSERT(nmap == 1); + ASSERT((map.br_startblock != DELAYSTARTBLOCK) && + (map.br_startblock != HOLESTARTBLOCK)); + lblkno += map.br_blockcount; + blkcnt -= map.br_blockcount; + + /* + * Start the next trans in the chain. + */ + error = xfs_trans_roll(&args->trans, dp); + if (error) + return (error); + } + + /* + * Roll through the "value", copying the attribute value to the + * already-allocated blocks. Blocks are written synchronously + * so that we can know they are all on disk before we turn off + * the INCOMPLETE flag. + */ + lblkno = args->rmtblkno; + blkcnt = args->rmtblkcnt; + valuelen = args->valuelen; + while (valuelen > 0) { + struct xfs_buf *bp; + xfs_daddr_t dblkno; + int dblkcnt; + + ASSERT(blkcnt > 0); + + xfs_bmap_init(args->flist, args->firstblock); + nmap = 1; + error = xfs_bmapi_read(dp, (xfs_fileoff_t)lblkno, + blkcnt, &map, &nmap, + XFS_BMAPI_ATTRFORK); + if (error) + return(error); + ASSERT(nmap == 1); + ASSERT((map.br_startblock != DELAYSTARTBLOCK) && + (map.br_startblock != HOLESTARTBLOCK)); + + dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock), + dblkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); + + bp = xfs_buf_get(mp->m_ddev_targp, dblkno, dblkcnt, 0); + if (!bp) + return ENOMEM; + bp->b_ops = &xfs_attr3_rmt_buf_ops; + + xfs_attr_rmtval_copyin(mp, bp, args->dp->i_ino, &offset, + &valuelen, &src); + + error = xfs_bwrite(bp); /* GROT: NOTE: synchronous write */ + xfs_buf_relse(bp); + if (error) + return error; + + + /* roll attribute extent map forwards */ + lblkno += map.br_blockcount; + blkcnt -= map.br_blockcount; + } + ASSERT(valuelen == 0); + return 0; +} + +/* + * Remove the value associated with an attribute by deleting the + * out-of-line buffer that it is stored on. + */ +int +xfs_attr_rmtval_remove( + struct xfs_da_args *args) +{ + struct xfs_mount *mp = args->dp->i_mount; + xfs_dablk_t lblkno; + int blkcnt; + int error; + int done; + + trace_xfs_attr_rmtval_remove(args); + + /* + * Roll through the "value", invalidating the attribute value's blocks. + */ + lblkno = args->rmtblkno; + blkcnt = args->rmtblkcnt; + while (blkcnt > 0) { + struct xfs_bmbt_irec map; + struct xfs_buf *bp; + xfs_daddr_t dblkno; + int dblkcnt; + int nmap; + + /* + * Try to remember where we decided to put the value. + */ + nmap = 1; + error = xfs_bmapi_read(args->dp, (xfs_fileoff_t)lblkno, + blkcnt, &map, &nmap, XFS_BMAPI_ATTRFORK); + if (error) + return(error); + ASSERT(nmap == 1); + ASSERT((map.br_startblock != DELAYSTARTBLOCK) && + (map.br_startblock != HOLESTARTBLOCK)); + + dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock), + dblkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); + + /* + * If the "remote" value is in the cache, remove it. + */ + bp = xfs_incore(mp->m_ddev_targp, dblkno, dblkcnt, XBF_TRYLOCK); + if (bp) { + xfs_buf_stale(bp); + xfs_buf_relse(bp); + bp = NULL; + } + + lblkno += map.br_blockcount; + blkcnt -= map.br_blockcount; + } + + /* + * Keep de-allocating extents until the remote-value region is gone. + */ + lblkno = args->rmtblkno; + blkcnt = args->rmtblkcnt; + done = 0; + while (!done) { + int committed; + + xfs_bmap_init(args->flist, args->firstblock); + error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, + XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, + 1, args->firstblock, args->flist, + &done); + if (!error) { + error = xfs_bmap_finish(&args->trans, args->flist, + &committed); + } + if (error) { + ASSERT(committed); + args->trans = NULL; + xfs_bmap_cancel(args->flist); + return error; + } + + /* + * bmap_finish() may have committed the last trans and started + * a new one. We need the inode to be in all transactions. + */ + if (committed) + xfs_trans_ijoin(args->trans, args->dp, 0); + + /* + * Close out trans and start the next one in the chain. + */ + error = xfs_trans_roll(&args->trans, args->dp); + if (error) + return (error); + } + return(0); +} diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_bmap_btree.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_bmap_btree.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_bmap_btree.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_bmap_btree.c 2014-05-02 00:09:16.000000000 +0000 @@ -38,24 +38,31 @@ */ void xfs_bmdr_to_bmbt( - struct xfs_mount *mp, + struct xfs_inode *ip, xfs_bmdr_block_t *dblock, int dblocklen, struct xfs_btree_block *rblock, int rblocklen) { + struct xfs_mount *mp = ip->i_mount; int dmxr; xfs_bmbt_key_t *fkp; __be64 *fpp; xfs_bmbt_key_t *tkp; __be64 *tpp; - rblock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC); + if (xfs_sb_version_hascrc(&mp->m_sb)) + xfs_btree_init_block_int(mp, rblock, XFS_BUF_DADDR_NULL, + XFS_BMAP_CRC_MAGIC, 0, 0, ip->i_ino, + XFS_BTREE_LONG_PTRS | XFS_BTREE_CRC_BLOCKS); + else + xfs_btree_init_block_int(mp, rblock, XFS_BUF_DADDR_NULL, + XFS_BMAP_MAGIC, 0, 0, ip->i_ino, + XFS_BTREE_LONG_PTRS); + rblock->bb_level = dblock->bb_level; ASSERT(be16_to_cpu(rblock->bb_level) > 0); rblock->bb_numrecs = dblock->bb_numrecs; - rblock->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO); - rblock->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO); dmxr = xfs_bmdr_maxrecs(mp, dblocklen, 0); fkp = XFS_BMDR_KEY_ADDR(dblock, 1); tkp = XFS_BMBT_KEY_ADDR(mp, rblock, 1); @@ -403,10 +410,16 @@ xfs_bmbt_key_t *tkp; __be64 *tpp; - ASSERT(be32_to_cpu(rblock->bb_magic) == XFS_BMAP_MAGIC); - ASSERT(be64_to_cpu(rblock->bb_u.l.bb_leftsib) == NULLDFSBNO); - ASSERT(be64_to_cpu(rblock->bb_u.l.bb_rightsib) == NULLDFSBNO); - ASSERT(be16_to_cpu(rblock->bb_level) > 0); + if (xfs_sb_version_hascrc(&mp->m_sb)) { + ASSERT(rblock->bb_magic == cpu_to_be32(XFS_BMAP_CRC_MAGIC)); + ASSERT(uuid_equal(&rblock->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)); + ASSERT(rblock->bb_u.l.bb_blkno == + cpu_to_be64(XFS_BUF_DADDR_NULL)); + } else + ASSERT(rblock->bb_magic == cpu_to_be32(XFS_BMAP_MAGIC)); + ASSERT(rblock->bb_u.l.bb_leftsib == cpu_to_be64(NULLDFSBNO)); + ASSERT(rblock->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO)); + ASSERT(rblock->bb_level != 0); dblock->bb_level = rblock->bb_level; dblock->bb_numrecs = rblock->bb_numrecs; dmxr = xfs_bmdr_maxrecs(mp, dblocklen, 0); @@ -687,7 +700,96 @@ cur->bc_rec.b.br_startoff; } -#ifdef DEBUG +static bool +xfs_bmbt_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); + unsigned int level; + + switch (block->bb_magic) { + case cpu_to_be32(XFS_BMAP_CRC_MAGIC): + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return false; + if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)) + return false; + if (be64_to_cpu(block->bb_u.l.bb_blkno) != bp->b_bn) + return false; + /* + * XXX: need a better way of verifying the owner here. Right now + * just make sure there has been one set. + */ + if (be64_to_cpu(block->bb_u.l.bb_owner) == 0) + return false; + /* fall through */ + case cpu_to_be32(XFS_BMAP_MAGIC): + break; + default: + return false; + } + + /* + * numrecs and level verification. + * + * We don't know what fork we belong to, so just verify that the level + * is less than the maximum of the two. Later checks will be more + * precise. + */ + level = be16_to_cpu(block->bb_level); + if (level > max(mp->m_bm_maxlevels[0], mp->m_bm_maxlevels[1])) + return false; + if (be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[level != 0]) + return false; + + /* sibling pointer verification */ + if (!block->bb_u.l.bb_leftsib || + (block->bb_u.l.bb_leftsib != cpu_to_be64(NULLDFSBNO) && + !XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_u.l.bb_leftsib)))) + return false; + if (!block->bb_u.l.bb_rightsib || + (block->bb_u.l.bb_rightsib != cpu_to_be64(NULLDFSBNO) && + !XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_u.l.bb_rightsib)))) + return false; + + return true; +} + +static void +xfs_bmbt_read_verify( + struct xfs_buf *bp) +{ + if (!xfs_btree_lblock_verify_crc(bp)) + xfs_buf_ioerror(bp, EFSBADCRC); + else if (!xfs_bmbt_verify(bp)) + xfs_buf_ioerror(bp, EFSCORRUPTED); + + if (bp->b_error) { + trace_xfs_btree_corrupt(bp, _RET_IP_); + xfs_verifier_error(bp); + } +} + +static void +xfs_bmbt_write_verify( + struct xfs_buf *bp) +{ + if (!xfs_bmbt_verify(bp)) { + trace_xfs_btree_corrupt(bp, _RET_IP_); + xfs_buf_ioerror(bp, EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + xfs_btree_lblock_calc_crc(bp); +} + +const struct xfs_buf_ops xfs_bmbt_buf_ops = { + .verify_read = xfs_bmbt_read_verify, + .verify_write = xfs_bmbt_write_verify, +}; + + +#if defined(DEBUG) || defined(XFS_WARN) STATIC int xfs_bmbt_keys_inorder( struct xfs_btree_cur *cur, @@ -815,8 +917,8 @@ .init_rec_from_cur = xfs_bmbt_init_rec_from_cur, .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur, .key_diff = xfs_bmbt_key_diff, - -#ifdef DEBUG + .buf_ops = &xfs_bmbt_buf_ops, +#if defined(DEBUG) || defined(XFS_WARN) .keys_inorder = xfs_bmbt_keys_inorder, .recs_inorder = xfs_bmbt_recs_inorder, #endif @@ -852,6 +954,8 @@ cur->bc_ops = &xfs_bmbt_ops; cur->bc_flags = XFS_BTREE_LONG_PTRS | XFS_BTREE_ROOT_IN_INODE; + if (xfs_sb_version_hascrc(&mp->m_sb)) + cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork); cur->bc_private.b.ip = ip; @@ -895,3 +999,47 @@ return blocklen / sizeof(xfs_bmdr_rec_t); return blocklen / (sizeof(xfs_bmdr_key_t) + sizeof(xfs_bmdr_ptr_t)); } + +/* + * Change the owner of a btree format fork of the inode passed in. Change it to + * the owner of that is passed in so that we can change owners before or after + * we switch forks between inodes. The operation that the caller is doing will + * determine whether is needs to change owner before or after the switch. + * + * For demand paged transactional modification, the fork switch should be done + * after reading in all the blocks, modifying them and pinning them in the + * transaction. For modification when the buffers are already pinned in memory, + * the fork switch can be done before changing the owner as we won't need to + * validate the owner until the btree buffers are unpinned and writes can occur + * again. + * + * For recovery based ownership change, there is no transactional context and + * so a buffer list must be supplied so that we can record the buffers that we + * modified for the caller to issue IO on. + */ +int +xfs_bmbt_change_owner( + struct xfs_trans *tp, + struct xfs_inode *ip, + int whichfork, + xfs_ino_t new_owner, + struct list_head *buffer_list) +{ + struct xfs_btree_cur *cur; + int error; + + ASSERT(tp || buffer_list); + ASSERT(!(tp && buffer_list)); + if (whichfork == XFS_DATA_FORK) + ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_BTREE); + else + ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_BTREE); + + cur = xfs_bmbt_init_cursor(ip->i_mount, tp, ip, whichfork); + if (!cur) + return ENOMEM; + + error = xfs_btree_change_owner(cur, new_owner, buffer_list); + xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + return error; +} diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_bmap.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_bmap.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_bmap.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_bmap.c 2014-05-02 00:09:16.000000000 +0000 @@ -15,244 +15,64 @@ * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #include -#ifdef DEBUG -STATIC void -xfs_bmap_check_leaf_extents(xfs_btree_cur_t *cur, xfs_inode_t *ip, int whichfork); -#endif - kmem_zone_t *xfs_bmap_free_item_zone; /* - * Prototypes for internal bmap routines. - */ - - -/* - * Called from xfs_bmap_add_attrfork to handle extents format files. - */ -STATIC int /* error */ -xfs_bmap_add_attrfork_extents( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_fsblock_t *firstblock, /* first block allocated */ - xfs_bmap_free_t *flist, /* blocks to free at commit */ - int *flags); /* inode logging flags */ - -/* - * Called from xfs_bmap_add_attrfork to handle local format files. - */ -STATIC int /* error */ -xfs_bmap_add_attrfork_local( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_fsblock_t *firstblock, /* first block allocated */ - xfs_bmap_free_t *flist, /* blocks to free at commit */ - int *flags); /* inode logging flags */ - -/* - * Called by xfs_bmapi to update file extent records and the btree - * after allocating space (or doing a delayed allocation). - */ -STATIC int /* error */ -xfs_bmap_add_extent( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* extent number to update/insert */ - xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ - xfs_bmbt_irec_t *new, /* new data to add to file extents */ - xfs_fsblock_t *first, /* pointer to firstblock variable */ - xfs_bmap_free_t *flist, /* list of extents to be freed */ - int *logflagsp, /* inode logging flags */ - int whichfork, /* data or attr fork */ - int rsvd); /* OK to allocate reserved blocks */ - -/* - * Called by xfs_bmap_add_extent to handle cases converting a delayed - * allocation to a real allocation. - */ -STATIC int /* error */ -xfs_bmap_add_extent_delay_real( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* extent number to update/insert */ - xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ - xfs_bmbt_irec_t *new, /* new data to add to file extents */ - xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ - xfs_fsblock_t *first, /* pointer to firstblock variable */ - xfs_bmap_free_t *flist, /* list of extents to be freed */ - int *logflagsp, /* inode logging flags */ - int rsvd); /* OK to allocate reserved blocks */ - -/* - * Called by xfs_bmap_add_extent to handle cases converting a hole - * to a delayed allocation. - */ -STATIC int /* error */ -xfs_bmap_add_extent_hole_delay( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* extent number to update/insert */ - xfs_bmbt_irec_t *new, /* new data to add to file extents */ - int *logflagsp,/* inode logging flags */ - int rsvd); /* OK to allocate reserved blocks */ - -/* - * Called by xfs_bmap_add_extent to handle cases converting a hole - * to a real allocation. - */ -STATIC int /* error */ -xfs_bmap_add_extent_hole_real( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* extent number to update/insert */ - xfs_btree_cur_t *cur, /* if null, not a btree */ - xfs_bmbt_irec_t *new, /* new data to add to file extents */ - int *logflagsp, /* inode logging flags */ - int whichfork); /* data or attr fork */ - -/* - * Called by xfs_bmap_add_extent to handle cases converting an unwritten - * allocation to a real allocation or vice versa. - */ -STATIC int /* error */ -xfs_bmap_add_extent_unwritten_real( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* extent number to update/insert */ - xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ - xfs_bmbt_irec_t *new, /* new data to add to file extents */ - int *logflagsp); /* inode logging flags */ - -/* - * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. - * It figures out where to ask the underlying allocator to put the new extent. - */ -STATIC int /* error */ -xfs_bmap_alloc( - xfs_bmalloca_t *ap); /* bmap alloc argument struct */ - -/* - * Transform a btree format file with only one leaf node, where the - * extents list will fit in the inode, into an extents format file. - * Since the file extents are already in-core, all we have to do is - * give up the space for the btree root and pitch the leaf block. - */ -STATIC int /* error */ -xfs_bmap_btree_to_extents( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_btree_cur_t *cur, /* btree cursor */ - int *logflagsp, /* inode logging flags */ - int whichfork); /* data or attr fork */ - -/* - * Called by xfs_bmapi to update file extent records and the btree - * after removing space (or undoing a delayed allocation). - */ -STATIC int /* error */ -xfs_bmap_del_extent( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_trans_t *tp, /* current trans pointer */ - xfs_extnum_t idx, /* extent number to update/insert */ - xfs_bmap_free_t *flist, /* list of extents to be freed */ - xfs_btree_cur_t *cur, /* if null, not a btree */ - xfs_bmbt_irec_t *new, /* new data to add to file extents */ - int *logflagsp,/* inode logging flags */ - int whichfork, /* data or attr fork */ - int rsvd); /* OK to allocate reserved blocks */ - -/* - * Convert an extents-format file into a btree-format file. - * The new file will have a root block (in the inode) and a single child block. - */ -STATIC int /* error */ -xfs_bmap_extents_to_btree( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_fsblock_t *firstblock, /* first-block-allocated */ - xfs_bmap_free_t *flist, /* blocks freed in xaction */ - xfs_btree_cur_t **curp, /* cursor returned to caller */ - int wasdel, /* converting a delayed alloc */ - int *logflagsp, /* inode logging flags */ - int whichfork); /* data or attr fork */ - -/* - * Convert a local file to an extents file. - * This code is sort of bogus, since the file data needs to get - * logged so it won't be lost. The bmap-level manipulations are ok, though. - */ -STATIC int /* error */ -xfs_bmap_local_to_extents( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_fsblock_t *firstblock, /* first block allocated in xaction */ - xfs_extlen_t total, /* total blocks needed by transaction */ - int *logflagsp, /* inode logging flags */ - int whichfork); /* data or attr fork */ - -/* - * Check the last inode extent to determine whether this allocation will result - * in blocks being allocated at the end of the file. When we allocate new data - * blocks at the end of the file which do not start at the previous data block, - * we will try to align the new blocks at stripe unit boundaries. - */ -STATIC int /* error */ -xfs_bmap_isaeof( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_fileoff_t off, /* file offset in fsblocks */ - int whichfork, /* data or attribute fork */ - char *aeof); /* return value */ - -/* - * Compute the worst-case number of indirect blocks that will be used - * for ip's delayed extent of length "len". + * Miscellaneous helper functions */ -STATIC xfs_filblks_t -xfs_bmap_worst_indlen( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_filblks_t len); /* delayed extent length */ -#ifdef DEBUG /* - * Perform various validation checks on the values being returned - * from xfs_bmapi(). + * Compute and fill in the value of the maximum depth of a bmap btree + * in this filesystem. Done once, during mount. */ -STATIC void -xfs_bmap_validate_ret( - xfs_fileoff_t bno, - xfs_filblks_t len, - int flags, - xfs_bmbt_irec_t *mval, - int nmap, - int ret_nmap); -#else -#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) -#endif /* DEBUG */ - -STATIC int -xfs_bmap_count_tree( - xfs_mount_t *mp, - xfs_trans_t *tp, - xfs_ifork_t *ifp, - xfs_fsblock_t blockno, - int levelin, - int *count); - -STATIC void -xfs_bmap_count_leaves( - xfs_ifork_t *ifp, - xfs_extnum_t idx, - int numrecs, - int *count); - -STATIC void -xfs_bmap_disk_count_leaves( - struct xfs_mount *mp, - struct xfs_btree_block *block, - int numrecs, - int *count); +void +xfs_bmap_compute_maxlevels( + xfs_mount_t *mp, /* file system mount structure */ + int whichfork) /* data or attr fork */ +{ + int level; /* btree level */ + uint maxblocks; /* max blocks at this level */ + uint maxleafents; /* max leaf entries possible */ + int maxrootrecs; /* max records in root block */ + int minleafrecs; /* min records in leaf block */ + int minnoderecs; /* min records in node block */ + int sz; /* root block size */ -/* - * Bmap internal routines. - */ + /* + * The maximum number of extents in a file, hence the maximum + * number of leaf entries, is controlled by the type of di_nextents + * (a signed 32-bit number, xfs_extnum_t), or by di_anextents + * (a signed 16-bit number, xfs_aextnum_t). + * + * Note that we can no longer assume that if we are in ATTR1 that + * the fork offset of all the inodes will be + * (xfs_default_attroffset(ip) >> 3) because we could have mounted + * with ATTR2 and then mounted back with ATTR1, keeping the + * di_forkoff's fixed but probably at various positions. Therefore, + * for both ATTR1 and ATTR2 we have to assume the worst case scenario + * of a minimum size available. + */ + if (whichfork == XFS_DATA_FORK) { + maxleafents = MAXEXTNUM; + sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS); + } else { + maxleafents = MAXAEXTNUM; + sz = XFS_BMDR_SPACE_CALC(MINABTPTRS); + } + maxrootrecs = xfs_bmdr_maxrecs(mp, sz, 0); + minleafrecs = mp->m_bmap_dmnr[0]; + minnoderecs = mp->m_bmap_dmnr[1]; + maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs; + for (level = 1; maxblocks > 1; level++) { + if (maxblocks <= maxrootrecs) + maxblocks = 1; + else + maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs; + } + mp->m_bm_maxlevels[whichfork] = level; +} STATIC int /* error */ xfs_bmbt_lookup_eq( @@ -283,7 +103,27 @@ } /* -* Update the record referred to by cur to the value given + * Check if the inode needs to be converted to btree format. + */ +static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork) +{ + return XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && + XFS_IFORK_NEXTENTS(ip, whichfork) > + XFS_IFORK_MAXEXT(ip, whichfork); +} + +/* + * Check if the inode should be converted to extent format. + */ +static inline bool xfs_bmap_wants_extents(struct xfs_inode *ip, int whichfork) +{ + return XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && + XFS_IFORK_NEXTENTS(ip, whichfork) <= + XFS_IFORK_MAXEXT(ip, whichfork); +} + +/* + * Update the record referred to by cur to the value given * by [off, bno, len, state]. * This either works (return 0) or gets an EFSCORRUPTED error. */ @@ -302,3817 +142,4295 @@ } /* - * Called from xfs_bmap_add_attrfork to handle btree format files. + * Compute the worst-case number of indirect blocks that will be used + * for ip's delayed extent of length "len". */ -STATIC int /* error */ -xfs_bmap_add_attrfork_btree( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_fsblock_t *firstblock, /* first block allocated */ - xfs_bmap_free_t *flist, /* blocks to free at commit */ - int *flags) /* inode logging flags */ +STATIC xfs_filblks_t +xfs_bmap_worst_indlen( + xfs_inode_t *ip, /* incore inode pointer */ + xfs_filblks_t len) /* delayed extent length */ { - xfs_btree_cur_t *cur; /* btree cursor */ - int error; /* error return value */ - xfs_mount_t *mp; /* file system mount struct */ - int stat; /* newroot status */ + int level; /* btree level number */ + int maxrecs; /* maximum record count at this level */ + xfs_mount_t *mp; /* mount structure */ + xfs_filblks_t rval; /* return value */ mp = ip->i_mount; - if (ip->i_df.if_broot_bytes <= XFS_IFORK_DSIZE(ip)) - *flags |= XFS_ILOG_DBROOT; - else { - cur = xfs_bmbt_init_cursor(mp, tp, ip, XFS_DATA_FORK); - cur->bc_private.b.flist = flist; - cur->bc_private.b.firstblock = *firstblock; - if ((error = xfs_bmbt_lookup_ge(cur, 0, 0, 0, &stat))) - goto error0; - /* must be at least one entry */ - XFS_WANT_CORRUPTED_GOTO(stat == 1, error0); - if ((error = xfs_btree_new_iroot(cur, flags, &stat))) - goto error0; - if (stat == 0) { - xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); - return XFS_ERROR(ENOSPC); - } - *firstblock = cur->bc_private.b.firstblock; - cur->bc_private.b.allocated = 0; - xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + maxrecs = mp->m_bmap_dmxr[0]; + for (level = 0, rval = 0; + level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK); + level++) { + len += maxrecs - 1; + do_div(len, maxrecs); + rval += len; + if (len == 1) + return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - + level - 1; + if (level == 0) + maxrecs = mp->m_bmap_dmxr[1]; } - return 0; -error0: - xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); - return error; + return rval; } /* - * Called from xfs_bmap_add_attrfork to handle extents format files. + * Calculate the default attribute fork offset for newly created inodes. */ -STATIC int /* error */ -xfs_bmap_add_attrfork_extents( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_fsblock_t *firstblock, /* first block allocated */ - xfs_bmap_free_t *flist, /* blocks to free at commit */ - int *flags) /* inode logging flags */ +uint +xfs_default_attroffset( + struct xfs_inode *ip) { - xfs_btree_cur_t *cur; /* bmap btree cursor */ - int error; /* error return value */ + struct xfs_mount *mp = ip->i_mount; + uint offset; - if (ip->i_d.di_nextents * sizeof(xfs_bmbt_rec_t) <= XFS_IFORK_DSIZE(ip)) - return 0; - cur = NULL; - error = xfs_bmap_extents_to_btree(tp, ip, firstblock, flist, &cur, 0, - flags, XFS_DATA_FORK); - if (cur) { - cur->bc_private.b.allocated = 0; - xfs_btree_del_cursor(cur, - error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + if (mp->m_sb.sb_inodesize == 256) { + offset = XFS_LITINO(mp, ip->i_d.di_version) - + XFS_BMDR_SPACE_CALC(MINABTPTRS); + } else { + offset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS); } - return error; + + ASSERT(offset < XFS_LITINO(mp, ip->i_d.di_version)); + return offset; } /* - * Called from xfs_bmap_add_attrfork to handle local format files. + * Helper routine to reset inode di_forkoff field when switching + * attribute fork from local to extent format - we reset it where + * possible to make space available for inline data fork extents. */ -STATIC int /* error */ -xfs_bmap_add_attrfork_local( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_fsblock_t *firstblock, /* first block allocated */ - xfs_bmap_free_t *flist, /* blocks to free at commit */ - int *flags) /* inode logging flags */ +STATIC void +xfs_bmap_forkoff_reset( + xfs_mount_t *mp, + xfs_inode_t *ip, + int whichfork) { - xfs_da_args_t dargs; /* args for dir/attr code */ - int error; /* error return value */ - xfs_mount_t *mp; /* mount structure pointer */ + if (whichfork == XFS_ATTR_FORK && + ip->i_d.di_format != XFS_DINODE_FMT_DEV && + ip->i_d.di_format != XFS_DINODE_FMT_UUID && + ip->i_d.di_format != XFS_DINODE_FMT_BTREE) { + uint dfl_forkoff = xfs_default_attroffset(ip) >> 3; - if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip)) - return 0; - if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { - mp = ip->i_mount; - memset(&dargs, 0, sizeof(dargs)); - dargs.dp = ip; - dargs.firstblock = firstblock; - dargs.flist = flist; - dargs.total = mp->m_dirblkfsbs; - dargs.whichfork = XFS_DATA_FORK; - dargs.trans = tp; - error = xfs_dir2_sf_to_block(&dargs); - } else - error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags, - XFS_DATA_FORK); - return error; + if (dfl_forkoff > ip->i_d.di_forkoff) + ip->i_d.di_forkoff = dfl_forkoff; + } } /* - * Called by xfs_bmapi to update file extent records and the btree - * after allocating space (or doing a delayed allocation). + * Debug/sanity checking code */ -STATIC int /* error */ -xfs_bmap_add_extent( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* extent number to update/insert */ - xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ - xfs_bmbt_irec_t *new, /* new data to add to file extents */ - xfs_fsblock_t *first, /* pointer to firstblock variable */ - xfs_bmap_free_t *flist, /* list of extents to be freed */ - int *logflagsp, /* inode logging flags */ - int whichfork, /* data or attr fork */ - int rsvd) /* OK to use reserved data blocks */ + +STATIC int +xfs_bmap_sanity_check( + struct xfs_mount *mp, + struct xfs_buf *bp, + int level) { - xfs_btree_cur_t *cur; /* btree cursor or null */ - xfs_filblks_t da_new; /* new count del alloc blocks used */ - xfs_filblks_t da_old; /* old count del alloc blocks used */ - int error; /* error return value */ - xfs_ifork_t *ifp; /* inode fork ptr */ - int logflags; /* returned value */ - xfs_extnum_t nextents; /* number of extents in file now */ + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); - XFS_STATS_INC(xs_add_exlist); - cur = *curp; - ifp = XFS_IFORK_PTR(ip, whichfork); - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - ASSERT(idx <= nextents); - da_old = da_new = 0; - error = 0; - /* - * This is the first extent added to a new/empty file. - * Special case this one, so other routines get to assume there are - * already extents in the list. - */ - if (nextents == 0) { - xfs_iext_insert(ip, 0, 1, new, - whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); + if (block->bb_magic != cpu_to_be32(XFS_BMAP_CRC_MAGIC) && + block->bb_magic != cpu_to_be32(XFS_BMAP_MAGIC)) + return 0; - ASSERT(cur == NULL); - ifp->if_lastex = 0; - if (!isnullstartblock(new->br_startblock)) { - XFS_IFORK_NEXT_SET(ip, whichfork, 1); - logflags = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); - } else - logflags = 0; + if (be16_to_cpu(block->bb_level) != level || + be16_to_cpu(block->bb_numrecs) == 0 || + be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[level != 0]) + return 0; + + return 1; +} + +#ifdef DEBUG +STATIC struct xfs_buf * +xfs_bmap_get_bp( + struct xfs_btree_cur *cur, + xfs_fsblock_t bno) +{ + struct xfs_log_item_desc *lidp; + int i; + + if (!cur) + return NULL; + + for (i = 0; i < XFS_BTREE_MAXLEVELS; i++) { + if (!cur->bc_bufs[i]) + break; + if (XFS_BUF_ADDR(cur->bc_bufs[i]) == bno) + return cur->bc_bufs[i]; } - /* - * Any kind of new delayed allocation goes here. - */ - else if (isnullstartblock(new->br_startblock)) { - if (cur) - ASSERT((cur->bc_private.b.flags & - XFS_BTCUR_BPRV_WASDEL) == 0); - if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, new, - &logflags, rsvd))) - goto done; + + /* Chase down all the log items to see if the bp is there */ + list_for_each_entry(lidp, &cur->bc_tp->t_items, lid_trans) { + struct xfs_buf_log_item *bip; + bip = (struct xfs_buf_log_item *)lidp->lid_item; + if (bip->bli_item.li_type == XFS_LI_BUF && + XFS_BUF_ADDR(bip->bli_buf) == bno) + return bip->bli_buf; } - /* - * Real allocation off the end of the file. - */ - else if (idx == nextents) { - if (cur) - ASSERT((cur->bc_private.b.flags & - XFS_BTCUR_BPRV_WASDEL) == 0); - if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new, - &logflags, whichfork))) - goto done; - } else { - xfs_bmbt_irec_t prev; /* old extent at offset idx */ - /* - * Get the record referred to by idx. - */ - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), &prev); - /* - * If it's a real allocation record, and the new allocation ends - * after the start of the referred to record, then we're filling - * in a delayed or unwritten allocation with a real one, or - * converting real back to unwritten. - */ - if (!isnullstartblock(new->br_startblock) && - new->br_startoff + new->br_blockcount > prev.br_startoff) { - if (prev.br_state != XFS_EXT_UNWRITTEN && - isnullstartblock(prev.br_startblock)) { - da_old = startblockval(prev.br_startblock); - if (cur) - ASSERT(cur->bc_private.b.flags & - XFS_BTCUR_BPRV_WASDEL); - if ((error = xfs_bmap_add_extent_delay_real(ip, - idx, &cur, new, &da_new, first, flist, - &logflags, rsvd))) - goto done; - } else if (new->br_state == XFS_EXT_NORM) { - ASSERT(new->br_state == XFS_EXT_NORM); - if ((error = xfs_bmap_add_extent_unwritten_real( - ip, idx, &cur, new, &logflags))) - goto done; - } else { - ASSERT(new->br_state == XFS_EXT_UNWRITTEN); - if ((error = xfs_bmap_add_extent_unwritten_real( - ip, idx, &cur, new, &logflags))) - goto done; - } - ASSERT(*curp == cur || *curp == NULL); + return NULL; +} + +STATIC void +xfs_check_block( + struct xfs_btree_block *block, + xfs_mount_t *mp, + int root, + short sz) +{ + int i, j, dmxr; + __be64 *pp, *thispa; /* pointer to block address */ + xfs_bmbt_key_t *prevp, *keyp; + + ASSERT(be16_to_cpu(block->bb_level) > 0); + + prevp = NULL; + for( i = 1; i <= xfs_btree_get_numrecs(block); i++) { + dmxr = mp->m_bmap_dmxr[0]; + keyp = XFS_BMBT_KEY_ADDR(mp, block, i); + + if (prevp) { + ASSERT(be64_to_cpu(prevp->br_startoff) < + be64_to_cpu(keyp->br_startoff)); } + prevp = keyp; + /* - * Otherwise we're filling in a hole with an allocation. + * Compare the block numbers to see if there are dups. */ - else { - if (cur) - ASSERT((cur->bc_private.b.flags & - XFS_BTCUR_BPRV_WASDEL) == 0); - if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, - new, &logflags, whichfork))) - goto done; - } - } - - ASSERT(*curp == cur || *curp == NULL); - /* - * Convert to a btree if necessary. - */ - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && - XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max) { - int tmp_logflags; /* partial log flag return val */ - - ASSERT(cur == NULL); - error = xfs_bmap_extents_to_btree(ip->i_transp, ip, first, - flist, &cur, da_old > 0, &tmp_logflags, whichfork); - logflags |= tmp_logflags; - if (error) - goto done; - } - /* - * Adjust for changes in reserved delayed indirect blocks. - * Nothing to do for disk quotas here. - */ - if (da_old || da_new) { - xfs_filblks_t nblks; + if (root) + pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, i, sz); + else + pp = XFS_BMBT_PTR_ADDR(mp, block, i, dmxr); - nblks = da_new; - if (cur) - nblks += cur->bc_private.b.allocated; - ASSERT(nblks <= da_old); - if (nblks < da_old) - xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, - (int64_t)(da_old - nblks), rsvd); - } - /* - * Clear out the allocated field, done with it now in any case. - */ - if (cur) { - cur->bc_private.b.allocated = 0; - *curp = cur; + for (j = i+1; j <= be16_to_cpu(block->bb_numrecs); j++) { + if (root) + thispa = XFS_BMAP_BROOT_PTR_ADDR(mp, block, j, sz); + else + thispa = XFS_BMBT_PTR_ADDR(mp, block, j, dmxr); + if (*thispa == *pp) { + xfs_warn(mp, "%s: thispa(%d) == pp(%d) %Ld", + __func__, j, i, + (unsigned long long)be64_to_cpu(*thispa)); + panic("%s: ptrs are equal in node\n", + __func__); + } + } } -done: -#ifdef DEBUG - if (!error) - xfs_bmap_check_leaf_extents(*curp, ip, whichfork); -#endif - *logflagsp = logflags; - return error; } /* - * Called by xfs_bmap_add_extent to handle cases converting a delayed - * allocation to a real allocation. + * Check that the extents for the inode ip are in the right order in all + * btree leaves. */ -STATIC int /* error */ -xfs_bmap_add_extent_delay_real( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* extent number to update/insert */ - xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ - xfs_bmbt_irec_t *new, /* new data to add to file extents */ - xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ - xfs_fsblock_t *first, /* pointer to firstblock variable */ - xfs_bmap_free_t *flist, /* list of extents to be freed */ - int *logflagsp, /* inode logging flags */ - int rsvd) /* OK to use reserved data block allocation */ + +STATIC void +xfs_bmap_check_leaf_extents( + xfs_btree_cur_t *cur, /* btree cursor or null */ + xfs_inode_t *ip, /* incore inode pointer */ + int whichfork) /* data or attr fork */ { - xfs_btree_cur_t *cur; /* btree cursor */ - int diff; /* temp value */ - xfs_bmbt_rec_host_t *ep; /* extent entry for idx */ + struct xfs_btree_block *block; /* current btree block */ + xfs_fsblock_t bno; /* block # of "block" */ + xfs_buf_t *bp; /* buffer for "block" */ int error; /* error return value */ - int i; /* temp state */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_fileoff_t new_endoff; /* end offset of new entry */ - xfs_bmbt_irec_t r[3]; /* neighbor extent entries */ - /* left is 0, right is 1, prev is 2 */ - int rval=0; /* return value (logging flags) */ - int state = 0;/* state bits, accessed thru macros */ - xfs_filblks_t temp=0; /* value for dnew calculations */ - xfs_filblks_t temp2=0;/* value for dnew calculations */ - int tmp_rval; /* partial logging flags */ + xfs_extnum_t i=0, j; /* index into the extents list */ + xfs_ifork_t *ifp; /* fork structure */ + int level; /* btree level, for checking */ + xfs_mount_t *mp; /* file system mount structure */ + __be64 *pp; /* pointer to block address */ + xfs_bmbt_rec_t *ep; /* pointer to current extent */ + xfs_bmbt_rec_t last = {0, 0}; /* last extent in prev block */ + xfs_bmbt_rec_t *nextp; /* pointer to next extent */ + int bp_release = 0; -#define LEFT r[0] -#define RIGHT r[1] -#define PREV r[2] + if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) { + return; + } + bno = NULLFSBLOCK; + mp = ip->i_mount; + ifp = XFS_IFORK_PTR(ip, whichfork); + block = ifp->if_broot; /* - * Set up a bunch of variables to make the tests simpler. + * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. */ - cur = *curp; - ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); - ep = xfs_iext_get_ext(ifp, idx); - xfs_bmbt_get_all(ep, &PREV); - new_endoff = new->br_startoff + new->br_blockcount; - ASSERT(PREV.br_startoff <= new->br_startoff); - ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff); + level = be16_to_cpu(block->bb_level); + ASSERT(level > 0); + xfs_check_block(block, mp, 1, ifp->if_broot_bytes); + pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); + bno = be64_to_cpu(*pp); - /* - * Set flags determining what part of the previous delayed allocation - * extent is being replaced by a real allocation. - */ - if (PREV.br_startoff == new->br_startoff) - state |= BMAP_LEFT_FILLING; - if (PREV.br_startoff + PREV.br_blockcount == new_endoff) - state |= BMAP_RIGHT_FILLING; + ASSERT(bno != NULLDFSBNO); + ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); + ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); /* - * Check and set flags if this segment has a left neighbor. - * Don't set contiguous if the combined extent would be too large. + * Go down the tree until leaf level is reached, following the first + * pointer (leftmost) at each level. */ - if (idx > 0) { - state |= BMAP_LEFT_VALID; - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT); + while (level-- > 0) { + /* See if buf is in cur first */ + bp_release = 0; + bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno)); + if (!bp) { + bp_release = 1; + error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp, + XFS_BMAP_BTREE_REF, + &xfs_bmbt_buf_ops); + if (error) + goto error_norelse; + } + block = XFS_BUF_TO_BLOCK(bp); + XFS_WANT_CORRUPTED_GOTO( + xfs_bmap_sanity_check(mp, bp, level), + error0); + if (level == 0) + break; - if (isnullstartblock(LEFT.br_startblock)) - state |= BMAP_LEFT_DELAY; + /* + * Check this block for basic sanity (increasing keys and + * no duplicate blocks). + */ + + xfs_check_block(block, mp, 0, 0); + pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); + bno = be64_to_cpu(*pp); + XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0); + if (bp_release) { + bp_release = 0; + xfs_trans_brelse(NULL, bp); + } } - if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) && - LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff && - LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock && - LEFT.br_state == new->br_state && - LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN) - state |= BMAP_LEFT_CONTIG; + /* + * Here with bp and block set to the leftmost leaf node in the tree. + */ + i = 0; /* - * Check and set flags if this segment has a right neighbor. - * Don't set contiguous if the combined extent would be too large. - * Also check for all-three-contiguous being too large. + * Loop over all leaf nodes checking that all extents are in the right order. */ - if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { - state |= BMAP_RIGHT_VALID; - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT); + for (;;) { + xfs_fsblock_t nextbno; + xfs_extnum_t num_recs; - if (isnullstartblock(RIGHT.br_startblock)) - state |= BMAP_RIGHT_DELAY; - } - if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) && - new_endoff == RIGHT.br_startoff && - new->br_startblock + new->br_blockcount == RIGHT.br_startblock && - new->br_state == RIGHT.br_state && - new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN && - ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | - BMAP_RIGHT_FILLING)) != - (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | - BMAP_RIGHT_FILLING) || - LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount - <= MAXEXTLEN)) - state |= BMAP_RIGHT_CONTIG; + num_recs = xfs_btree_get_numrecs(block); - error = 0; - /* - * Switch out based on the FILLING and CONTIG state bits. - */ - switch (state & (BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | - BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG)) { - case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | - BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* - * Filling in all of a previously delayed allocation extent. - * The left and right neighbors are both contiguous with new. + * Read-ahead the next leaf block, if any. */ - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), - LEFT.br_blockcount + PREV.br_blockcount + - RIGHT.br_blockcount); - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); - xfs_iext_remove(ip, idx, 2, state); - ip->i_df.if_lastex = idx - 1; - ip->i_d.di_nextents--; - if (cur == NULL) - rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; - else { - rval = XFS_ILOG_CORE; - if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, - RIGHT.br_startblock, - RIGHT.br_blockcount, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_btree_delete(cur, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_btree_decrement(cur, 0, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, - LEFT.br_startblock, - LEFT.br_blockcount + - PREV.br_blockcount + - RIGHT.br_blockcount, LEFT.br_state))) - goto done; - } - *dnew = 0; - break; + nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib); - case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: /* - * Filling in all of a previously delayed allocation extent. - * The left neighbor is contiguous, the right is not. - */ - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), - LEFT.br_blockcount + PREV.br_blockcount); - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); - - ip->i_df.if_lastex = idx - 1; - xfs_iext_remove(ip, idx, 1, state); - if (cur == NULL) - rval = XFS_ILOG_DEXT; - else { - rval = 0; - if ((error = xfs_bmbt_lookup_eq(cur, LEFT.br_startoff, - LEFT.br_startblock, LEFT.br_blockcount, - &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, - LEFT.br_startblock, - LEFT.br_blockcount + - PREV.br_blockcount, LEFT.br_state))) - goto done; + * Check all the extents to make sure they are OK. + * If we had a previous block, the last entry should + * conform with the first entry in this one. + */ + + ep = XFS_BMBT_REC_ADDR(mp, block, 1); + if (i) { + ASSERT(xfs_bmbt_disk_get_startoff(&last) + + xfs_bmbt_disk_get_blockcount(&last) <= + xfs_bmbt_disk_get_startoff(ep)); + } + for (j = 1; j < num_recs; j++) { + nextp = XFS_BMBT_REC_ADDR(mp, block, j + 1); + ASSERT(xfs_bmbt_disk_get_startoff(ep) + + xfs_bmbt_disk_get_blockcount(ep) <= + xfs_bmbt_disk_get_startoff(nextp)); + ep = nextp; + } + + last = *ep; + i += num_recs; + if (bp_release) { + bp_release = 0; + xfs_trans_brelse(NULL, bp); } - *dnew = 0; - break; - - case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: + bno = nextbno; /* - * Filling in all of a previously delayed allocation extent. - * The right neighbor is contiguous, the left is not. + * If we've reached the end, stop. */ - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); - xfs_bmbt_set_startblock(ep, new->br_startblock); - xfs_bmbt_set_blockcount(ep, - PREV.br_blockcount + RIGHT.br_blockcount); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); + if (bno == NULLFSBLOCK) + break; - ip->i_df.if_lastex = idx; - xfs_iext_remove(ip, idx + 1, 1, state); - if (cur == NULL) - rval = XFS_ILOG_DEXT; - else { - rval = 0; - if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, - RIGHT.br_startblock, - RIGHT.br_blockcount, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_bmbt_update(cur, PREV.br_startoff, - new->br_startblock, - PREV.br_blockcount + - RIGHT.br_blockcount, PREV.br_state))) - goto done; + bp_release = 0; + bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno)); + if (!bp) { + bp_release = 1; + error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp, + XFS_BMAP_BTREE_REF, + &xfs_bmbt_buf_ops); + if (error) + goto error_norelse; } - *dnew = 0; - break; + block = XFS_BUF_TO_BLOCK(bp); + } + if (bp_release) { + bp_release = 0; + xfs_trans_brelse(NULL, bp); + } + return; - case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING: - /* - * Filling in all of a previously delayed allocation extent. - * Neither the left nor right neighbors are contiguous with - * the new one. - */ - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); - xfs_bmbt_set_startblock(ep, new->br_startblock); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); +error0: + xfs_warn(mp, "%s: at error0", __func__); + if (bp_release) + xfs_trans_brelse(NULL, bp); +error_norelse: + xfs_warn(mp, "%s: BAD after btree leaves for %d extents", + __func__, i); + panic("%s: CORRUPTED BTREE OR SOMETHING", __func__); + return; +} - ip->i_df.if_lastex = idx; - ip->i_d.di_nextents++; - if (cur == NULL) - rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; - else { - rval = XFS_ILOG_CORE; - if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, - new->br_startblock, new->br_blockcount, - &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 0, done); - cur->bc_rec.b.br_state = XFS_EXT_NORM; - if ((error = xfs_btree_insert(cur, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - } - *dnew = 0; - break; +/* + * Add bmap trace insert entries for all the contents of the extent records. + */ +void +xfs_bmap_trace_exlist( + xfs_inode_t *ip, /* incore inode pointer */ + xfs_extnum_t cnt, /* count of entries in the list */ + int whichfork, /* data or attr fork */ + unsigned long caller_ip) +{ + xfs_extnum_t idx; /* extent record index */ + xfs_ifork_t *ifp; /* inode fork pointer */ + int state = 0; - case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG: - /* - * Filling in the first part of a previous delayed allocation. - * The left neighbor is contiguous. - */ - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), - LEFT.br_blockcount + new->br_blockcount); - xfs_bmbt_set_startoff(ep, - PREV.br_startoff + new->br_blockcount); - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); + if (whichfork == XFS_ATTR_FORK) + state |= BMAP_ATTRFORK; - temp = PREV.br_blockcount - new->br_blockcount; - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); - xfs_bmbt_set_blockcount(ep, temp); - ip->i_df.if_lastex = idx - 1; - if (cur == NULL) - rval = XFS_ILOG_DEXT; - else { - rval = 0; - if ((error = xfs_bmbt_lookup_eq(cur, LEFT.br_startoff, - LEFT.br_startblock, LEFT.br_blockcount, - &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, - LEFT.br_startblock, - LEFT.br_blockcount + - new->br_blockcount, - LEFT.br_state))) - goto done; + ifp = XFS_IFORK_PTR(ip, whichfork); + ASSERT(cnt == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))); + for (idx = 0; idx < cnt; idx++) + trace_xfs_extlist(ip, idx, whichfork, caller_ip); +} + +/* + * Validate that the bmbt_irecs being returned from bmapi are valid + * given the caller's original parameters. Specifically check the + * ranges of the returned irecs to ensure that they only extend beyond + * the given parameters if the XFS_BMAPI_ENTIRE flag was set. + */ +STATIC void +xfs_bmap_validate_ret( + xfs_fileoff_t bno, + xfs_filblks_t len, + int flags, + xfs_bmbt_irec_t *mval, + int nmap, + int ret_nmap) +{ + int i; /* index to map values */ + + ASSERT(ret_nmap <= nmap); + + for (i = 0; i < ret_nmap; i++) { + ASSERT(mval[i].br_blockcount > 0); + if (!(flags & XFS_BMAPI_ENTIRE)) { + ASSERT(mval[i].br_startoff >= bno); + ASSERT(mval[i].br_blockcount <= len); + ASSERT(mval[i].br_startoff + mval[i].br_blockcount <= + bno + len); + } else { + ASSERT(mval[i].br_startoff < bno + len); + ASSERT(mval[i].br_startoff + mval[i].br_blockcount > + bno); } - temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), - startblockval(PREV.br_startblock)); - xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); - *dnew = temp; - break; + ASSERT(i == 0 || + mval[i - 1].br_startoff + mval[i - 1].br_blockcount == + mval[i].br_startoff); + ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK && + mval[i].br_startblock != HOLESTARTBLOCK); + ASSERT(mval[i].br_state == XFS_EXT_NORM || + mval[i].br_state == XFS_EXT_UNWRITTEN); + } +} - case BMAP_LEFT_FILLING: - /* - * Filling in the first part of a previous delayed allocation. - * The left neighbor is not contiguous. - */ - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); - xfs_bmbt_set_startoff(ep, new_endoff); - temp = PREV.br_blockcount - new->br_blockcount; - xfs_bmbt_set_blockcount(ep, temp); - xfs_iext_insert(ip, idx, 1, new, state); - ip->i_df.if_lastex = idx; - ip->i_d.di_nextents++; - if (cur == NULL) - rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; - else { - rval = XFS_ILOG_CORE; - if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, - new->br_startblock, new->br_blockcount, - &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 0, done); - cur->bc_rec.b.br_state = XFS_EXT_NORM; - if ((error = xfs_btree_insert(cur, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - } - if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && - ip->i_d.di_nextents > ip->i_df.if_ext_max) { - error = xfs_bmap_extents_to_btree(ip->i_transp, ip, - first, flist, &cur, 1, &tmp_rval, - XFS_DATA_FORK); - rval |= tmp_rval; - if (error) - goto done; - } - temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), - startblockval(PREV.br_startblock) - - (cur ? cur->bc_private.b.allocated : 0)); - ep = xfs_iext_get_ext(ifp, idx + 1); - xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); - trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); - *dnew = temp; - break; +#else +#define xfs_bmap_check_leaf_extents(cur, ip, whichfork) do { } while (0) +#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) +#endif /* DEBUG */ - case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: - /* - * Filling in the last part of a previous delayed allocation. - * The right neighbor is contiguous with the new allocation. - */ - temp = PREV.br_blockcount - new->br_blockcount; - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); - trace_xfs_bmap_pre_update(ip, idx + 1, state, _THIS_IP_); - xfs_bmbt_set_blockcount(ep, temp); - xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), - new->br_startoff, new->br_startblock, - new->br_blockcount + RIGHT.br_blockcount, - RIGHT.br_state); - trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); - ip->i_df.if_lastex = idx + 1; - if (cur == NULL) - rval = XFS_ILOG_DEXT; - else { - rval = 0; - if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, - RIGHT.br_startblock, - RIGHT.br_blockcount, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_bmbt_update(cur, new->br_startoff, - new->br_startblock, - new->br_blockcount + - RIGHT.br_blockcount, - RIGHT.br_state))) - goto done; - } - temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), - startblockval(PREV.br_startblock)); - xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); - *dnew = temp; - break; +/* + * bmap free list manipulation functions + */ - case BMAP_RIGHT_FILLING: - /* - * Filling in the last part of a previous delayed allocation. - * The right neighbor is not contiguous. - */ - temp = PREV.br_blockcount - new->br_blockcount; - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); - xfs_bmbt_set_blockcount(ep, temp); - xfs_iext_insert(ip, idx + 1, 1, new, state); - ip->i_df.if_lastex = idx + 1; - ip->i_d.di_nextents++; - if (cur == NULL) - rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; - else { - rval = XFS_ILOG_CORE; - if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, - new->br_startblock, new->br_blockcount, - &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 0, done); - cur->bc_rec.b.br_state = XFS_EXT_NORM; - if ((error = xfs_btree_insert(cur, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - } - if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && - ip->i_d.di_nextents > ip->i_df.if_ext_max) { - error = xfs_bmap_extents_to_btree(ip->i_transp, ip, - first, flist, &cur, 1, &tmp_rval, - XFS_DATA_FORK); - rval |= tmp_rval; - if (error) - goto done; - } - temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), - startblockval(PREV.br_startblock) - - (cur ? cur->bc_private.b.allocated : 0)); - ep = xfs_iext_get_ext(ifp, idx); - xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); - *dnew = temp; - break; +/* + * Add the extent to the list of extents to be free at transaction end. + * The list is maintained sorted (by block number). + */ +void +xfs_bmap_add_free( + xfs_fsblock_t bno, /* fs block number of extent */ + xfs_filblks_t len, /* length of extent */ + xfs_bmap_free_t *flist, /* list of extents */ + xfs_mount_t *mp) /* mount point structure */ +{ + xfs_bmap_free_item_t *cur; /* current (next) element */ + xfs_bmap_free_item_t *new; /* new element */ + xfs_bmap_free_item_t *prev; /* previous element */ +#ifdef DEBUG + xfs_agnumber_t agno; + xfs_agblock_t agbno; - case 0: - /* - * Filling in the middle part of a previous delayed allocation. - * Contiguity is impossible here. - * This case is avoided almost all the time. - */ - temp = new->br_startoff - PREV.br_startoff; - trace_xfs_bmap_pre_update(ip, idx, 0, _THIS_IP_); - xfs_bmbt_set_blockcount(ep, temp); - r[0] = *new; - r[1].br_state = PREV.br_state; - r[1].br_startblock = 0; - r[1].br_startoff = new_endoff; - temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; - r[1].br_blockcount = temp2; - xfs_iext_insert(ip, idx + 1, 2, &r[0], state); - ip->i_df.if_lastex = idx + 1; - ip->i_d.di_nextents++; - if (cur == NULL) - rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; - else { - rval = XFS_ILOG_CORE; - if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, - new->br_startblock, new->br_blockcount, - &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 0, done); - cur->bc_rec.b.br_state = XFS_EXT_NORM; - if ((error = xfs_btree_insert(cur, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - } - if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && - ip->i_d.di_nextents > ip->i_df.if_ext_max) { - error = xfs_bmap_extents_to_btree(ip->i_transp, ip, - first, flist, &cur, 1, &tmp_rval, - XFS_DATA_FORK); - rval |= tmp_rval; - if (error) - goto done; - } - temp = xfs_bmap_worst_indlen(ip, temp); - temp2 = xfs_bmap_worst_indlen(ip, temp2); - diff = (int)(temp + temp2 - startblockval(PREV.br_startblock) - - (cur ? cur->bc_private.b.allocated : 0)); - if (diff > 0 && - xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, - -((int64_t)diff), rsvd)) { - /* - * Ick gross gag me with a spoon. - */ - ASSERT(0); /* want to see if this ever happens! */ - while (diff > 0) { - if (temp) { - temp--; - diff--; - if (!diff || - !xfs_icsb_modify_counters(ip->i_mount, - XFS_SBS_FDBLOCKS, - -((int64_t)diff), rsvd)) - break; - } - if (temp2) { - temp2--; - diff--; - if (!diff || - !xfs_icsb_modify_counters(ip->i_mount, - XFS_SBS_FDBLOCKS, - -((int64_t)diff), rsvd)) - break; - } - } - } - ep = xfs_iext_get_ext(ifp, idx); - xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); - trace_xfs_bmap_pre_update(ip, idx + 2, state, _THIS_IP_); - xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx + 2), - nullstartblock((int)temp2)); - trace_xfs_bmap_post_update(ip, idx + 2, state, _THIS_IP_); - *dnew = temp + temp2; - break; + ASSERT(bno != NULLFSBLOCK); + ASSERT(len > 0); + ASSERT(len <= MAXEXTLEN); + ASSERT(!isnullstartblock(bno)); + agno = XFS_FSB_TO_AGNO(mp, bno); + agbno = XFS_FSB_TO_AGBNO(mp, bno); + ASSERT(agno < mp->m_sb.sb_agcount); + ASSERT(agbno < mp->m_sb.sb_agblocks); + ASSERT(len < mp->m_sb.sb_agblocks); + ASSERT(agbno + len <= mp->m_sb.sb_agblocks); +#endif + ASSERT(xfs_bmap_free_item_zone != NULL); + new = kmem_zone_alloc(xfs_bmap_free_item_zone, KM_SLEEP); + new->xbfi_startblock = bno; + new->xbfi_blockcount = (xfs_extlen_t)len; + for (prev = NULL, cur = flist->xbf_first; + cur != NULL; + prev = cur, cur = cur->xbfi_next) { + if (cur->xbfi_startblock >= bno) + break; + } + if (prev) + prev->xbfi_next = new; + else + flist->xbf_first = new; + new->xbfi_next = cur; + flist->xbf_count++; +} - case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: - case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: - case BMAP_LEFT_FILLING | BMAP_RIGHT_CONTIG: - case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: - case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: - case BMAP_LEFT_CONTIG: - case BMAP_RIGHT_CONTIG: - /* - * These cases are all impossible. - */ - ASSERT(0); +/* + * Remove the entry "free" from the free item list. Prev points to the + * previous entry, unless "free" is the head of the list. + */ +void +xfs_bmap_del_free( + xfs_bmap_free_t *flist, /* free item list header */ + xfs_bmap_free_item_t *prev, /* previous item on list, if any */ + xfs_bmap_free_item_t *free) /* list item to be freed */ +{ + if (prev) + prev->xbfi_next = free->xbfi_next; + else + flist->xbf_first = free->xbfi_next; + flist->xbf_count--; + kmem_zone_free(xfs_bmap_free_item_zone, free); +} + +/* + * Free up any items left in the list. + */ +void +xfs_bmap_cancel( + xfs_bmap_free_t *flist) /* list of bmap_free_items */ +{ + xfs_bmap_free_item_t *free; /* free list item */ + xfs_bmap_free_item_t *next; + + if (flist->xbf_count == 0) + return; + ASSERT(flist->xbf_first != NULL); + for (free = flist->xbf_first; free; free = next) { + next = free->xbfi_next; + xfs_bmap_del_free(flist, NULL, free); } - *curp = cur; -done: - *logflagsp = rval; - return error; -#undef LEFT -#undef RIGHT -#undef PREV + ASSERT(flist->xbf_count == 0); } /* - * Called by xfs_bmap_add_extent to handle cases converting an unwritten - * allocation to a real allocation or vice versa. + * Inode fork format manipulation functions + */ + +/* + * Transform a btree format file with only one leaf node, where the + * extents list will fit in the inode, into an extents format file. + * Since the file extents are already in-core, all we have to do is + * give up the space for the btree root and pitch the leaf block. */ STATIC int /* error */ -xfs_bmap_add_extent_unwritten_real( +xfs_bmap_btree_to_extents( + xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* extent number to update/insert */ - xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ - xfs_bmbt_irec_t *new, /* new data to add to file extents */ - int *logflagsp) /* inode logging flags */ + xfs_btree_cur_t *cur, /* btree cursor */ + int *logflagsp, /* inode logging flags */ + int whichfork) /* data or attr fork */ { - xfs_btree_cur_t *cur; /* btree cursor */ - xfs_bmbt_rec_host_t *ep; /* extent entry for idx */ + /* REFERENCED */ + struct xfs_btree_block *cblock;/* child btree block */ + xfs_fsblock_t cbno; /* child block number */ + xfs_buf_t *cbp; /* child block's buffer */ int error; /* error return value */ - int i; /* temp state */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_fileoff_t new_endoff; /* end offset of new entry */ - xfs_exntst_t newext; /* new extent state */ - xfs_exntst_t oldext; /* old extent state */ - xfs_bmbt_irec_t r[3]; /* neighbor extent entries */ - /* left is 0, right is 1, prev is 2 */ - int rval=0; /* return value (logging flags) */ - int state = 0;/* state bits, accessed thru macros */ + xfs_ifork_t *ifp; /* inode fork data */ + xfs_mount_t *mp; /* mount point structure */ + __be64 *pp; /* ptr to block address */ + struct xfs_btree_block *rblock;/* root btree block */ + + mp = ip->i_mount; + ifp = XFS_IFORK_PTR(ip, whichfork); + ASSERT(ifp->if_flags & XFS_IFEXTENTS); + ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); + rblock = ifp->if_broot; + ASSERT(be16_to_cpu(rblock->bb_level) == 1); + ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1); + ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0) == 1); + pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes); + cbno = be64_to_cpu(*pp); + *logflagsp = 0; +#ifdef DEBUG + if ((error = xfs_btree_check_lptr(cur, cbno, 1))) + return error; +#endif + error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, XFS_BMAP_BTREE_REF, + &xfs_bmbt_buf_ops); + if (error) + return error; + cblock = XFS_BUF_TO_BLOCK(cbp); + if ((error = xfs_btree_check_block(cur, cblock, 0, cbp))) + return error; + xfs_bmap_add_free(cbno, 1, cur->bc_private.b.flist, mp); + ip->i_d.di_nblocks--; + xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); + xfs_trans_binval(tp, cbp); + if (cur->bc_bufs[0] == cbp) + cur->bc_bufs[0] = NULL; + xfs_iroot_realloc(ip, -1, whichfork); + ASSERT(ifp->if_broot == NULL); + ASSERT((ifp->if_flags & XFS_IFBROOT) == 0); + XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); + *logflagsp = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); + return 0; +} + +/* + * Convert an extents-format file into a btree-format file. + * The new file will have a root block (in the inode) and a single child block. + */ +STATIC int /* error */ +xfs_bmap_extents_to_btree( + xfs_trans_t *tp, /* transaction pointer */ + xfs_inode_t *ip, /* incore inode pointer */ + xfs_fsblock_t *firstblock, /* first-block-allocated */ + xfs_bmap_free_t *flist, /* blocks freed in xaction */ + xfs_btree_cur_t **curp, /* cursor returned to caller */ + int wasdel, /* converting a delayed alloc */ + int *logflagsp, /* inode logging flags */ + int whichfork) /* data or attr fork */ +{ + struct xfs_btree_block *ablock; /* allocated (child) bt block */ + xfs_buf_t *abp; /* buffer for ablock */ + xfs_alloc_arg_t args; /* allocation arguments */ + xfs_bmbt_rec_t *arp; /* child record pointer */ + struct xfs_btree_block *block; /* btree root block */ + xfs_btree_cur_t *cur; /* bmap btree cursor */ + xfs_bmbt_rec_host_t *ep; /* extent record pointer */ + int error; /* error return value */ + xfs_extnum_t i, cnt; /* extent record index */ + xfs_ifork_t *ifp; /* inode fork pointer */ + xfs_bmbt_key_t *kp; /* root block key pointer */ + xfs_mount_t *mp; /* mount structure */ + xfs_extnum_t nextents; /* number of file extents */ + xfs_bmbt_ptr_t *pp; /* root block address pointer */ + + mp = ip->i_mount; + ifp = XFS_IFORK_PTR(ip, whichfork); + ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS); -#define LEFT r[0] -#define RIGHT r[1] -#define PREV r[2] /* - * Set up a bunch of variables to make the tests simpler. + * Make space in the inode incore. */ - error = 0; - cur = *curp; - ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); - ep = xfs_iext_get_ext(ifp, idx); - xfs_bmbt_get_all(ep, &PREV); - newext = new->br_state; - oldext = (newext == XFS_EXT_UNWRITTEN) ? - XFS_EXT_NORM : XFS_EXT_UNWRITTEN; - ASSERT(PREV.br_state == oldext); - new_endoff = new->br_startoff + new->br_blockcount; - ASSERT(PREV.br_startoff <= new->br_startoff); - ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff); + xfs_iroot_realloc(ip, 1, whichfork); + ifp->if_flags |= XFS_IFBROOT; /* - * Set flags determining what part of the previous oldext allocation - * extent is being replaced by a newext allocation. + * Fill in the root. */ - if (PREV.br_startoff == new->br_startoff) - state |= BMAP_LEFT_FILLING; - if (PREV.br_startoff + PREV.br_blockcount == new_endoff) - state |= BMAP_RIGHT_FILLING; + block = ifp->if_broot; + if (xfs_sb_version_hascrc(&mp->m_sb)) + xfs_btree_init_block_int(mp, block, XFS_BUF_DADDR_NULL, + XFS_BMAP_CRC_MAGIC, 1, 1, ip->i_ino, + XFS_BTREE_LONG_PTRS | XFS_BTREE_CRC_BLOCKS); + else + xfs_btree_init_block_int(mp, block, XFS_BUF_DADDR_NULL, + XFS_BMAP_MAGIC, 1, 1, ip->i_ino, + XFS_BTREE_LONG_PTRS); /* - * Check and set flags if this segment has a left neighbor. - * Don't set contiguous if the combined extent would be too large. + * Need a cursor. Can't allocate until bb_level is filled in. */ - if (idx > 0) { - state |= BMAP_LEFT_VALID; - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT); + cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); + cur->bc_private.b.firstblock = *firstblock; + cur->bc_private.b.flist = flist; + cur->bc_private.b.flags = wasdel ? XFS_BTCUR_BPRV_WASDEL : 0; + /* + * Convert to a btree with two levels, one record in root. + */ + XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); + memset(&args, 0, sizeof(args)); + args.tp = tp; + args.mp = mp; + args.firstblock = *firstblock; + if (*firstblock == NULLFSBLOCK) { + args.type = XFS_ALLOCTYPE_START_BNO; + args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); + } else if (flist->xbf_low) { + args.type = XFS_ALLOCTYPE_START_BNO; + args.fsbno = *firstblock; + } else { + args.type = XFS_ALLOCTYPE_NEAR_BNO; + args.fsbno = *firstblock; + } + args.minlen = args.maxlen = args.prod = 1; + args.wasdel = wasdel; + *logflagsp = 0; + if ((error = xfs_alloc_vextent(&args))) { + xfs_iroot_realloc(ip, -1, whichfork); + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); + return error; + } + /* + * Allocation can't fail, the space was reserved. + */ + ASSERT(args.fsbno != NULLFSBLOCK); + ASSERT(*firstblock == NULLFSBLOCK || + args.agno == XFS_FSB_TO_AGNO(mp, *firstblock) || + (flist->xbf_low && + args.agno > XFS_FSB_TO_AGNO(mp, *firstblock))); + *firstblock = cur->bc_private.b.firstblock = args.fsbno; + cur->bc_private.b.allocated++; + ip->i_d.di_nblocks++; + xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); + abp = xfs_btree_get_bufl(mp, tp, args.fsbno, 0); + /* + * Fill in the child block. + */ + abp->b_ops = &xfs_bmbt_buf_ops; + ablock = XFS_BUF_TO_BLOCK(abp); + if (xfs_sb_version_hascrc(&mp->m_sb)) + xfs_btree_init_block_int(mp, ablock, abp->b_bn, + XFS_BMAP_CRC_MAGIC, 0, 0, ip->i_ino, + XFS_BTREE_LONG_PTRS | XFS_BTREE_CRC_BLOCKS); + else + xfs_btree_init_block_int(mp, ablock, abp->b_bn, + XFS_BMAP_MAGIC, 0, 0, ip->i_ino, + XFS_BTREE_LONG_PTRS); - if (isnullstartblock(LEFT.br_startblock)) - state |= BMAP_LEFT_DELAY; + arp = XFS_BMBT_REC_ADDR(mp, ablock, 1); + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + for (cnt = i = 0; i < nextents; i++) { + ep = xfs_iext_get_ext(ifp, i); + if (!isnullstartblock(xfs_bmbt_get_startblock(ep))) { + arp->l0 = cpu_to_be64(ep->l0); + arp->l1 = cpu_to_be64(ep->l1); + arp++; cnt++; + } } + ASSERT(cnt == XFS_IFORK_NEXTENTS(ip, whichfork)); + xfs_btree_set_numrecs(ablock, cnt); - if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) && - LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff && - LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock && - LEFT.br_state == newext && - LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN) - state |= BMAP_LEFT_CONTIG; + /* + * Fill in the root key and pointer. + */ + kp = XFS_BMBT_KEY_ADDR(mp, block, 1); + arp = XFS_BMBT_REC_ADDR(mp, ablock, 1); + kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp)); + pp = XFS_BMBT_PTR_ADDR(mp, block, 1, xfs_bmbt_get_maxrecs(cur, + be16_to_cpu(block->bb_level))); + *pp = cpu_to_be64(args.fsbno); /* - * Check and set flags if this segment has a right neighbor. - * Don't set contiguous if the combined extent would be too large. - * Also check for all-three-contiguous being too large. + * Do all this logging at the end so that + * the root is at the right level. */ - if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { - state |= BMAP_RIGHT_VALID; - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT); - if (isnullstartblock(RIGHT.br_startblock)) - state |= BMAP_RIGHT_DELAY; - } + xfs_btree_log_block(cur, abp, XFS_BB_ALL_BITS); + xfs_btree_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs)); + ASSERT(*curp == NULL); + *curp = cur; + *logflagsp = XFS_ILOG_CORE | xfs_ilog_fbroot(whichfork); + return 0; +} - if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) && - new_endoff == RIGHT.br_startoff && - new->br_startblock + new->br_blockcount == RIGHT.br_startblock && - newext == RIGHT.br_state && - new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN && - ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | - BMAP_RIGHT_FILLING)) != - (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | - BMAP_RIGHT_FILLING) || - LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount - <= MAXEXTLEN)) - state |= BMAP_RIGHT_CONTIG; +/* + * Convert a local file to an extents file. + * This code is out of bounds for data forks of regular files, + * since the file data needs to get logged so things will stay consistent. + * (The bmap-level manipulations are ok, though). + */ +void +xfs_bmap_local_to_extents_empty( + struct xfs_inode *ip, + int whichfork) +{ + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); + + ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); + ASSERT(ifp->if_bytes == 0); + ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0); + + xfs_bmap_forkoff_reset(ip->i_mount, ip, whichfork); + ifp->if_flags &= ~XFS_IFINLINE; + ifp->if_flags |= XFS_IFEXTENTS; + XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); +} + + +STATIC int /* error */ +xfs_bmap_local_to_extents( + xfs_trans_t *tp, /* transaction pointer */ + xfs_inode_t *ip, /* incore inode pointer */ + xfs_fsblock_t *firstblock, /* first block allocated in xaction */ + xfs_extlen_t total, /* total blocks needed by transaction */ + int *logflagsp, /* inode logging flags */ + int whichfork, + void (*init_fn)(struct xfs_trans *tp, + struct xfs_buf *bp, + struct xfs_inode *ip, + struct xfs_ifork *ifp)) +{ + int error = 0; + int flags; /* logging flags returned */ + xfs_ifork_t *ifp; /* inode fork pointer */ + xfs_alloc_arg_t args; /* allocation arguments */ + xfs_buf_t *bp; /* buffer for extent block */ + xfs_bmbt_rec_host_t *ep; /* extent record pointer */ /* - * Switch out based on the FILLING and CONTIG state bits. + * We don't want to deal with the case of keeping inode data inline yet. + * So sending the data fork of a regular inode is invalid. */ - switch (state & (BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | - BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG)) { - case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | - BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: - /* - * Setting all of a previous oldext extent to newext. - * The left and right neighbors are both contiguous with new. - */ - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), - LEFT.br_blockcount + PREV.br_blockcount + - RIGHT.br_blockcount); - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); + ASSERT(!(S_ISREG(ip->i_d.di_mode) && whichfork == XFS_DATA_FORK)); + ifp = XFS_IFORK_PTR(ip, whichfork); + ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); - xfs_iext_remove(ip, idx, 2, state); - ip->i_df.if_lastex = idx - 1; - ip->i_d.di_nextents -= 2; - if (cur == NULL) - rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; - else { - rval = XFS_ILOG_CORE; - if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, - RIGHT.br_startblock, - RIGHT.br_blockcount, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_btree_delete(cur, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_btree_decrement(cur, 0, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_btree_delete(cur, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_btree_decrement(cur, 0, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, - LEFT.br_startblock, - LEFT.br_blockcount + PREV.br_blockcount + - RIGHT.br_blockcount, LEFT.br_state))) - goto done; - } - break; + if (!ifp->if_bytes) { + xfs_bmap_local_to_extents_empty(ip, whichfork); + flags = XFS_ILOG_CORE; + goto done; + } - case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: - /* - * Setting all of a previous oldext extent to newext. - * The left neighbor is contiguous, the right is not. - */ - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), - LEFT.br_blockcount + PREV.br_blockcount); - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); + flags = 0; + error = 0; + ASSERT((ifp->if_flags & (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == + XFS_IFINLINE); + memset(&args, 0, sizeof(args)); + args.tp = tp; + args.mp = ip->i_mount; + args.firstblock = *firstblock; + /* + * Allocate a block. We know we need only one, since the + * file currently fits in an inode. + */ + if (*firstblock == NULLFSBLOCK) { + args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino); + args.type = XFS_ALLOCTYPE_START_BNO; + } else { + args.fsbno = *firstblock; + args.type = XFS_ALLOCTYPE_NEAR_BNO; + } + args.total = total; + args.minlen = args.maxlen = args.prod = 1; + error = xfs_alloc_vextent(&args); + if (error) + goto done; - ip->i_df.if_lastex = idx - 1; - xfs_iext_remove(ip, idx, 1, state); - ip->i_d.di_nextents--; - if (cur == NULL) - rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; - else { - rval = XFS_ILOG_CORE; - if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, - PREV.br_startblock, PREV.br_blockcount, - &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_btree_delete(cur, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_btree_decrement(cur, 0, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, - LEFT.br_startblock, - LEFT.br_blockcount + PREV.br_blockcount, - LEFT.br_state))) - goto done; - } - break; + /* Can't fail, the space was reserved. */ + ASSERT(args.fsbno != NULLFSBLOCK); + ASSERT(args.len == 1); + *firstblock = args.fsbno; + bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0); + + /* initialise the block and copy the data */ + init_fn(tp, bp, ip, ifp); + + /* account for the change in fork size and log everything */ + xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1); + xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); + xfs_bmap_local_to_extents_empty(ip, whichfork); + flags |= XFS_ILOG_CORE; - case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: - /* - * Setting all of a previous oldext extent to newext. - * The right neighbor is contiguous, the left is not. - */ - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); - xfs_bmbt_set_blockcount(ep, - PREV.br_blockcount + RIGHT.br_blockcount); - xfs_bmbt_set_state(ep, newext); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); - ip->i_df.if_lastex = idx; - xfs_iext_remove(ip, idx + 1, 1, state); - ip->i_d.di_nextents--; - if (cur == NULL) - rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; - else { - rval = XFS_ILOG_CORE; - if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, - RIGHT.br_startblock, - RIGHT.br_blockcount, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_btree_delete(cur, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_btree_decrement(cur, 0, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_bmbt_update(cur, new->br_startoff, - new->br_startblock, - new->br_blockcount + RIGHT.br_blockcount, - newext))) - goto done; - } - break; + xfs_iext_add(ifp, 0, 1); + ep = xfs_iext_get_ext(ifp, 0); + xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM); + trace_xfs_bmap_post_update(ip, 0, + whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0, + _THIS_IP_); + XFS_IFORK_NEXT_SET(ip, whichfork, 1); + ip->i_d.di_nblocks = 1; + xfs_trans_mod_dquot_byino(tp, ip, + XFS_TRANS_DQ_BCOUNT, 1L); + flags |= xfs_ilog_fext(whichfork); - case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING: - /* - * Setting all of a previous oldext extent to newext. - * Neither the left nor right neighbors are contiguous with - * the new one. - */ - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); - xfs_bmbt_set_state(ep, newext); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); +done: + *logflagsp = flags; + return error; +} - ip->i_df.if_lastex = idx; - if (cur == NULL) - rval = XFS_ILOG_DEXT; - else { - rval = 0; - if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, - new->br_startblock, new->br_blockcount, - &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_bmbt_update(cur, new->br_startoff, - new->br_startblock, new->br_blockcount, - newext))) - goto done; +/* + * Called from xfs_bmap_add_attrfork to handle btree format files. + */ +STATIC int /* error */ +xfs_bmap_add_attrfork_btree( + xfs_trans_t *tp, /* transaction pointer */ + xfs_inode_t *ip, /* incore inode pointer */ + xfs_fsblock_t *firstblock, /* first block allocated */ + xfs_bmap_free_t *flist, /* blocks to free at commit */ + int *flags) /* inode logging flags */ +{ + xfs_btree_cur_t *cur; /* btree cursor */ + int error; /* error return value */ + xfs_mount_t *mp; /* file system mount struct */ + int stat; /* newroot status */ + + mp = ip->i_mount; + if (ip->i_df.if_broot_bytes <= XFS_IFORK_DSIZE(ip)) + *flags |= XFS_ILOG_DBROOT; + else { + cur = xfs_bmbt_init_cursor(mp, tp, ip, XFS_DATA_FORK); + cur->bc_private.b.flist = flist; + cur->bc_private.b.firstblock = *firstblock; + if ((error = xfs_bmbt_lookup_ge(cur, 0, 0, 0, &stat))) + goto error0; + /* must be at least one entry */ + XFS_WANT_CORRUPTED_GOTO(stat == 1, error0); + if ((error = xfs_btree_new_iroot(cur, flags, &stat))) + goto error0; + if (stat == 0) { + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + return XFS_ERROR(ENOSPC); } - break; + *firstblock = cur->bc_private.b.firstblock; + cur->bc_private.b.allocated = 0; + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + } + return 0; +error0: + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); + return error; +} - case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG: - /* - * Setting the first part of a previous oldext extent to newext. - * The left neighbor is contiguous. - */ - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), - LEFT.br_blockcount + new->br_blockcount); - xfs_bmbt_set_startoff(ep, - PREV.br_startoff + new->br_blockcount); - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); +/* + * Called from xfs_bmap_add_attrfork to handle extents format files. + */ +STATIC int /* error */ +xfs_bmap_add_attrfork_extents( + xfs_trans_t *tp, /* transaction pointer */ + xfs_inode_t *ip, /* incore inode pointer */ + xfs_fsblock_t *firstblock, /* first block allocated */ + xfs_bmap_free_t *flist, /* blocks to free at commit */ + int *flags) /* inode logging flags */ +{ + xfs_btree_cur_t *cur; /* bmap btree cursor */ + int error; /* error return value */ - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); - xfs_bmbt_set_startblock(ep, - new->br_startblock + new->br_blockcount); - xfs_bmbt_set_blockcount(ep, - PREV.br_blockcount - new->br_blockcount); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); + if (ip->i_d.di_nextents * sizeof(xfs_bmbt_rec_t) <= XFS_IFORK_DSIZE(ip)) + return 0; + cur = NULL; + error = xfs_bmap_extents_to_btree(tp, ip, firstblock, flist, &cur, 0, + flags, XFS_DATA_FORK); + if (cur) { + cur->bc_private.b.allocated = 0; + xfs_btree_del_cursor(cur, + error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + } + return error; +} - ip->i_df.if_lastex = idx - 1; - if (cur == NULL) - rval = XFS_ILOG_DEXT; - else { - rval = 0; - if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, - PREV.br_startblock, PREV.br_blockcount, - &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_bmbt_update(cur, - PREV.br_startoff + new->br_blockcount, - PREV.br_startblock + new->br_blockcount, - PREV.br_blockcount - new->br_blockcount, - oldext))) - goto done; - if ((error = xfs_btree_decrement(cur, 0, &i))) - goto done; - if (xfs_bmbt_update(cur, LEFT.br_startoff, - LEFT.br_startblock, - LEFT.br_blockcount + new->br_blockcount, - LEFT.br_state)) - goto done; - } - break; +/* + * Called from xfs_bmap_add_attrfork to handle local format files. Each + * different data fork content type needs a different callout to do the + * conversion. Some are basic and only require special block initialisation + * callouts for the data formating, others (directories) are so specialised they + * handle everything themselves. + * + * XXX (dgc): investigate whether directory conversion can use the generic + * formatting callout. It should be possible - it's just a very complex + * formatter. + */ +STATIC int /* error */ +xfs_bmap_add_attrfork_local( + xfs_trans_t *tp, /* transaction pointer */ + xfs_inode_t *ip, /* incore inode pointer */ + xfs_fsblock_t *firstblock, /* first block allocated */ + xfs_bmap_free_t *flist, /* blocks to free at commit */ + int *flags) /* inode logging flags */ +{ + xfs_da_args_t dargs; /* args for dir/attr code */ - case BMAP_LEFT_FILLING: - /* - * Setting the first part of a previous oldext extent to newext. - * The left neighbor is not contiguous. - */ - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); - ASSERT(ep && xfs_bmbt_get_state(ep) == oldext); - xfs_bmbt_set_startoff(ep, new_endoff); - xfs_bmbt_set_blockcount(ep, - PREV.br_blockcount - new->br_blockcount); - xfs_bmbt_set_startblock(ep, - new->br_startblock + new->br_blockcount); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); + if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip)) + return 0; - xfs_iext_insert(ip, idx, 1, new, state); - ip->i_df.if_lastex = idx; - ip->i_d.di_nextents++; - if (cur == NULL) - rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; - else { - rval = XFS_ILOG_CORE; - if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, - PREV.br_startblock, PREV.br_blockcount, - &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_bmbt_update(cur, - PREV.br_startoff + new->br_blockcount, - PREV.br_startblock + new->br_blockcount, - PREV.br_blockcount - new->br_blockcount, - oldext))) - goto done; - cur->bc_rec.b = *new; - if ((error = xfs_btree_insert(cur, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - } - break; - - case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: - /* - * Setting the last part of a previous oldext extent to newext. - * The right neighbor is contiguous with the new allocation. - */ - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); - trace_xfs_bmap_pre_update(ip, idx + 1, state, _THIS_IP_); - xfs_bmbt_set_blockcount(ep, - PREV.br_blockcount - new->br_blockcount); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); - xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), - new->br_startoff, new->br_startblock, - new->br_blockcount + RIGHT.br_blockcount, newext); - trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); - - ip->i_df.if_lastex = idx + 1; - if (cur == NULL) - rval = XFS_ILOG_DEXT; - else { - rval = 0; - if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, - PREV.br_startblock, - PREV.br_blockcount, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_bmbt_update(cur, PREV.br_startoff, - PREV.br_startblock, - PREV.br_blockcount - new->br_blockcount, - oldext))) - goto done; - if ((error = xfs_btree_increment(cur, 0, &i))) - goto done; - if ((error = xfs_bmbt_update(cur, new->br_startoff, - new->br_startblock, - new->br_blockcount + RIGHT.br_blockcount, - newext))) - goto done; - } - break; - - case BMAP_RIGHT_FILLING: - /* - * Setting the last part of a previous oldext extent to newext. - * The right neighbor is not contiguous. - */ - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); - xfs_bmbt_set_blockcount(ep, - PREV.br_blockcount - new->br_blockcount); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); - - xfs_iext_insert(ip, idx + 1, 1, new, state); - ip->i_df.if_lastex = idx + 1; - ip->i_d.di_nextents++; - if (cur == NULL) - rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; - else { - rval = XFS_ILOG_CORE; - if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, - PREV.br_startblock, PREV.br_blockcount, - &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_bmbt_update(cur, PREV.br_startoff, - PREV.br_startblock, - PREV.br_blockcount - new->br_blockcount, - oldext))) - goto done; - if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, - new->br_startblock, new->br_blockcount, - &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 0, done); - cur->bc_rec.b.br_state = XFS_EXT_NORM; - if ((error = xfs_btree_insert(cur, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - } - break; - - case 0: - /* - * Setting the middle part of a previous oldext extent to - * newext. Contiguity is impossible here. - * One extent becomes three extents. - */ - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); - xfs_bmbt_set_blockcount(ep, - new->br_startoff - PREV.br_startoff); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); + if (S_ISDIR(ip->i_d.di_mode)) { + memset(&dargs, 0, sizeof(dargs)); + dargs.dp = ip; + dargs.firstblock = firstblock; + dargs.flist = flist; + dargs.total = ip->i_mount->m_dirblkfsbs; + dargs.whichfork = XFS_DATA_FORK; + dargs.trans = tp; + return xfs_dir2_sf_to_block(&dargs); + } - r[0] = *new; - r[1].br_startoff = new_endoff; - r[1].br_blockcount = - PREV.br_startoff + PREV.br_blockcount - new_endoff; - r[1].br_startblock = new->br_startblock + new->br_blockcount; - r[1].br_state = oldext; - xfs_iext_insert(ip, idx + 1, 2, &r[0], state); - ip->i_df.if_lastex = idx + 1; - ip->i_d.di_nextents += 2; - if (cur == NULL) - rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; - else { - rval = XFS_ILOG_CORE; - if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, - PREV.br_startblock, PREV.br_blockcount, - &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - /* new right extent - oldext */ - if ((error = xfs_bmbt_update(cur, r[1].br_startoff, - r[1].br_startblock, r[1].br_blockcount, - r[1].br_state))) - goto done; - /* new left extent - oldext */ - cur->bc_rec.b = PREV; - cur->bc_rec.b.br_blockcount = - new->br_startoff - PREV.br_startoff; - if ((error = xfs_btree_insert(cur, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - /* - * Reset the cursor to the position of the new extent - * we are about to insert as we can't trust it after - * the previous insert. - */ - if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, - new->br_startblock, new->br_blockcount, - &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 0, done); - /* new middle extent - newext */ - cur->bc_rec.b.br_state = new->br_state; - if ((error = xfs_btree_insert(cur, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - } - break; + if (S_ISLNK(ip->i_d.di_mode)) + return xfs_bmap_local_to_extents(tp, ip, firstblock, 1, + flags, XFS_DATA_FORK, + xfs_symlink_local_to_remote); - case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: - case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: - case BMAP_LEFT_FILLING | BMAP_RIGHT_CONTIG: - case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: - case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: - case BMAP_LEFT_CONTIG: - case BMAP_RIGHT_CONTIG: - /* - * These cases are all impossible. - */ - ASSERT(0); - } - *curp = cur; -done: - *logflagsp = rval; - return error; -#undef LEFT -#undef RIGHT -#undef PREV + /* should only be called for types that support local format data */ + ASSERT(0); + return EFSCORRUPTED; } /* - * Called by xfs_bmap_add_extent to handle cases converting a hole - * to a delayed allocation. + * Convert inode from non-attributed to attributed. + * Must not be in a transaction, ip must not be locked. */ -/*ARGSUSED*/ -STATIC int /* error */ -xfs_bmap_add_extent_hole_delay( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* extent number to update/insert */ - xfs_bmbt_irec_t *new, /* new data to add to file extents */ - int *logflagsp, /* inode logging flags */ - int rsvd) /* OK to allocate reserved blocks */ +int /* error code */ +xfs_bmap_add_attrfork( + xfs_inode_t *ip, /* incore inode pointer */ + int size, /* space new attribute needs */ + int rsvd) /* xact may use reserved blks */ { - xfs_bmbt_rec_host_t *ep; /* extent record for idx */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_bmbt_irec_t left; /* left neighbor extent entry */ - xfs_filblks_t newlen=0; /* new indirect size */ - xfs_filblks_t oldlen=0; /* old indirect size */ - xfs_bmbt_irec_t right; /* right neighbor extent entry */ - int state; /* state bits, accessed thru macros */ - xfs_filblks_t temp=0; /* temp for indirect calculations */ - - ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); - ep = xfs_iext_get_ext(ifp, idx); - state = 0; - ASSERT(isnullstartblock(new->br_startblock)); + xfs_fsblock_t firstblock; /* 1st block/ag allocated */ + xfs_bmap_free_t flist; /* freed extent records */ + xfs_mount_t *mp; /* mount structure */ + xfs_trans_t *tp; /* transaction pointer */ + int blks; /* space reservation */ + int version = 1; /* superblock attr version */ + int committed; /* xaction was committed */ + int logflags; /* logging flags */ + int error; /* error return value */ - /* - * Check and set flags if this segment has a left neighbor - */ - if (idx > 0) { - state |= BMAP_LEFT_VALID; - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left); + ASSERT(XFS_IFORK_Q(ip) == 0); - if (isnullstartblock(left.br_startblock)) - state |= BMAP_LEFT_DELAY; + mp = ip->i_mount; + ASSERT(!XFS_NOT_DQATTACHED(mp, ip)); + tp = xfs_trans_alloc(mp, XFS_TRANS_ADDAFORK); + blks = XFS_ADDAFORK_SPACE_RES(mp); + if (rsvd) + tp->t_flags |= XFS_TRANS_RESERVE; + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_addafork, blks, 0); + if (error) + goto error0; + xfs_ilock(ip, XFS_ILOCK_EXCL); + error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ? + XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : + XFS_QMOPT_RES_REGBLKS); + if (error) { + xfs_iunlock(ip, XFS_ILOCK_EXCL); + xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES); + return error; } - - /* - * Check and set flags if the current (right) segment exists. - * If it doesn't exist, we're converting the hole at end-of-file. - */ - if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { - state |= BMAP_RIGHT_VALID; - xfs_bmbt_get_all(ep, &right); - - if (isnullstartblock(right.br_startblock)) - state |= BMAP_RIGHT_DELAY; + if (XFS_IFORK_Q(ip)) + goto error1; + if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) { + /* + * For inodes coming from pre-6.2 filesystems. + */ + ASSERT(ip->i_d.di_aformat == 0); + ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; } + ASSERT(ip->i_d.di_anextents == 0); - /* - * Set contiguity flags on the left and right neighbors. - * Don't let extents get too large, even if the pieces are contiguous. - */ - if ((state & BMAP_LEFT_VALID) && (state & BMAP_LEFT_DELAY) && - left.br_startoff + left.br_blockcount == new->br_startoff && - left.br_blockcount + new->br_blockcount <= MAXEXTLEN) - state |= BMAP_LEFT_CONTIG; - - if ((state & BMAP_RIGHT_VALID) && (state & BMAP_RIGHT_DELAY) && - new->br_startoff + new->br_blockcount == right.br_startoff && - new->br_blockcount + right.br_blockcount <= MAXEXTLEN && - (!(state & BMAP_LEFT_CONTIG) || - (left.br_blockcount + new->br_blockcount + - right.br_blockcount <= MAXEXTLEN))) - state |= BMAP_RIGHT_CONTIG; + xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - /* - * Switch out based on the contiguity flags. - */ - switch (state & (BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG)) { - case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: - /* - * New allocation is contiguous with delayed allocations - * on the left and on the right. - * Merge all three into a single extent record. - */ - temp = left.br_blockcount + new->br_blockcount + - right.br_blockcount; - - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); - oldlen = startblockval(left.br_startblock) + - startblockval(new->br_startblock) + - startblockval(right.br_startblock); - newlen = xfs_bmap_worst_indlen(ip, temp); - xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), - nullstartblock((int)newlen)); - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); - - xfs_iext_remove(ip, idx, 1, state); - ip->i_df.if_lastex = idx - 1; + switch (ip->i_d.di_format) { + case XFS_DINODE_FMT_DEV: + ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; break; - - case BMAP_LEFT_CONTIG: - /* - * New allocation is contiguous with a delayed allocation - * on the left. - * Merge the new allocation with the left neighbor. - */ - temp = left.br_blockcount + new->br_blockcount; - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); - oldlen = startblockval(left.br_startblock) + - startblockval(new->br_startblock); - newlen = xfs_bmap_worst_indlen(ip, temp); - xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), - nullstartblock((int)newlen)); - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); - - ip->i_df.if_lastex = idx - 1; + case XFS_DINODE_FMT_UUID: + ip->i_d.di_forkoff = roundup(sizeof(uuid_t), 8) >> 3; break; - - case BMAP_RIGHT_CONTIG: - /* - * New allocation is contiguous with a delayed allocation - * on the right. - * Merge the new allocation with the right neighbor. - */ - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); - temp = new->br_blockcount + right.br_blockcount; - oldlen = startblockval(new->br_startblock) + - startblockval(right.br_startblock); - newlen = xfs_bmap_worst_indlen(ip, temp); - xfs_bmbt_set_allf(ep, new->br_startoff, - nullstartblock((int)newlen), temp, right.br_state); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); - - ip->i_df.if_lastex = idx; + case XFS_DINODE_FMT_LOCAL: + case XFS_DINODE_FMT_EXTENTS: + case XFS_DINODE_FMT_BTREE: + ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size); + if (!ip->i_d.di_forkoff) + ip->i_d.di_forkoff = xfs_default_attroffset(ip) >> 3; + else if (mp->m_flags & XFS_MOUNT_ATTR2) + version = 2; break; + default: + ASSERT(0); + error = XFS_ERROR(EINVAL); + goto error1; + } - case 0: - /* - * New allocation is not contiguous with another - * delayed allocation. - * Insert a new entry. - */ - oldlen = newlen = 0; - xfs_iext_insert(ip, idx, 1, new, state); - ip->i_df.if_lastex = idx; + ASSERT(ip->i_afp == NULL); + ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP); + ip->i_afp->if_flags = XFS_IFEXTENTS; + logflags = 0; + xfs_bmap_init(&flist, &firstblock); + switch (ip->i_d.di_format) { + case XFS_DINODE_FMT_LOCAL: + error = xfs_bmap_add_attrfork_local(tp, ip, &firstblock, &flist, + &logflags); + break; + case XFS_DINODE_FMT_EXTENTS: + error = xfs_bmap_add_attrfork_extents(tp, ip, &firstblock, + &flist, &logflags); + break; + case XFS_DINODE_FMT_BTREE: + error = xfs_bmap_add_attrfork_btree(tp, ip, &firstblock, &flist, + &logflags); + break; + default: + error = 0; break; } - if (oldlen != newlen) { - ASSERT(oldlen > newlen); - xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, - (int64_t)(oldlen - newlen), rsvd); - /* - * Nothing to do for disk quota accounting here. - */ + if (logflags) + xfs_trans_log_inode(tp, ip, logflags); + if (error) + goto error2; + if (!xfs_sb_version_hasattr(&mp->m_sb) || + (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) { + __int64_t sbfields = 0; + + spin_lock(&mp->m_sb_lock); + if (!xfs_sb_version_hasattr(&mp->m_sb)) { + xfs_sb_version_addattr(&mp->m_sb); + sbfields |= XFS_SB_VERSIONNUM; + } + if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) { + xfs_sb_version_addattr2(&mp->m_sb); + sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); + } + if (sbfields) { + spin_unlock(&mp->m_sb_lock); + xfs_mod_sb(tp, sbfields); + } else + spin_unlock(&mp->m_sb_lock); } - *logflagsp = 0; - return 0; + + error = xfs_bmap_finish(&tp, &flist, &committed); + if (error) + goto error2; + return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); +error2: + xfs_bmap_cancel(&flist); +error1: + xfs_iunlock(ip, XFS_ILOCK_EXCL); +error0: + xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); + return error; } /* - * Called by xfs_bmap_add_extent to handle cases converting a hole - * to a real allocation. + * Internal and external extent tree search functions. */ -STATIC int /* error */ -xfs_bmap_add_extent_hole_real( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* extent number to update/insert */ - xfs_btree_cur_t *cur, /* if null, not a btree */ - xfs_bmbt_irec_t *new, /* new data to add to file extents */ - int *logflagsp, /* inode logging flags */ + +/* + * Read in the extents to if_extents. + * All inode fields are set up by caller, we just traverse the btree + * and copy the records in. If the file system cannot contain unwritten + * extents, the records are checked for no "state" flags. + */ +int /* error */ +xfs_bmap_read_extents( + xfs_trans_t *tp, /* transaction pointer */ + xfs_inode_t *ip, /* incore inode */ int whichfork) /* data or attr fork */ { - xfs_bmbt_rec_host_t *ep; /* pointer to extent entry ins. point */ + struct xfs_btree_block *block; /* current btree block */ + xfs_fsblock_t bno; /* block # of "block" */ + xfs_buf_t *bp; /* buffer for "block" */ int error; /* error return value */ - int i; /* temp state */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_bmbt_irec_t left; /* left neighbor extent entry */ - xfs_bmbt_irec_t right; /* right neighbor extent entry */ - int rval=0; /* return value (logging flags) */ - int state; /* state bits, accessed thru macros */ + xfs_exntfmt_t exntf; /* XFS_EXTFMT_NOSTATE, if checking */ + xfs_extnum_t i, j; /* index into the extents list */ + xfs_ifork_t *ifp; /* fork structure */ + int level; /* btree level, for checking */ + xfs_mount_t *mp; /* file system mount structure */ + __be64 *pp; /* pointer to block address */ + /* REFERENCED */ + xfs_extnum_t room; /* number of entries there's room for */ + bno = NULLFSBLOCK; + mp = ip->i_mount; ifp = XFS_IFORK_PTR(ip, whichfork); - ASSERT(idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)); - ep = xfs_iext_get_ext(ifp, idx); - state = 0; - - if (whichfork == XFS_ATTR_FORK) - state |= BMAP_ATTRFORK; - + exntf = (whichfork != XFS_DATA_FORK) ? XFS_EXTFMT_NOSTATE : + XFS_EXTFMT_INODE(ip); + block = ifp->if_broot; /* - * Check and set flags if this segment has a left neighbor. + * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. */ - if (idx > 0) { - state |= BMAP_LEFT_VALID; - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left); - if (isnullstartblock(left.br_startblock)) - state |= BMAP_LEFT_DELAY; - } - + level = be16_to_cpu(block->bb_level); + ASSERT(level > 0); + pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); + bno = be64_to_cpu(*pp); + ASSERT(bno != NULLDFSBNO); + ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); + ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); /* - * Check and set flags if this segment has a current value. - * Not true if we're inserting into the "hole" at eof. + * Go down the tree until leaf level is reached, following the first + * pointer (leftmost) at each level. */ - if (idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { - state |= BMAP_RIGHT_VALID; - xfs_bmbt_get_all(ep, &right); - if (isnullstartblock(right.br_startblock)) - state |= BMAP_RIGHT_DELAY; + while (level-- > 0) { + error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, + XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops); + if (error) + return error; + block = XFS_BUF_TO_BLOCK(bp); + XFS_WANT_CORRUPTED_GOTO( + xfs_bmap_sanity_check(mp, bp, level), + error0); + if (level == 0) + break; + pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); + bno = be64_to_cpu(*pp); + XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0); + xfs_trans_brelse(tp, bp); } - /* - * We're inserting a real allocation between "left" and "right". - * Set the contiguity flags. Don't let extents get too large. + * Here with bp and block set to the leftmost leaf node in the tree. */ - if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) && - left.br_startoff + left.br_blockcount == new->br_startoff && - left.br_startblock + left.br_blockcount == new->br_startblock && - left.br_state == new->br_state && - left.br_blockcount + new->br_blockcount <= MAXEXTLEN) - state |= BMAP_LEFT_CONTIG; - - if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) && - new->br_startoff + new->br_blockcount == right.br_startoff && - new->br_startblock + new->br_blockcount == right.br_startblock && - new->br_state == right.br_state && - new->br_blockcount + right.br_blockcount <= MAXEXTLEN && - (!(state & BMAP_LEFT_CONTIG) || - left.br_blockcount + new->br_blockcount + - right.br_blockcount <= MAXEXTLEN)) - state |= BMAP_RIGHT_CONTIG; - - error = 0; + room = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + i = 0; /* - * Select which case we're in here, and implement it. + * Loop over all leaf nodes. Copy information to the extent records. */ - switch (state & (BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG)) { - case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: + for (;;) { + xfs_bmbt_rec_t *frp; + xfs_fsblock_t nextbno; + xfs_extnum_t num_recs; + xfs_extnum_t start; + + num_recs = xfs_btree_get_numrecs(block); + if (unlikely(i + num_recs > room)) { + ASSERT(i + num_recs <= room); + xfs_warn(ip->i_mount, + "corrupt dinode %Lu, (btree extents).", + (unsigned long long) ip->i_ino); + XFS_CORRUPTION_ERROR("xfs_bmap_read_extents(1)", + XFS_ERRLEVEL_LOW, ip->i_mount, block); + goto error0; + } + XFS_WANT_CORRUPTED_GOTO( + xfs_bmap_sanity_check(mp, bp, 0), + error0); /* - * New allocation is contiguous with real allocations on the - * left and on the right. - * Merge all three into a single extent record. + * Read-ahead the next leaf block, if any. */ - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), - left.br_blockcount + new->br_blockcount + - right.br_blockcount); - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); - - xfs_iext_remove(ip, idx, 1, state); - ifp->if_lastex = idx - 1; - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) - 1); - if (cur == NULL) { - rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); - } else { - rval = XFS_ILOG_CORE; - if ((error = xfs_bmbt_lookup_eq(cur, - right.br_startoff, - right.br_startblock, - right.br_blockcount, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_btree_delete(cur, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_btree_decrement(cur, 0, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_bmbt_update(cur, left.br_startoff, - left.br_startblock, - left.br_blockcount + - new->br_blockcount + - right.br_blockcount, - left.br_state))) - goto done; - } - break; - - case BMAP_LEFT_CONTIG: + nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib); + if (nextbno != NULLFSBLOCK) + xfs_btree_reada_bufl(mp, nextbno, 1, + &xfs_bmbt_buf_ops); /* - * New allocation is contiguous with a real allocation - * on the left. - * Merge the new allocation with the left neighbor. + * Copy records into the extent records. */ - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), - left.br_blockcount + new->br_blockcount); - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); - - ifp->if_lastex = idx - 1; - if (cur == NULL) { - rval = xfs_ilog_fext(whichfork); - } else { - rval = 0; - if ((error = xfs_bmbt_lookup_eq(cur, - left.br_startoff, - left.br_startblock, - left.br_blockcount, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_bmbt_update(cur, left.br_startoff, - left.br_startblock, - left.br_blockcount + - new->br_blockcount, - left.br_state))) - goto done; + frp = XFS_BMBT_REC_ADDR(mp, block, 1); + start = i; + for (j = 0; j < num_recs; j++, i++, frp++) { + xfs_bmbt_rec_host_t *trp = xfs_iext_get_ext(ifp, i); + trp->l0 = be64_to_cpu(frp->l0); + trp->l1 = be64_to_cpu(frp->l1); } - break; - - case BMAP_RIGHT_CONTIG: + if (exntf == XFS_EXTFMT_NOSTATE) { + /* + * Check all attribute bmap btree records and + * any "older" data bmap btree records for a + * set bit in the "extent flag" position. + */ + if (unlikely(xfs_check_nostate_extents(ifp, + start, num_recs))) { + XFS_ERROR_REPORT("xfs_bmap_read_extents(2)", + XFS_ERRLEVEL_LOW, + ip->i_mount); + goto error0; + } + } + xfs_trans_brelse(tp, bp); + bno = nextbno; /* - * New allocation is contiguous with a real allocation - * on the right. - * Merge the new allocation with the right neighbor. + * If we've reached the end, stop. */ - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); - xfs_bmbt_set_allf(ep, new->br_startoff, new->br_startblock, - new->br_blockcount + right.br_blockcount, - right.br_state); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); + if (bno == NULLFSBLOCK) + break; + error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, + XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops); + if (error) + return error; + block = XFS_BUF_TO_BLOCK(bp); + } + ASSERT(i == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))); + ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork)); + XFS_BMAP_TRACE_EXLIST(ip, i, whichfork); + return 0; +error0: + xfs_trans_brelse(tp, bp); + return XFS_ERROR(EFSCORRUPTED); +} - ifp->if_lastex = idx; - if (cur == NULL) { - rval = xfs_ilog_fext(whichfork); - } else { - rval = 0; - if ((error = xfs_bmbt_lookup_eq(cur, - right.br_startoff, - right.br_startblock, - right.br_blockcount, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - if ((error = xfs_bmbt_update(cur, new->br_startoff, - new->br_startblock, - new->br_blockcount + - right.br_blockcount, - right.br_state))) - goto done; - } - break; - case 0: - /* - * New allocation is not contiguous with another - * real allocation. - * Insert a new entry. - */ - xfs_iext_insert(ip, idx, 1, new, state); - ifp->if_lastex = idx; - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) + 1); - if (cur == NULL) { - rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); - } else { - rval = XFS_ILOG_CORE; - if ((error = xfs_bmbt_lookup_eq(cur, - new->br_startoff, - new->br_startblock, - new->br_blockcount, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 0, done); - cur->bc_rec.b.br_state = new->br_state; - if ((error = xfs_btree_insert(cur, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); +/* + * Search the extent records for the entry containing block bno. + * If bno lies in a hole, point to the next entry. If bno lies + * past eof, *eofp will be set, and *prevp will contain the last + * entry (null if none). Else, *lastxp will be set to the index + * of the found entry; *gotp will contain the entry. + */ +STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */ +xfs_bmap_search_multi_extents( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_fileoff_t bno, /* block number searched for */ + int *eofp, /* out: end of file found */ + xfs_extnum_t *lastxp, /* out: last extent index */ + xfs_bmbt_irec_t *gotp, /* out: extent entry found */ + xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ +{ + xfs_bmbt_rec_host_t *ep; /* extent record pointer */ + xfs_extnum_t lastx; /* last extent index */ + + /* + * Initialize the extent entry structure to catch access to + * uninitialized br_startblock field. + */ + gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL; + gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL; + gotp->br_state = XFS_EXT_INVALID; +#if XFS_BIG_BLKNOS + gotp->br_startblock = 0xffffa5a5a5a5a5a5LL; +#else + gotp->br_startblock = 0xffffa5a5; +#endif + prevp->br_startoff = NULLFILEOFF; + + ep = xfs_iext_bno_to_ext(ifp, bno, &lastx); + if (lastx > 0) { + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp); + } + if (lastx < (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) { + xfs_bmbt_get_all(ep, gotp); + *eofp = 0; + } else { + if (lastx > 0) { + *gotp = *prevp; } - break; + *eofp = 1; + ep = NULL; } -done: - *logflagsp = rval; - return error; + *lastxp = lastx; + return ep; } /* - * Adjust the size of the new extent based on di_extsize and rt extsize. + * Search the extents list for the inode, for the extent containing bno. + * If bno lies in a hole, point to the next entry. If bno lies past eof, + * *eofp will be set, and *prevp will contain the last entry (null if none). + * Else, *lastxp will be set to the index of the found + * entry; *gotp will contain the entry. */ -STATIC int -xfs_bmap_extsize_align( - xfs_mount_t *mp, - xfs_bmbt_irec_t *gotp, /* next extent pointer */ - xfs_bmbt_irec_t *prevp, /* previous extent pointer */ - xfs_extlen_t extsz, /* align to this extent size */ - int rt, /* is this a realtime inode? */ - int eof, /* is extent at end-of-file? */ - int delay, /* creating delalloc extent? */ - int convert, /* overwriting unwritten extent? */ - xfs_fileoff_t *offp, /* in/out: aligned offset */ - xfs_extlen_t *lenp) /* in/out: aligned length */ +xfs_bmbt_rec_host_t * /* pointer to found extent entry */ +xfs_bmap_search_extents( + xfs_inode_t *ip, /* incore inode pointer */ + xfs_fileoff_t bno, /* block number searched for */ + int fork, /* data or attr fork */ + int *eofp, /* out: end of file found */ + xfs_extnum_t *lastxp, /* out: last extent index */ + xfs_bmbt_irec_t *gotp, /* out: extent entry found */ + xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ { - xfs_fileoff_t orig_off; /* original offset */ - xfs_extlen_t orig_alen; /* original length */ - xfs_fileoff_t orig_end; /* original off+len */ - xfs_fileoff_t nexto; /* next file offset */ - xfs_fileoff_t prevo; /* previous file offset */ - xfs_fileoff_t align_off; /* temp for offset */ - xfs_extlen_t align_alen; /* temp for length */ - xfs_extlen_t temp; /* temp for calculations */ + xfs_ifork_t *ifp; /* inode fork pointer */ + xfs_bmbt_rec_host_t *ep; /* extent record pointer */ - if (convert) - return 0; + XFS_STATS_INC(xs_look_exlist); + ifp = XFS_IFORK_PTR(ip, fork); - orig_off = align_off = *offp; - orig_alen = align_alen = *lenp; - orig_end = orig_off + orig_alen; + ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp); - /* - * If this request overlaps an existing extent, then don't - * attempt to perform any additional alignment. - */ - if (!delay && !eof && - (orig_off >= gotp->br_startoff) && - (orig_end <= gotp->br_startoff + gotp->br_blockcount)) { - return 0; + if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) && + !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) { + xfs_alert_tag(ip->i_mount, XFS_PTAG_FSBLOCK_ZERO, + "Access to block zero in inode %llu " + "start_block: %llx start_off: %llx " + "blkcnt: %llx extent-state: %x lastx: %x", + (unsigned long long)ip->i_ino, + (unsigned long long)gotp->br_startblock, + (unsigned long long)gotp->br_startoff, + (unsigned long long)gotp->br_blockcount, + gotp->br_state, *lastxp); + *lastxp = NULLEXTNUM; + *eofp = 1; + return NULL; } + return ep; +} - /* - * If the file offset is unaligned vs. the extent size - * we need to align it. This will be possible unless - * the file was previously written with a kernel that didn't - * perform this alignment, or if a truncate shot us in the - * foot. - */ - temp = do_mod(orig_off, extsz); - if (temp) { - align_alen += temp; - align_off -= temp; - } - /* - * Same adjustment for the end of the requested area. - */ - if ((temp = (align_alen % extsz))) { - align_alen += extsz - temp; - } - /* - * If the previous block overlaps with this proposed allocation - * then move the start forward without adjusting the length. - */ - if (prevp->br_startoff != NULLFILEOFF) { - if (prevp->br_startblock == HOLESTARTBLOCK) - prevo = prevp->br_startoff; - else - prevo = prevp->br_startoff + prevp->br_blockcount; - } else - prevo = 0; - if (align_off != orig_off && align_off < prevo) - align_off = prevo; - /* - * If the next block overlaps with this proposed allocation - * then move the start back without adjusting the length, - * but not before offset 0. - * This may of course make the start overlap previous block, - * and if we hit the offset 0 limit then the next block - * can still overlap too. - */ - if (!eof && gotp->br_startoff != NULLFILEOFF) { - if ((delay && gotp->br_startblock == HOLESTARTBLOCK) || - (!delay && gotp->br_startblock == DELAYSTARTBLOCK)) - nexto = gotp->br_startoff + gotp->br_blockcount; - else - nexto = gotp->br_startoff; - } else - nexto = NULLFILEOFF; - if (!eof && - align_off + align_alen != orig_end && - align_off + align_alen > nexto) - align_off = nexto > align_alen ? nexto - align_alen : 0; - /* - * If we're now overlapping the next or previous extent that - * means we can't fit an extsz piece in this hole. Just move - * the start forward to the first valid spot and set - * the length so we hit the end. - */ - if (align_off != orig_off && align_off < prevo) - align_off = prevo; - if (align_off + align_alen != orig_end && - align_off + align_alen > nexto && - nexto != NULLFILEOFF) { - ASSERT(nexto > prevo); - align_alen = nexto - align_off; - } +/* + * Returns the file-relative block number of the first unused block(s) + * in the file with at least "len" logically contiguous blocks free. + * This is the lowest-address hole if the file has holes, else the first block + * past the end of file. + * Return 0 if the file is currently local (in-inode). + */ +int /* error */ +xfs_bmap_first_unused( + xfs_trans_t *tp, /* transaction pointer */ + xfs_inode_t *ip, /* incore inode */ + xfs_extlen_t len, /* size of hole to find */ + xfs_fileoff_t *first_unused, /* unused block */ + int whichfork) /* data or attr fork */ +{ + int error; /* error return value */ + int idx; /* extent record index */ + xfs_ifork_t *ifp; /* inode fork pointer */ + xfs_fileoff_t lastaddr; /* last block number seen */ + xfs_fileoff_t lowest; /* lowest useful block */ + xfs_fileoff_t max; /* starting useful block */ + xfs_fileoff_t off; /* offset for this block */ + xfs_extnum_t nextents; /* number of extent entries */ - /* - * If realtime, and the result isn't a multiple of the realtime - * extent size we need to remove blocks until it is. - */ - if (rt && (temp = (align_alen % mp->m_sb.sb_rextsize))) { - /* - * We're not covering the original request, or - * we won't be able to once we fix the length. - */ - if (orig_off < align_off || - orig_end > align_off + align_alen || - align_alen - temp < orig_alen) - return XFS_ERROR(EINVAL); - /* - * Try to fix it by moving the start up. - */ - if (align_off + temp <= orig_off) { - align_alen -= temp; - align_off += temp; - } - /* - * Try to fix it by moving the end in. - */ - else if (align_off + align_alen - temp >= orig_end) - align_alen -= temp; + ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE || + XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS || + XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); + if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { + *first_unused = 0; + return 0; + } + ifp = XFS_IFORK_PTR(ip, whichfork); + if (!(ifp->if_flags & XFS_IFEXTENTS) && + (error = xfs_iread_extents(tp, ip, whichfork))) + return error; + lowest = *first_unused; + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) { + xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx); + off = xfs_bmbt_get_startoff(ep); /* - * Set the start to the minimum then trim the length. + * See if the hole before this extent will work. */ - else { - align_alen -= orig_off - align_off; - align_off = orig_off; - align_alen -= align_alen % mp->m_sb.sb_rextsize; + if (off >= lowest + len && off - max >= len) { + *first_unused = max; + return 0; } - /* - * Result doesn't cover the request, fail it. - */ - if (orig_off < align_off || orig_end > align_off + align_alen) - return XFS_ERROR(EINVAL); - } else { - ASSERT(orig_off >= align_off); - ASSERT(orig_end <= align_off + align_alen); + lastaddr = off + xfs_bmbt_get_blockcount(ep); + max = XFS_FILEOFF_MAX(lastaddr, lowest); } + *first_unused = max; + return 0; +} -#ifdef DEBUG - if (!eof && gotp->br_startoff != NULLFILEOFF) - ASSERT(align_off + align_alen <= gotp->br_startoff); - if (prevp->br_startoff != NULLFILEOFF) - ASSERT(align_off >= prevp->br_startoff + prevp->br_blockcount); -#endif +/* + * Returns the file-relative block number of the last block - 1 before + * last_block (input value) in the file. + * This is not based on i_size, it is based on the extent records. + * Returns 0 for local files, as they do not have extent records. + */ +int /* error */ +xfs_bmap_last_before( + xfs_trans_t *tp, /* transaction pointer */ + xfs_inode_t *ip, /* incore inode */ + xfs_fileoff_t *last_block, /* last block */ + int whichfork) /* data or attr fork */ +{ + xfs_fileoff_t bno; /* input file offset */ + int eof; /* hit end of file */ + xfs_bmbt_rec_host_t *ep; /* pointer to last extent */ + int error; /* error return value */ + xfs_bmbt_irec_t got; /* current extent value */ + xfs_ifork_t *ifp; /* inode fork pointer */ + xfs_extnum_t lastx; /* last extent used */ + xfs_bmbt_irec_t prev; /* previous extent value */ - *lenp = align_alen; - *offp = align_off; + if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && + XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && + XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) + return XFS_ERROR(EIO); + if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { + *last_block = 0; + return 0; + } + ifp = XFS_IFORK_PTR(ip, whichfork); + if (!(ifp->if_flags & XFS_IFEXTENTS) && + (error = xfs_iread_extents(tp, ip, whichfork))) + return error; + bno = *last_block - 1; + ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, + &prev); + if (eof || xfs_bmbt_get_startoff(ep) > bno) { + if (prev.br_startoff == NULLFILEOFF) + *last_block = 0; + else + *last_block = prev.br_startoff + prev.br_blockcount; + } + /* + * Otherwise *last_block is already the right answer. + */ return 0; } -#define XFS_ALLOC_GAP_UNITS 4 - -STATIC void -xfs_bmap_adjacent( - xfs_bmalloca_t *ap) /* bmap alloc argument struct */ +int +xfs_bmap_last_extent( + struct xfs_trans *tp, + struct xfs_inode *ip, + int whichfork, + struct xfs_bmbt_irec *rec, + int *is_empty) { - xfs_fsblock_t adjust; /* adjustment to block numbers */ - xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ - xfs_mount_t *mp; /* mount point structure */ - int nullfb; /* true if ap->firstblock isn't set */ - int rt; /* true if inode is realtime */ + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); + int error; + int nextents; -#define ISVALID(x,y) \ - (rt ? \ - (x) < mp->m_sb.sb_rblocks : \ - XFS_FSB_TO_AGNO(mp, x) == XFS_FSB_TO_AGNO(mp, y) && \ - XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \ - XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks) + if (!(ifp->if_flags & XFS_IFEXTENTS)) { + error = xfs_iread_extents(tp, ip, whichfork); + if (error) + return error; + } - mp = ap->ip->i_mount; - nullfb = ap->firstblock == NULLFSBLOCK; - rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata; - fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock); - /* - * If allocating at eof, and there's a previous real block, - * try to use its last block as our starting point. - */ - if (ap->eof && ap->prevp->br_startoff != NULLFILEOFF && - !isnullstartblock(ap->prevp->br_startblock) && - ISVALID(ap->prevp->br_startblock + ap->prevp->br_blockcount, - ap->prevp->br_startblock)) { - ap->rval = ap->prevp->br_startblock + ap->prevp->br_blockcount; - /* - * Adjust for the gap between prevp and us. - */ - adjust = ap->off - - (ap->prevp->br_startoff + ap->prevp->br_blockcount); - if (adjust && - ISVALID(ap->rval + adjust, ap->prevp->br_startblock)) - ap->rval += adjust; + nextents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); + if (nextents == 0) { + *is_empty = 1; + return 0; } + + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, nextents - 1), rec); + *is_empty = 0; + return 0; +} + +/* + * Check the last inode extent to determine whether this allocation will result + * in blocks being allocated at the end of the file. When we allocate new data + * blocks at the end of the file which do not start at the previous data block, + * we will try to align the new blocks at stripe unit boundaries. + * + * Returns 0 in bma->aeof if the file (fork) is empty as any new write will be + * at, or past the EOF. + */ +STATIC int +xfs_bmap_isaeof( + struct xfs_bmalloca *bma, + int whichfork) +{ + struct xfs_bmbt_irec rec; + int is_empty; + int error; + + bma->aeof = 0; + error = xfs_bmap_last_extent(NULL, bma->ip, whichfork, &rec, + &is_empty); + if (error || is_empty) + return error; + /* - * If not at eof, then compare the two neighbor blocks. - * Figure out whether either one gives us a good starting point, - * and pick the better one. + * Check if we are allocation or past the last extent, or at least into + * the last delayed allocated extent. */ - else if (!ap->eof) { - xfs_fsblock_t gotbno; /* right side block number */ - xfs_fsblock_t gotdiff=0; /* right side difference */ - xfs_fsblock_t prevbno; /* left side block number */ - xfs_fsblock_t prevdiff=0; /* left side difference */ + bma->aeof = bma->offset >= rec.br_startoff + rec.br_blockcount || + (bma->offset >= rec.br_startoff && + isnullstartblock(rec.br_startblock)); + return 0; +} - /* - * If there's a previous (left) block, select a requested - * start block based on it. - */ - if (ap->prevp->br_startoff != NULLFILEOFF && - !isnullstartblock(ap->prevp->br_startblock) && - (prevbno = ap->prevp->br_startblock + - ap->prevp->br_blockcount) && - ISVALID(prevbno, ap->prevp->br_startblock)) { - /* - * Calculate gap to end of previous block. - */ - adjust = prevdiff = ap->off - - (ap->prevp->br_startoff + - ap->prevp->br_blockcount); - /* - * Figure the startblock based on the previous block's - * end and the gap size. - * Heuristic! - * If the gap is large relative to the piece we're - * allocating, or using it gives us an invalid block - * number, then just use the end of the previous block. - */ - if (prevdiff <= XFS_ALLOC_GAP_UNITS * ap->alen && - ISVALID(prevbno + prevdiff, - ap->prevp->br_startblock)) - prevbno += adjust; - else - prevdiff += adjust; - /* - * If the firstblock forbids it, can't use it, - * must use default. - */ - if (!rt && !nullfb && - XFS_FSB_TO_AGNO(mp, prevbno) != fb_agno) - prevbno = NULLFSBLOCK; - } - /* - * No previous block or can't follow it, just default. - */ - else - prevbno = NULLFSBLOCK; - /* - * If there's a following (right) block, select a requested - * start block based on it. - */ - if (!isnullstartblock(ap->gotp->br_startblock)) { - /* - * Calculate gap to start of next block. - */ - adjust = gotdiff = ap->gotp->br_startoff - ap->off; - /* - * Figure the startblock based on the next block's - * start and the gap size. - */ - gotbno = ap->gotp->br_startblock; - /* - * Heuristic! - * If the gap is large relative to the piece we're - * allocating, or using it gives us an invalid block - * number, then just use the start of the next block - * offset by our length. - */ - if (gotdiff <= XFS_ALLOC_GAP_UNITS * ap->alen && - ISVALID(gotbno - gotdiff, gotbno)) - gotbno -= adjust; - else if (ISVALID(gotbno - ap->alen, gotbno)) { - gotbno -= ap->alen; - gotdiff += adjust - ap->alen; - } else - gotdiff += adjust; - /* - * If the firstblock forbids it, can't use it, - * must use default. - */ - if (!rt && !nullfb && - XFS_FSB_TO_AGNO(mp, gotbno) != fb_agno) - gotbno = NULLFSBLOCK; - } - /* - * No next block, just default. - */ - else - gotbno = NULLFSBLOCK; - /* - * If both valid, pick the better one, else the only good - * one, else ap->rval is already set (to 0 or the inode block). - */ - if (prevbno != NULLFSBLOCK && gotbno != NULLFSBLOCK) - ap->rval = prevdiff <= gotdiff ? prevbno : gotbno; - else if (prevbno != NULLFSBLOCK) - ap->rval = prevbno; - else if (gotbno != NULLFSBLOCK) - ap->rval = gotbno; - } -#undef ISVALID -} - -STATIC int -xfs_bmap_btalloc_nullfb( - struct xfs_bmalloca *ap, - struct xfs_alloc_arg *args, - xfs_extlen_t *blen) +/* + * Returns the file-relative block number of the first block past eof in + * the file. This is not based on i_size, it is based on the extent records. + * Returns 0 for local files, as they do not have extent records. + */ +int +xfs_bmap_last_offset( + struct xfs_trans *tp, + struct xfs_inode *ip, + xfs_fileoff_t *last_block, + int whichfork) { - struct xfs_mount *mp = ap->ip->i_mount; - struct xfs_perag *pag; - xfs_agnumber_t ag, startag; - int notinit = 0; + struct xfs_bmbt_irec rec; + int is_empty; int error; - if (ap->userdata && xfs_inode_is_filestream(ap->ip)) - args->type = XFS_ALLOCTYPE_NEAR_BNO; - else - args->type = XFS_ALLOCTYPE_START_BNO; - args->total = ap->total; + *last_block = 0; - /* - * Search for an allocation group with a single extent large enough - * for the request. If one isn't found, then adjust the minimum - * allocation size to the largest space found. - */ - startag = ag = XFS_FSB_TO_AGNO(mp, args->fsbno); - if (startag == NULLAGNUMBER) - startag = ag = 0; + if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) + return 0; - pag = xfs_perag_get(mp, ag); - while (*blen < ap->alen) { - if (!pag->pagf_init) { - error = xfs_alloc_pagf_init(mp, args->tp, ag, - XFS_ALLOC_FLAG_TRYLOCK); - if (error) { - xfs_perag_put(pag); - return error; - } - } + if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && + XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) + return XFS_ERROR(EIO); - /* - * See xfs_alloc_fix_freelist... - */ - if (pag->pagf_init) { - xfs_extlen_t longest; - longest = xfs_alloc_longest_free_extent(mp, pag); - if (*blen < longest) - *blen = longest; - } else - notinit = 1; + error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty); + if (error || is_empty) + return error; - if (xfs_inode_is_filestream(ap->ip)) { - if (*blen >= ap->alen) - break; + *last_block = rec.br_startoff + rec.br_blockcount; + return 0; +} - if (ap->userdata) { - /* - * If startag is an invalid AG, we've - * come here once before and - * xfs_filestream_new_ag picked the - * best currently available. - * - * Don't continue looping, since we - * could loop forever. - */ - if (startag == NULLAGNUMBER) - break; +/* + * Returns whether the selected fork of the inode has exactly one + * block or not. For the data fork we check this matches di_size, + * implying the file's range is 0..bsize-1. + */ +int /* 1=>1 block, 0=>otherwise */ +xfs_bmap_one_block( + xfs_inode_t *ip, /* incore inode */ + int whichfork) /* data or attr fork */ +{ + xfs_bmbt_rec_host_t *ep; /* ptr to fork's extent */ + xfs_ifork_t *ifp; /* inode fork pointer */ + int rval; /* return value */ + xfs_bmbt_irec_t s; /* internal version of extent */ - error = xfs_filestream_new_ag(ap, &ag); - xfs_perag_put(pag); - if (error) - return error; +#ifndef DEBUG + if (whichfork == XFS_DATA_FORK) + return XFS_ISIZE(ip) == ip->i_mount->m_sb.sb_blocksize; +#endif /* !DEBUG */ + if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1) + return 0; + if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) + return 0; + ifp = XFS_IFORK_PTR(ip, whichfork); + ASSERT(ifp->if_flags & XFS_IFEXTENTS); + ep = xfs_iext_get_ext(ifp, 0); + xfs_bmbt_get_all(ep, &s); + rval = s.br_startoff == 0 && s.br_blockcount == 1; + if (rval && whichfork == XFS_DATA_FORK) + ASSERT(XFS_ISIZE(ip) == ip->i_mount->m_sb.sb_blocksize); + return rval; +} - /* loop again to set 'blen'*/ - startag = NULLAGNUMBER; - pag = xfs_perag_get(mp, ag); - continue; - } - } - if (++ag == mp->m_sb.sb_agcount) - ag = 0; - if (ag == startag) - break; - xfs_perag_put(pag); - pag = xfs_perag_get(mp, ag); - } - xfs_perag_put(pag); +/* + * Extent tree manipulation functions used during allocation. + */ + +/* + * Convert a delayed allocation to a real allocation. + */ +STATIC int /* error */ +xfs_bmap_add_extent_delay_real( + struct xfs_bmalloca *bma) +{ + struct xfs_bmbt_irec *new = &bma->got; + int diff; /* temp value */ + xfs_bmbt_rec_host_t *ep; /* extent entry for idx */ + int error; /* error return value */ + int i; /* temp state */ + xfs_ifork_t *ifp; /* inode fork pointer */ + xfs_fileoff_t new_endoff; /* end offset of new entry */ + xfs_bmbt_irec_t r[3]; /* neighbor extent entries */ + /* left is 0, right is 1, prev is 2 */ + int rval=0; /* return value (logging flags) */ + int state = 0;/* state bits, accessed thru macros */ + xfs_filblks_t da_new; /* new count del alloc blocks used */ + xfs_filblks_t da_old; /* old count del alloc blocks used */ + xfs_filblks_t temp=0; /* value for da_new calculations */ + xfs_filblks_t temp2=0;/* value for da_new calculations */ + int tmp_rval; /* partial logging flags */ + + ifp = XFS_IFORK_PTR(bma->ip, XFS_DATA_FORK); + + ASSERT(bma->idx >= 0); + ASSERT(bma->idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec)); + ASSERT(!isnullstartblock(new->br_startblock)); + ASSERT(!bma->cur || + (bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL)); + + XFS_STATS_INC(xs_add_exlist); + +#define LEFT r[0] +#define RIGHT r[1] +#define PREV r[2] /* - * Since the above loop did a BUF_TRYLOCK, it is - * possible that there is space for this request. + * Set up a bunch of variables to make the tests simpler. */ - if (notinit || *blen < ap->minlen) - args->minlen = ap->minlen; + ep = xfs_iext_get_ext(ifp, bma->idx); + xfs_bmbt_get_all(ep, &PREV); + new_endoff = new->br_startoff + new->br_blockcount; + ASSERT(PREV.br_startoff <= new->br_startoff); + ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff); + + da_old = startblockval(PREV.br_startblock); + da_new = 0; + /* - * If the best seen length is less than the request - * length, use the best as the minimum. + * Set flags determining what part of the previous delayed allocation + * extent is being replaced by a real allocation. */ - else if (*blen < ap->alen) - args->minlen = *blen; + if (PREV.br_startoff == new->br_startoff) + state |= BMAP_LEFT_FILLING; + if (PREV.br_startoff + PREV.br_blockcount == new_endoff) + state |= BMAP_RIGHT_FILLING; + /* - * Otherwise we've seen an extent as big as alen, - * use that as the minimum. + * Check and set flags if this segment has a left neighbor. + * Don't set contiguous if the combined extent would be too large. */ - else - args->minlen = ap->alen; + if (bma->idx > 0) { + state |= BMAP_LEFT_VALID; + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx - 1), &LEFT); + + if (isnullstartblock(LEFT.br_startblock)) + state |= BMAP_LEFT_DELAY; + } + + if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) && + LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff && + LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock && + LEFT.br_state == new->br_state && + LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN) + state |= BMAP_LEFT_CONTIG; /* - * set the failure fallback case to look in the selected - * AG as the stream may have moved. + * Check and set flags if this segment has a right neighbor. + * Don't set contiguous if the combined extent would be too large. + * Also check for all-three-contiguous being too large. */ - if (xfs_inode_is_filestream(ap->ip)) - ap->rval = args->fsbno = XFS_AGB_TO_FSB(mp, ag, 0); + if (bma->idx < bma->ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { + state |= BMAP_RIGHT_VALID; + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx + 1), &RIGHT); - return 0; -} + if (isnullstartblock(RIGHT.br_startblock)) + state |= BMAP_RIGHT_DELAY; + } -STATIC int -xfs_bmap_btalloc( - xfs_bmalloca_t *ap) /* bmap alloc argument struct */ -{ - xfs_mount_t *mp; /* mount point structure */ - xfs_alloctype_t atype = 0; /* type for allocation routines */ - xfs_extlen_t align; /* minimum allocation alignment */ - xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ - xfs_agnumber_t ag; - xfs_alloc_arg_t args; - xfs_extlen_t blen; - xfs_extlen_t nextminlen = 0; - int nullfb; /* true if ap->firstblock isn't set */ - int isaligned; - int tryagain; - int error; - - mp = ap->ip->i_mount; - align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0; - if (unlikely(align)) { - error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, - align, 0, ap->eof, 0, ap->conv, - &ap->off, &ap->alen); - ASSERT(!error); - ASSERT(ap->alen); - } - nullfb = ap->firstblock == NULLFSBLOCK; - fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock); - if (nullfb) { - if (ap->userdata && xfs_inode_is_filestream(ap->ip)) { - ag = xfs_filestream_lookup_ag(ap->ip); - ag = (ag != NULLAGNUMBER) ? ag : 0; - ap->rval = XFS_AGB_TO_FSB(mp, ag, 0); - } else { - ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino); - } - } else - ap->rval = ap->firstblock; - - xfs_bmap_adjacent(ap); + if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) && + new_endoff == RIGHT.br_startoff && + new->br_startblock + new->br_blockcount == RIGHT.br_startblock && + new->br_state == RIGHT.br_state && + new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN && + ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | + BMAP_RIGHT_FILLING)) != + (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | + BMAP_RIGHT_FILLING) || + LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount + <= MAXEXTLEN)) + state |= BMAP_RIGHT_CONTIG; + error = 0; /* - * If allowed, use ap->rval; otherwise must use firstblock since - * it's in the right allocation group. - */ - if (nullfb || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno) - ; - else - ap->rval = ap->firstblock; - /* - * Normal allocation, done through xfs_alloc_vextent. - */ - tryagain = isaligned = 0; - args.tp = ap->tp; - args.mp = mp; - args.fsbno = ap->rval; - args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks); - args.firstblock = ap->firstblock; - blen = 0; - if (nullfb) { - error = xfs_bmap_btalloc_nullfb(ap, &args, &blen); - if (error) - return error; - } else if (ap->low) { - if (xfs_inode_is_filestream(ap->ip)) - args.type = XFS_ALLOCTYPE_FIRST_AG; - else - args.type = XFS_ALLOCTYPE_START_BNO; - args.total = args.minlen = ap->minlen; - } else { - args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.total = ap->total; - args.minlen = ap->minlen; - } - /* apply extent size hints if obtained earlier */ - if (unlikely(align)) { - args.prod = align; - if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod))) - args.mod = (xfs_extlen_t)(args.prod - args.mod); - } else if (mp->m_sb.sb_blocksize >= PAGE_CACHE_SIZE) { - args.prod = 1; - args.mod = 0; - } else { - args.prod = PAGE_CACHE_SIZE >> mp->m_sb.sb_blocklog; - if ((args.mod = (xfs_extlen_t)(do_mod(ap->off, args.prod)))) - args.mod = (xfs_extlen_t)(args.prod - args.mod); - } - /* - * If we are not low on available data blocks, and the - * underlying logical volume manager is a stripe, and - * the file offset is zero then try to allocate data - * blocks on stripe unit boundary. - * NOTE: ap->aeof is only set if the allocation length - * is >= the stripe unit and the allocation offset is - * at the end of file. + * Switch out based on the FILLING and CONTIG state bits. */ - if (!ap->low && ap->aeof) { - if (!ap->off) { - args.alignment = mp->m_dalign; - atype = args.type; - isaligned = 1; - /* - * Adjust for alignment - */ - if (blen > args.alignment && blen <= ap->alen) - args.minlen = blen - args.alignment; - args.minalignslop = 0; - } else { - /* - * First try an exact bno allocation. - * If it fails then do a near or start bno - * allocation with alignment turned on. - */ - atype = args.type; - tryagain = 1; - args.type = XFS_ALLOCTYPE_THIS_BNO; - args.alignment = 1; - /* - * Compute the minlen+alignment for the - * next case. Set slop so that the value - * of minlen+alignment+slop doesn't go up - * between the calls. - */ - if (blen > mp->m_dalign && blen <= ap->alen) - nextminlen = blen - mp->m_dalign; - else - nextminlen = args.minlen; - if (nextminlen + mp->m_dalign > args.minlen + 1) - args.minalignslop = - nextminlen + mp->m_dalign - - args.minlen - 1; - else - args.minalignslop = 0; - } - } else { - args.alignment = 1; - args.minalignslop = 0; - } - args.minleft = ap->minleft; - args.wasdel = ap->wasdel; - args.isfl = 0; - args.userdata = ap->userdata; - if ((error = xfs_alloc_vextent(&args))) - return error; - if (tryagain && args.fsbno == NULLFSBLOCK) { + switch (state & (BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | + BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG)) { + case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | + BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* - * Exact allocation failed. Now try with alignment - * turned on. + * Filling in all of a previously delayed allocation extent. + * The left and right neighbors are both contiguous with new. */ - args.type = atype; - args.fsbno = ap->rval; - args.alignment = mp->m_dalign; - args.minlen = nextminlen; - args.minalignslop = 0; - isaligned = 1; - if ((error = xfs_alloc_vextent(&args))) - return error; - } - if (isaligned && args.fsbno == NULLFSBLOCK) { + bma->idx--; + trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx), + LEFT.br_blockcount + PREV.br_blockcount + + RIGHT.br_blockcount); + trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); + + xfs_iext_remove(bma->ip, bma->idx + 1, 2, state); + bma->ip->i_d.di_nextents--; + if (bma->cur == NULL) + rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; + else { + rval = XFS_ILOG_CORE; + error = xfs_bmbt_lookup_eq(bma->cur, RIGHT.br_startoff, + RIGHT.br_startblock, + RIGHT.br_blockcount, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + error = xfs_btree_delete(bma->cur, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + error = xfs_btree_decrement(bma->cur, 0, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + error = xfs_bmbt_update(bma->cur, LEFT.br_startoff, + LEFT.br_startblock, + LEFT.br_blockcount + + PREV.br_blockcount + + RIGHT.br_blockcount, LEFT.br_state); + if (error) + goto done; + } + break; + + case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: /* - * allocation failed, so turn off alignment and - * try again. + * Filling in all of a previously delayed allocation extent. + * The left neighbor is contiguous, the right is not. */ - args.type = atype; - args.fsbno = ap->rval; - args.alignment = 0; - if ((error = xfs_alloc_vextent(&args))) - return error; - } - if (args.fsbno == NULLFSBLOCK && nullfb && - args.minlen > ap->minlen) { - args.minlen = ap->minlen; - args.type = XFS_ALLOCTYPE_START_BNO; - args.fsbno = ap->rval; - if ((error = xfs_alloc_vextent(&args))) - return error; - } - if (args.fsbno == NULLFSBLOCK && nullfb) { - args.fsbno = 0; - args.type = XFS_ALLOCTYPE_FIRST_AG; - args.total = ap->minlen; - args.minleft = 0; - if ((error = xfs_alloc_vextent(&args))) - return error; - ap->low = 1; - } - if (args.fsbno != NULLFSBLOCK) { - ap->firstblock = ap->rval = args.fsbno; - ASSERT(nullfb || fb_agno == args.agno || - (ap->low && fb_agno < args.agno)); - ap->alen = args.len; - ap->ip->i_d.di_nblocks += args.len; - xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); - if (ap->wasdel) - ap->ip->i_delayed_blks -= args.len; + bma->idx--; + + trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx), + LEFT.br_blockcount + PREV.br_blockcount); + trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); + + xfs_iext_remove(bma->ip, bma->idx + 1, 1, state); + if (bma->cur == NULL) + rval = XFS_ILOG_DEXT; + else { + rval = 0; + error = xfs_bmbt_lookup_eq(bma->cur, LEFT.br_startoff, + LEFT.br_startblock, LEFT.br_blockcount, + &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + error = xfs_bmbt_update(bma->cur, LEFT.br_startoff, + LEFT.br_startblock, + LEFT.br_blockcount + + PREV.br_blockcount, LEFT.br_state); + if (error) + goto done; + } + break; + + case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* - * Adjust the disk quota also. This was reserved - * earlier. + * Filling in all of a previously delayed allocation extent. + * The right neighbor is contiguous, the left is not. */ - xfs_trans_mod_dquot_byino(ap->tp, ap->ip, - ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT : - XFS_TRANS_DQ_BCOUNT, - (long) args.len); - } else { - ap->rval = NULLFSBLOCK; - ap->alen = 0; - } - return 0; -} - -/* - * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. - * It figures out where to ask the underlying allocator to put the new extent. - */ -STATIC int -xfs_bmap_alloc( - xfs_bmalloca_t *ap) /* bmap alloc argument struct */ -{ - if (XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata) - return xfs_bmap_rtalloc(ap); - return xfs_bmap_btalloc(ap); -} + trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); + xfs_bmbt_set_startblock(ep, new->br_startblock); + xfs_bmbt_set_blockcount(ep, + PREV.br_blockcount + RIGHT.br_blockcount); + trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); -/* - * Transform a btree format file with only one leaf node, where the - * extents list will fit in the inode, into an extents format file. - * Since the file extents are already in-core, all we have to do is - * give up the space for the btree root and pitch the leaf block. - */ -STATIC int /* error */ -xfs_bmap_btree_to_extents( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_btree_cur_t *cur, /* btree cursor */ - int *logflagsp, /* inode logging flags */ - int whichfork) /* data or attr fork */ -{ - /* REFERENCED */ - struct xfs_btree_block *cblock;/* child btree block */ - xfs_fsblock_t cbno; /* child block number */ - xfs_buf_t *cbp; /* child block's buffer */ - int error; /* error return value */ - xfs_ifork_t *ifp; /* inode fork data */ - xfs_mount_t *mp; /* mount point structure */ - __be64 *pp; /* ptr to block address */ - struct xfs_btree_block *rblock;/* root btree block */ - - mp = ip->i_mount; - ifp = XFS_IFORK_PTR(ip, whichfork); - ASSERT(ifp->if_flags & XFS_IFEXTENTS); - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); - rblock = ifp->if_broot; - ASSERT(be16_to_cpu(rblock->bb_level) == 1); - ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1); - ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0) == 1); - pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes); - cbno = be64_to_cpu(*pp); - *logflagsp = 0; -#ifdef DEBUG - if ((error = xfs_btree_check_lptr(cur, cbno, 1))) - return error; -#endif - if ((error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, - XFS_BMAP_BTREE_REF))) - return error; - cblock = XFS_BUF_TO_BLOCK(cbp); - if ((error = xfs_btree_check_block(cur, cblock, 0, cbp))) - return error; - xfs_bmap_add_free(cbno, 1, cur->bc_private.b.flist, mp); - ip->i_d.di_nblocks--; - xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); - xfs_trans_binval(tp, cbp); - if (cur->bc_bufs[0] == cbp) - cur->bc_bufs[0] = NULL; - xfs_iroot_realloc(ip, -1, whichfork); - ASSERT(ifp->if_broot == NULL); - ASSERT((ifp->if_flags & XFS_IFBROOT) == 0); - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); - *logflagsp = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); - return 0; -} - -/* - * Called by xfs_bmapi to update file extent records and the btree - * after removing space (or undoing a delayed allocation). - */ -STATIC int /* error */ -xfs_bmap_del_extent( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_trans_t *tp, /* current transaction pointer */ - xfs_extnum_t idx, /* extent number to update/delete */ - xfs_bmap_free_t *flist, /* list of extents to be freed */ - xfs_btree_cur_t *cur, /* if null, not a btree */ - xfs_bmbt_irec_t *del, /* data to remove from extents */ - int *logflagsp, /* inode logging flags */ - int whichfork, /* data or attr fork */ - int rsvd) /* OK to allocate reserved blocks */ -{ - xfs_filblks_t da_new; /* new delay-alloc indirect blocks */ - xfs_filblks_t da_old; /* old delay-alloc indirect blocks */ - xfs_fsblock_t del_endblock=0; /* first block past del */ - xfs_fileoff_t del_endoff; /* first offset past del */ - int delay; /* current block is delayed allocated */ - int do_fx; /* free extent at end of routine */ - xfs_bmbt_rec_host_t *ep; /* current extent entry pointer */ - int error; /* error return value */ - int flags; /* inode logging flags */ - xfs_bmbt_irec_t got; /* current extent entry */ - xfs_fileoff_t got_endoff; /* first offset past got */ - int i; /* temp state */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_mount_t *mp; /* mount structure */ - xfs_filblks_t nblks; /* quota/sb block count */ - xfs_bmbt_irec_t new; /* new record to be inserted */ - /* REFERENCED */ - uint qfield; /* quota field to update */ - xfs_filblks_t temp; /* for indirect length calculations */ - xfs_filblks_t temp2; /* for indirect length calculations */ - int state = 0; - - XFS_STATS_INC(xs_del_exlist); - - if (whichfork == XFS_ATTR_FORK) - state |= BMAP_ATTRFORK; + xfs_iext_remove(bma->ip, bma->idx + 1, 1, state); + if (bma->cur == NULL) + rval = XFS_ILOG_DEXT; + else { + rval = 0; + error = xfs_bmbt_lookup_eq(bma->cur, RIGHT.br_startoff, + RIGHT.br_startblock, + RIGHT.br_blockcount, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + error = xfs_bmbt_update(bma->cur, PREV.br_startoff, + new->br_startblock, + PREV.br_blockcount + + RIGHT.br_blockcount, PREV.br_state); + if (error) + goto done; + } + break; - mp = ip->i_mount; - ifp = XFS_IFORK_PTR(ip, whichfork); - ASSERT((idx >= 0) && (idx < ifp->if_bytes / - (uint)sizeof(xfs_bmbt_rec_t))); - ASSERT(del->br_blockcount > 0); - ep = xfs_iext_get_ext(ifp, idx); - xfs_bmbt_get_all(ep, &got); - ASSERT(got.br_startoff <= del->br_startoff); - del_endoff = del->br_startoff + del->br_blockcount; - got_endoff = got.br_startoff + got.br_blockcount; - ASSERT(got_endoff >= del_endoff); - delay = isnullstartblock(got.br_startblock); - ASSERT(isnullstartblock(del->br_startblock) == delay); - flags = 0; - qfield = 0; - error = 0; - /* - * If deleting a real allocation, must free up the disk space. - */ - if (!delay) { - flags = XFS_ILOG_CORE; + case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING: /* - * Realtime allocation. Free it and record di_nblocks update. + * Filling in all of a previously delayed allocation extent. + * Neither the left nor right neighbors are contiguous with + * the new one. */ - if (whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip)) { - xfs_fsblock_t bno; - xfs_filblks_t len; + trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); + xfs_bmbt_set_startblock(ep, new->br_startblock); + trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); - ASSERT(do_mod(del->br_blockcount, - mp->m_sb.sb_rextsize) == 0); - ASSERT(do_mod(del->br_startblock, - mp->m_sb.sb_rextsize) == 0); - bno = del->br_startblock; - len = del->br_blockcount; - do_div(bno, mp->m_sb.sb_rextsize); - do_div(len, mp->m_sb.sb_rextsize); - if ((error = xfs_rtfree_extent(ip->i_transp, bno, - (xfs_extlen_t)len))) + bma->ip->i_d.di_nextents++; + if (bma->cur == NULL) + rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; + else { + rval = XFS_ILOG_CORE; + error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff, + new->br_startblock, new->br_blockcount, + &i); + if (error) goto done; - do_fx = 0; - nblks = len * mp->m_sb.sb_rextsize; - qfield = XFS_TRANS_DQ_RTBCOUNT; + XFS_WANT_CORRUPTED_GOTO(i == 0, done); + bma->cur->bc_rec.b.br_state = XFS_EXT_NORM; + error = xfs_btree_insert(bma->cur, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); } + break; + + case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG: /* - * Ordinary allocation. + * Filling in the first part of a previous delayed allocation. + * The left neighbor is contiguous. */ + trace_xfs_bmap_pre_update(bma->ip, bma->idx - 1, state, _THIS_IP_); + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx - 1), + LEFT.br_blockcount + new->br_blockcount); + xfs_bmbt_set_startoff(ep, + PREV.br_startoff + new->br_blockcount); + trace_xfs_bmap_post_update(bma->ip, bma->idx - 1, state, _THIS_IP_); + + temp = PREV.br_blockcount - new->br_blockcount; + trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); + xfs_bmbt_set_blockcount(ep, temp); + if (bma->cur == NULL) + rval = XFS_ILOG_DEXT; else { - do_fx = 1; - nblks = del->br_blockcount; - qfield = XFS_TRANS_DQ_BCOUNT; - } - /* - * Set up del_endblock and cur for later. - */ - del_endblock = del->br_startblock + del->br_blockcount; - if (cur) { - if ((error = xfs_bmbt_lookup_eq(cur, got.br_startoff, - got.br_startblock, got.br_blockcount, - &i))) + rval = 0; + error = xfs_bmbt_lookup_eq(bma->cur, LEFT.br_startoff, + LEFT.br_startblock, LEFT.br_blockcount, + &i); + if (error) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); + error = xfs_bmbt_update(bma->cur, LEFT.br_startoff, + LEFT.br_startblock, + LEFT.br_blockcount + + new->br_blockcount, + LEFT.br_state); + if (error) + goto done; } - da_old = da_new = 0; - } else { - da_old = startblockval(got.br_startblock); - da_new = 0; - nblks = 0; - do_fx = 0; - } - /* - * Set flag value to use in switch statement. - * Left-contig is 2, right-contig is 1. - */ - switch (((got.br_startoff == del->br_startoff) << 1) | - (got_endoff == del_endoff)) { - case 3: - /* - * Matches the whole extent. Delete the entry. - */ - xfs_iext_remove(ip, idx, 1, - whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); - ifp->if_lastex = idx; - if (delay) - break; - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) - 1); - flags |= XFS_ILOG_CORE; - if (!cur) { - flags |= xfs_ilog_fext(whichfork); - break; - } - if ((error = xfs_btree_delete(cur, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); + da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), + startblockval(PREV.br_startblock)); + xfs_bmbt_set_startblock(ep, nullstartblock(da_new)); + trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); + + bma->idx--; break; - case 2: + case BMAP_LEFT_FILLING: /* - * Deleting the first part of the extent. + * Filling in the first part of a previous delayed allocation. + * The left neighbor is not contiguous. */ - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); - xfs_bmbt_set_startoff(ep, del_endoff); - temp = got.br_blockcount - del->br_blockcount; + trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); + xfs_bmbt_set_startoff(ep, new_endoff); + temp = PREV.br_blockcount - new->br_blockcount; xfs_bmbt_set_blockcount(ep, temp); - ifp->if_lastex = idx; - if (delay) { - temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), - da_old); - xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); - da_new = temp; - break; + xfs_iext_insert(bma->ip, bma->idx, 1, new, state); + bma->ip->i_d.di_nextents++; + if (bma->cur == NULL) + rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; + else { + rval = XFS_ILOG_CORE; + error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff, + new->br_startblock, new->br_blockcount, + &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 0, done); + bma->cur->bc_rec.b.br_state = XFS_EXT_NORM; + error = xfs_btree_insert(bma->cur, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); } - xfs_bmbt_set_startblock(ep, del_endblock); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); - if (!cur) { - flags |= xfs_ilog_fext(whichfork); - break; + + if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { + error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, + bma->firstblock, bma->flist, + &bma->cur, 1, &tmp_rval, XFS_DATA_FORK); + rval |= tmp_rval; + if (error) + goto done; } - if ((error = xfs_bmbt_update(cur, del_endoff, del_endblock, - got.br_blockcount - del->br_blockcount, - got.br_state))) - goto done; + da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), + startblockval(PREV.br_startblock) - + (bma->cur ? bma->cur->bc_private.b.allocated : 0)); + ep = xfs_iext_get_ext(ifp, bma->idx + 1); + xfs_bmbt_set_startblock(ep, nullstartblock(da_new)); + trace_xfs_bmap_post_update(bma->ip, bma->idx + 1, state, _THIS_IP_); break; - case 1: + case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* - * Deleting the last part of the extent. + * Filling in the last part of a previous delayed allocation. + * The right neighbor is contiguous with the new allocation. */ - temp = got.br_blockcount - del->br_blockcount; - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); + temp = PREV.br_blockcount - new->br_blockcount; + trace_xfs_bmap_pre_update(bma->ip, bma->idx + 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, temp); - ifp->if_lastex = idx; - if (delay) { - temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), - da_old); - xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); - da_new = temp; - break; + xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, bma->idx + 1), + new->br_startoff, new->br_startblock, + new->br_blockcount + RIGHT.br_blockcount, + RIGHT.br_state); + trace_xfs_bmap_post_update(bma->ip, bma->idx + 1, state, _THIS_IP_); + if (bma->cur == NULL) + rval = XFS_ILOG_DEXT; + else { + rval = 0; + error = xfs_bmbt_lookup_eq(bma->cur, RIGHT.br_startoff, + RIGHT.br_startblock, + RIGHT.br_blockcount, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + error = xfs_bmbt_update(bma->cur, new->br_startoff, + new->br_startblock, + new->br_blockcount + + RIGHT.br_blockcount, + RIGHT.br_state); + if (error) + goto done; } - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); - if (!cur) { - flags |= xfs_ilog_fext(whichfork); - break; + + da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), + startblockval(PREV.br_startblock)); + trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); + xfs_bmbt_set_startblock(ep, nullstartblock(da_new)); + trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); + + bma->idx++; + break; + + case BMAP_RIGHT_FILLING: + /* + * Filling in the last part of a previous delayed allocation. + * The right neighbor is not contiguous. + */ + temp = PREV.br_blockcount - new->br_blockcount; + trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); + xfs_bmbt_set_blockcount(ep, temp); + xfs_iext_insert(bma->ip, bma->idx + 1, 1, new, state); + bma->ip->i_d.di_nextents++; + if (bma->cur == NULL) + rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; + else { + rval = XFS_ILOG_CORE; + error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff, + new->br_startblock, new->br_blockcount, + &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 0, done); + bma->cur->bc_rec.b.br_state = XFS_EXT_NORM; + error = xfs_btree_insert(bma->cur, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); } - if ((error = xfs_bmbt_update(cur, got.br_startoff, - got.br_startblock, - got.br_blockcount - del->br_blockcount, - got.br_state))) - goto done; + + if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { + error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, + bma->firstblock, bma->flist, &bma->cur, 1, + &tmp_rval, XFS_DATA_FORK); + rval |= tmp_rval; + if (error) + goto done; + } + da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), + startblockval(PREV.br_startblock) - + (bma->cur ? bma->cur->bc_private.b.allocated : 0)); + ep = xfs_iext_get_ext(ifp, bma->idx); + xfs_bmbt_set_startblock(ep, nullstartblock(da_new)); + trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); + + bma->idx++; break; case 0: /* - * Deleting the middle of the extent. + * Filling in the middle part of a previous delayed allocation. + * Contiguity is impossible here. + * This case is avoided almost all the time. + * + * We start with a delayed allocation: + * + * +ddddddddddddddddddddddddddddddddddddddddddddddddddddddd+ + * PREV @ idx + * + * and we are allocating: + * +rrrrrrrrrrrrrrrrr+ + * new + * + * and we set it up for insertion as: + * +ddddddddddddddddddd+rrrrrrrrrrrrrrrrr+ddddddddddddddddd+ + * new + * PREV @ idx LEFT RIGHT + * inserted at idx + 1 */ - temp = del->br_startoff - got.br_startoff; - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); - xfs_bmbt_set_blockcount(ep, temp); - new.br_startoff = del_endoff; - temp2 = got_endoff - del_endoff; - new.br_blockcount = temp2; - new.br_state = got.br_state; - if (!delay) { - new.br_startblock = del_endblock; - flags |= XFS_ILOG_CORE; - if (cur) { - if ((error = xfs_bmbt_update(cur, - got.br_startoff, - got.br_startblock, temp, - got.br_state))) - goto done; - if ((error = xfs_btree_increment(cur, 0, &i))) - goto done; - cur->bc_rec.b = new; - error = xfs_btree_insert(cur, &i); - if (error && error != ENOSPC) - goto done; - /* - * If get no-space back from btree insert, - * it tried a split, and we have a zero - * block reservation. - * Fix up our state and return the error. - */ - if (error == ENOSPC) { - /* - * Reset the cursor, don't trust - * it after any insert operation. - */ - if ((error = xfs_bmbt_lookup_eq(cur, - got.br_startoff, - got.br_startblock, - temp, &i))) - goto done; - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - /* - * Update the btree record back - * to the original value. - */ - if ((error = xfs_bmbt_update(cur, - got.br_startoff, - got.br_startblock, - got.br_blockcount, - got.br_state))) - goto done; - /* - * Reset the extent record back - * to the original value. - */ - xfs_bmbt_set_blockcount(ep, - got.br_blockcount); - flags = 0; - error = XFS_ERROR(ENOSPC); - goto done; - } - XFS_WANT_CORRUPTED_GOTO(i == 1, done); - } else - flags |= xfs_ilog_fext(whichfork); - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) + 1); - } else { - ASSERT(whichfork == XFS_DATA_FORK); - temp = xfs_bmap_worst_indlen(ip, temp); - xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); - temp2 = xfs_bmap_worst_indlen(ip, temp2); - new.br_startblock = nullstartblock((int)temp2); - da_new = temp + temp2; - while (da_new > da_old) { - if (temp) { - temp--; - da_new--; - xfs_bmbt_set_startblock(ep, - nullstartblock((int)temp)); - } - if (da_new == da_old) - break; - if (temp2) { - temp2--; - da_new--; - new.br_startblock = - nullstartblock((int)temp2); - } - } + temp = new->br_startoff - PREV.br_startoff; + temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; + trace_xfs_bmap_pre_update(bma->ip, bma->idx, 0, _THIS_IP_); + xfs_bmbt_set_blockcount(ep, temp); /* truncate PREV */ + LEFT = *new; + RIGHT.br_state = PREV.br_state; + RIGHT.br_startblock = nullstartblock( + (int)xfs_bmap_worst_indlen(bma->ip, temp2)); + RIGHT.br_startoff = new_endoff; + RIGHT.br_blockcount = temp2; + /* insert LEFT (r[0]) and RIGHT (r[1]) at the same time */ + xfs_iext_insert(bma->ip, bma->idx + 1, 2, &LEFT, state); + bma->ip->i_d.di_nextents++; + if (bma->cur == NULL) + rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; + else { + rval = XFS_ILOG_CORE; + error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff, + new->br_startblock, new->br_blockcount, + &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 0, done); + bma->cur->bc_rec.b.br_state = XFS_EXT_NORM; + error = xfs_btree_insert(bma->cur, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + } + + if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { + error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, + bma->firstblock, bma->flist, &bma->cur, + 1, &tmp_rval, XFS_DATA_FORK); + rval |= tmp_rval; + if (error) + goto done; + } + temp = xfs_bmap_worst_indlen(bma->ip, temp); + temp2 = xfs_bmap_worst_indlen(bma->ip, temp2); + diff = (int)(temp + temp2 - startblockval(PREV.br_startblock) - + (bma->cur ? bma->cur->bc_private.b.allocated : 0)); + if (diff > 0) { + error = xfs_icsb_modify_counters(bma->ip->i_mount, + XFS_SBS_FDBLOCKS, + -((int64_t)diff), 0); + ASSERT(!error); + if (error) + goto done; } - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); - xfs_iext_insert(ip, idx + 1, 1, &new, state); - ifp->if_lastex = idx + 1; + + ep = xfs_iext_get_ext(ifp, bma->idx); + xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); + trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); + trace_xfs_bmap_pre_update(bma->ip, bma->idx + 2, state, _THIS_IP_); + xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, bma->idx + 2), + nullstartblock((int)temp2)); + trace_xfs_bmap_post_update(bma->ip, bma->idx + 2, state, _THIS_IP_); + + bma->idx++; + da_new = temp + temp2; break; + + case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: + case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: + case BMAP_LEFT_FILLING | BMAP_RIGHT_CONTIG: + case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: + case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: + case BMAP_LEFT_CONTIG: + case BMAP_RIGHT_CONTIG: + /* + * These cases are all impossible. + */ + ASSERT(0); } - /* - * If we need to, add to list of extents to delete. - */ - if (do_fx) - xfs_bmap_add_free(del->br_startblock, del->br_blockcount, flist, - mp); - /* - * Adjust inode # blocks in the file. - */ - if (nblks) - ip->i_d.di_nblocks -= nblks; - /* - * Adjust quota data. - */ - if (qfield) - xfs_trans_mod_dquot_byino(tp, ip, qfield, (long)-nblks); - /* - * Account for change in delayed indirect blocks. - * Nothing to do for disk quota accounting here. - */ - ASSERT(da_old >= da_new); - if (da_old > da_new) { - xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, - (int64_t)(da_old - da_new), rsvd); + /* convert to a btree if necessary */ + if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { + int tmp_logflags; /* partial log flag return val */ + + ASSERT(bma->cur == NULL); + error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, + bma->firstblock, bma->flist, &bma->cur, + da_old > 0, &tmp_logflags, XFS_DATA_FORK); + bma->logflags |= tmp_logflags; + if (error) + goto done; + } + + /* adjust for changes in reserved delayed indirect blocks */ + if (da_old || da_new) { + temp = da_new; + if (bma->cur) + temp += bma->cur->bc_private.b.allocated; + ASSERT(temp <= da_old); + if (temp < da_old) + xfs_icsb_modify_counters(bma->ip->i_mount, + XFS_SBS_FDBLOCKS, + (int64_t)(da_old - temp), 0); } + + /* clear out the allocated field, done with it now in any case. */ + if (bma->cur) + bma->cur->bc_private.b.allocated = 0; + + xfs_bmap_check_leaf_extents(bma->cur, bma->ip, XFS_DATA_FORK); done: - *logflagsp = flags; + bma->logflags |= rval; return error; +#undef LEFT +#undef RIGHT +#undef PREV } /* - * Remove the entry "free" from the free item list. Prev points to the - * previous entry, unless "free" is the head of the list. + * Convert an unwritten allocation to a real allocation or vice versa. */ -void -xfs_bmap_del_free( - xfs_bmap_free_t *flist, /* free item list header */ - xfs_bmap_free_item_t *prev, /* previous item on list, if any */ - xfs_bmap_free_item_t *free) /* list item to be freed */ +STATIC int /* error */ +xfs_bmap_add_extent_unwritten_real( + struct xfs_trans *tp, + xfs_inode_t *ip, /* incore inode pointer */ + xfs_extnum_t *idx, /* extent number to update/insert */ + xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ + xfs_bmbt_irec_t *new, /* new data to add to file extents */ + xfs_fsblock_t *first, /* pointer to firstblock variable */ + xfs_bmap_free_t *flist, /* list of extents to be freed */ + int *logflagsp) /* inode logging flags */ { - if (prev) - prev->xbfi_next = free->xbfi_next; - else - flist->xbf_first = free->xbfi_next; - flist->xbf_count--; - kmem_zone_free(xfs_bmap_free_item_zone, free); -} - -/* - * Convert an extents-format file into a btree-format file. - * The new file will have a root block (in the inode) and a single child block. - */ -STATIC int /* error */ -xfs_bmap_extents_to_btree( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_fsblock_t *firstblock, /* first-block-allocated */ - xfs_bmap_free_t *flist, /* blocks freed in xaction */ - xfs_btree_cur_t **curp, /* cursor returned to caller */ - int wasdel, /* converting a delayed alloc */ - int *logflagsp, /* inode logging flags */ - int whichfork) /* data or attr fork */ -{ - struct xfs_btree_block *ablock; /* allocated (child) bt block */ - xfs_buf_t *abp; /* buffer for ablock */ - xfs_alloc_arg_t args; /* allocation arguments */ - xfs_bmbt_rec_t *arp; /* child record pointer */ - struct xfs_btree_block *block; /* btree root block */ - xfs_btree_cur_t *cur; /* bmap btree cursor */ - xfs_bmbt_rec_host_t *ep; /* extent record pointer */ - int error; /* error return value */ - xfs_extnum_t i, cnt; /* extent record index */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_bmbt_key_t *kp; /* root block key pointer */ - xfs_mount_t *mp; /* mount structure */ - xfs_extnum_t nextents; /* number of file extents */ - xfs_bmbt_ptr_t *pp; /* root block address pointer */ + xfs_btree_cur_t *cur; /* btree cursor */ + xfs_bmbt_rec_host_t *ep; /* extent entry for idx */ + int error; /* error return value */ + int i; /* temp state */ + xfs_ifork_t *ifp; /* inode fork pointer */ + xfs_fileoff_t new_endoff; /* end offset of new entry */ + xfs_exntst_t newext; /* new extent state */ + xfs_exntst_t oldext; /* old extent state */ + xfs_bmbt_irec_t r[3]; /* neighbor extent entries */ + /* left is 0, right is 1, prev is 2 */ + int rval=0; /* return value (logging flags) */ + int state = 0;/* state bits, accessed thru macros */ - ifp = XFS_IFORK_PTR(ip, whichfork); - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS); - ASSERT(ifp->if_ext_max == - XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); - /* - * Make space in the inode incore. - */ - xfs_iroot_realloc(ip, 1, whichfork); - ifp->if_flags |= XFS_IFBROOT; + *logflagsp = 0; - /* - * Fill in the root. - */ - block = ifp->if_broot; - block->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC); - block->bb_level = cpu_to_be16(1); - block->bb_numrecs = cpu_to_be16(1); - block->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO); - block->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO); + cur = *curp; + ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); + + ASSERT(*idx >= 0); + ASSERT(*idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec)); + ASSERT(!isnullstartblock(new->br_startblock)); + + XFS_STATS_INC(xs_add_exlist); + +#define LEFT r[0] +#define RIGHT r[1] +#define PREV r[2] /* - * Need a cursor. Can't allocate until bb_level is filled in. - */ - mp = ip->i_mount; - cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); - cur->bc_private.b.firstblock = *firstblock; - cur->bc_private.b.flist = flist; - cur->bc_private.b.flags = wasdel ? XFS_BTCUR_BPRV_WASDEL : 0; - /* - * Convert to a btree with two levels, one record in root. - */ - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); - args.tp = tp; - args.mp = mp; - args.firstblock = *firstblock; - if (*firstblock == NULLFSBLOCK) { - args.type = XFS_ALLOCTYPE_START_BNO; - args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); - } else if (flist->xbf_low) { - args.type = XFS_ALLOCTYPE_START_BNO; - args.fsbno = *firstblock; - } else { - args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.fsbno = *firstblock; - } - args.minlen = args.maxlen = args.prod = 1; - args.total = args.minleft = args.alignment = args.mod = args.isfl = - args.minalignslop = 0; - args.wasdel = wasdel; - *logflagsp = 0; - if ((error = xfs_alloc_vextent(&args))) { - xfs_iroot_realloc(ip, -1, whichfork); - xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); - return error; - } - /* - * Allocation can't fail, the space was reserved. - */ - ASSERT(args.fsbno != NULLFSBLOCK); - ASSERT(*firstblock == NULLFSBLOCK || - args.agno == XFS_FSB_TO_AGNO(mp, *firstblock) || - (flist->xbf_low && - args.agno > XFS_FSB_TO_AGNO(mp, *firstblock))); - *firstblock = cur->bc_private.b.firstblock = args.fsbno; - cur->bc_private.b.allocated++; - ip->i_d.di_nblocks++; - xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); - abp = xfs_btree_get_bufl(mp, tp, args.fsbno, 0); - /* - * Fill in the child block. + * Set up a bunch of variables to make the tests simpler. */ - ablock = XFS_BUF_TO_BLOCK(abp); - ablock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC); - ablock->bb_level = 0; - ablock->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO); - ablock->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO); - arp = XFS_BMBT_REC_ADDR(mp, ablock, 1); - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - for (cnt = i = 0; i < nextents; i++) { - ep = xfs_iext_get_ext(ifp, i); - if (!isnullstartblock(xfs_bmbt_get_startblock(ep))) { - arp->l0 = cpu_to_be64(ep->l0); - arp->l1 = cpu_to_be64(ep->l1); - arp++; cnt++; - } - } - ASSERT(cnt == XFS_IFORK_NEXTENTS(ip, whichfork)); - xfs_btree_set_numrecs(ablock, cnt); + error = 0; + ep = xfs_iext_get_ext(ifp, *idx); + xfs_bmbt_get_all(ep, &PREV); + newext = new->br_state; + oldext = (newext == XFS_EXT_UNWRITTEN) ? + XFS_EXT_NORM : XFS_EXT_UNWRITTEN; + ASSERT(PREV.br_state == oldext); + new_endoff = new->br_startoff + new->br_blockcount; + ASSERT(PREV.br_startoff <= new->br_startoff); + ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff); /* - * Fill in the root key and pointer. + * Set flags determining what part of the previous oldext allocation + * extent is being replaced by a newext allocation. */ - kp = XFS_BMBT_KEY_ADDR(mp, block, 1); - arp = XFS_BMBT_REC_ADDR(mp, ablock, 1); - kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp)); - pp = XFS_BMBT_PTR_ADDR(mp, block, 1, xfs_bmbt_get_maxrecs(cur, - be16_to_cpu(block->bb_level))); - *pp = cpu_to_be64(args.fsbno); + if (PREV.br_startoff == new->br_startoff) + state |= BMAP_LEFT_FILLING; + if (PREV.br_startoff + PREV.br_blockcount == new_endoff) + state |= BMAP_RIGHT_FILLING; /* - * Do all this logging at the end so that - * the root is at the right level. + * Check and set flags if this segment has a left neighbor. + * Don't set contiguous if the combined extent would be too large. */ - xfs_btree_log_block(cur, abp, XFS_BB_ALL_BITS); - xfs_btree_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs)); - ASSERT(*curp == NULL); - *curp = cur; - *logflagsp = XFS_ILOG_CORE | xfs_ilog_fbroot(whichfork); - return 0; -} - -/* - * Calculate the default attribute fork offset for newly created inodes. - */ -uint -xfs_default_attroffset( - struct xfs_inode *ip) -{ - struct xfs_mount *mp = ip->i_mount; - uint offset; + if (*idx > 0) { + state |= BMAP_LEFT_VALID; + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &LEFT); - if (mp->m_sb.sb_inodesize == 256) { - offset = XFS_LITINO(mp) - - XFS_BMDR_SPACE_CALC(MINABTPTRS); - } else { - offset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS); + if (isnullstartblock(LEFT.br_startblock)) + state |= BMAP_LEFT_DELAY; } - ASSERT(offset < XFS_LITINO(mp)); - return offset; -} - -/* - * Helper routine to reset inode di_forkoff field when switching - * attribute fork from local to extent format - we reset it where - * possible to make space available for inline data fork extents. - */ -STATIC void -xfs_bmap_forkoff_reset( - xfs_mount_t *mp, - xfs_inode_t *ip, - int whichfork) -{ - if (whichfork == XFS_ATTR_FORK && - ip->i_d.di_format != XFS_DINODE_FMT_DEV && - ip->i_d.di_format != XFS_DINODE_FMT_UUID && - ip->i_d.di_format != XFS_DINODE_FMT_BTREE) { - uint dfl_forkoff = xfs_default_attroffset(ip) >> 3; + if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) && + LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff && + LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock && + LEFT.br_state == newext && + LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN) + state |= BMAP_LEFT_CONTIG; - if (dfl_forkoff > ip->i_d.di_forkoff) { - ip->i_d.di_forkoff = dfl_forkoff; - ip->i_df.if_ext_max = - XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t); - ip->i_afp->if_ext_max = - XFS_IFORK_ASIZE(ip) / sizeof(xfs_bmbt_rec_t); - } + /* + * Check and set flags if this segment has a right neighbor. + * Don't set contiguous if the combined extent would be too large. + * Also check for all-three-contiguous being too large. + */ + if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { + state |= BMAP_RIGHT_VALID; + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx + 1), &RIGHT); + if (isnullstartblock(RIGHT.br_startblock)) + state |= BMAP_RIGHT_DELAY; } -} -/* - * Convert a local file to an extents file. - * This code is out of bounds for data forks of regular files, - * since the file data needs to get logged so things will stay consistent. - * (The bmap-level manipulations are ok, though). - */ -STATIC int /* error */ -xfs_bmap_local_to_extents( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_fsblock_t *firstblock, /* first block allocated in xaction */ - xfs_extlen_t total, /* total blocks needed by transaction */ - int *logflagsp, /* inode logging flags */ - int whichfork) /* data or attr fork */ -{ - int error; /* error return value */ - int flags; /* logging flags returned */ - xfs_ifork_t *ifp; /* inode fork pointer */ + if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) && + new_endoff == RIGHT.br_startoff && + new->br_startblock + new->br_blockcount == RIGHT.br_startblock && + newext == RIGHT.br_state && + new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN && + ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | + BMAP_RIGHT_FILLING)) != + (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | + BMAP_RIGHT_FILLING) || + LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount + <= MAXEXTLEN)) + state |= BMAP_RIGHT_CONTIG; /* - * We don't want to deal with the case of keeping inode data inline yet. - * So sending the data fork of a regular inode is invalid. + * Switch out based on the FILLING and CONTIG state bits. */ - ASSERT(!((ip->i_d.di_mode & S_IFMT) == S_IFREG && - whichfork == XFS_DATA_FORK)); - ifp = XFS_IFORK_PTR(ip, whichfork); - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); - flags = 0; - error = 0; - if (ifp->if_bytes) { - xfs_alloc_arg_t args; /* allocation arguments */ - xfs_buf_t *bp; /* buffer for extent block */ - xfs_bmbt_rec_host_t *ep;/* extent record pointer */ - - args.tp = tp; - args.mp = ip->i_mount; - args.firstblock = *firstblock; - ASSERT((ifp->if_flags & - (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE); - /* - * Allocate a block. We know we need only one, since the - * file currently fits in an inode. - */ - if (*firstblock == NULLFSBLOCK) { - args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino); - args.type = XFS_ALLOCTYPE_START_BNO; - } else { - args.fsbno = *firstblock; - args.type = XFS_ALLOCTYPE_NEAR_BNO; - } - args.total = total; - args.mod = args.minleft = args.alignment = args.wasdel = - args.isfl = args.minalignslop = 0; - args.minlen = args.maxlen = args.prod = 1; - if ((error = xfs_alloc_vextent(&args))) - goto done; + switch (state & (BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | + BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG)) { + case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | + BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* - * Can't fail, the space was reserved. + * Setting all of a previous oldext extent to newext. + * The left and right neighbors are both contiguous with new. */ - ASSERT(args.fsbno != NULLFSBLOCK); - ASSERT(args.len == 1); - *firstblock = args.fsbno; - bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0); - memcpy((char *)XFS_BUF_PTR(bp), ifp->if_u1.if_data, - ifp->if_bytes); - xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1); - xfs_bmap_forkoff_reset(args.mp, ip, whichfork); - xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); - xfs_iext_add(ifp, 0, 1); - ep = xfs_iext_get_ext(ifp, 0); - xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM); - trace_xfs_bmap_post_update(ip, 0, - whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0, - _THIS_IP_); - XFS_IFORK_NEXT_SET(ip, whichfork, 1); - ip->i_d.di_nblocks = 1; - xfs_trans_mod_dquot_byino(tp, ip, - XFS_TRANS_DQ_BCOUNT, 1L); - flags |= xfs_ilog_fext(whichfork); - } else { - ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0); - xfs_bmap_forkoff_reset(ip->i_mount, ip, whichfork); - } - ifp->if_flags &= ~XFS_IFINLINE; - ifp->if_flags |= XFS_IFEXTENTS; - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); - flags |= XFS_ILOG_CORE; -done: - *logflagsp = flags; - return error; -} + --*idx; -/* - * Search the extent records for the entry containing block bno. - * If bno lies in a hole, point to the next entry. If bno lies - * past eof, *eofp will be set, and *prevp will contain the last - * entry (null if none). Else, *lastxp will be set to the index - * of the found entry; *gotp will contain the entry. - */ -STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */ -xfs_bmap_search_multi_extents( - xfs_ifork_t *ifp, /* inode fork pointer */ - xfs_fileoff_t bno, /* block number searched for */ - int *eofp, /* out: end of file found */ - xfs_extnum_t *lastxp, /* out: last extent index */ - xfs_bmbt_irec_t *gotp, /* out: extent entry found */ - xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ -{ - xfs_bmbt_rec_host_t *ep; /* extent record pointer */ - xfs_extnum_t lastx; /* last extent index */ + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), + LEFT.br_blockcount + PREV.br_blockcount + + RIGHT.br_blockcount); + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); - /* - * Initialize the extent entry structure to catch access to - * uninitialized br_startblock field. - */ - gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL; - gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL; - gotp->br_state = XFS_EXT_INVALID; -#if XFS_BIG_BLKNOS - gotp->br_startblock = 0xffffa5a5a5a5a5a5LL; -#else - gotp->br_startblock = 0xffffa5a5; -#endif - prevp->br_startoff = NULLFILEOFF; + xfs_iext_remove(ip, *idx + 1, 2, state); + ip->i_d.di_nextents -= 2; + if (cur == NULL) + rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; + else { + rval = XFS_ILOG_CORE; + if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, + RIGHT.br_startblock, + RIGHT.br_blockcount, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_btree_delete(cur, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_btree_decrement(cur, 0, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_btree_delete(cur, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_btree_decrement(cur, 0, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, + LEFT.br_startblock, + LEFT.br_blockcount + PREV.br_blockcount + + RIGHT.br_blockcount, LEFT.br_state))) + goto done; + } + break; - ep = xfs_iext_bno_to_ext(ifp, bno, &lastx); - if (lastx > 0) { - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp); - } - if (lastx < (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) { - xfs_bmbt_get_all(ep, gotp); - *eofp = 0; - } else { - if (lastx > 0) { - *gotp = *prevp; + case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: + /* + * Setting all of a previous oldext extent to newext. + * The left neighbor is contiguous, the right is not. + */ + --*idx; + + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), + LEFT.br_blockcount + PREV.br_blockcount); + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); + + xfs_iext_remove(ip, *idx + 1, 1, state); + ip->i_d.di_nextents--; + if (cur == NULL) + rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; + else { + rval = XFS_ILOG_CORE; + if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, + PREV.br_startblock, PREV.br_blockcount, + &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_btree_delete(cur, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_btree_decrement(cur, 0, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, + LEFT.br_startblock, + LEFT.br_blockcount + PREV.br_blockcount, + LEFT.br_state))) + goto done; } - *eofp = 1; - ep = NULL; - } - *lastxp = lastx; - return ep; -} + break; -/* - * Search the extents list for the inode, for the extent containing bno. - * If bno lies in a hole, point to the next entry. If bno lies past eof, - * *eofp will be set, and *prevp will contain the last entry (null if none). - * Else, *lastxp will be set to the index of the found - * entry; *gotp will contain the entry. - */ -xfs_bmbt_rec_host_t * /* pointer to found extent entry */ -xfs_bmap_search_extents( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_fileoff_t bno, /* block number searched for */ - int fork, /* data or attr fork */ - int *eofp, /* out: end of file found */ - xfs_extnum_t *lastxp, /* out: last extent index */ - xfs_bmbt_irec_t *gotp, /* out: extent entry found */ - xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ -{ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_bmbt_rec_host_t *ep; /* extent record pointer */ + case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: + /* + * Setting all of a previous oldext extent to newext. + * The right neighbor is contiguous, the left is not. + */ + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); + xfs_bmbt_set_blockcount(ep, + PREV.br_blockcount + RIGHT.br_blockcount); + xfs_bmbt_set_state(ep, newext); + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); + xfs_iext_remove(ip, *idx + 1, 1, state); + ip->i_d.di_nextents--; + if (cur == NULL) + rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; + else { + rval = XFS_ILOG_CORE; + if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, + RIGHT.br_startblock, + RIGHT.br_blockcount, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_btree_delete(cur, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_btree_decrement(cur, 0, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_bmbt_update(cur, new->br_startoff, + new->br_startblock, + new->br_blockcount + RIGHT.br_blockcount, + newext))) + goto done; + } + break; - XFS_STATS_INC(xs_look_exlist); - ifp = XFS_IFORK_PTR(ip, fork); + case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING: + /* + * Setting all of a previous oldext extent to newext. + * Neither the left nor right neighbors are contiguous with + * the new one. + */ + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); + xfs_bmbt_set_state(ep, newext); + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); - ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp); + if (cur == NULL) + rval = XFS_ILOG_DEXT; + else { + rval = 0; + if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, + new->br_startblock, new->br_blockcount, + &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_bmbt_update(cur, new->br_startoff, + new->br_startblock, new->br_blockcount, + newext))) + goto done; + } + break; - if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) && - !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) { - xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount, - "Access to block zero in inode %llu " - "start_block: %llx start_off: %llx " - "blkcnt: %llx extent-state: %x lastx: %x\n", - (unsigned long long)ip->i_ino, - (unsigned long long)gotp->br_startblock, - (unsigned long long)gotp->br_startoff, - (unsigned long long)gotp->br_blockcount, - gotp->br_state, *lastxp); - *lastxp = NULLEXTNUM; - *eofp = 1; - return NULL; - } - return ep; -} + case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG: + /* + * Setting the first part of a previous oldext extent to newext. + * The left neighbor is contiguous. + */ + trace_xfs_bmap_pre_update(ip, *idx - 1, state, _THIS_IP_); + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx - 1), + LEFT.br_blockcount + new->br_blockcount); + xfs_bmbt_set_startoff(ep, + PREV.br_startoff + new->br_blockcount); + trace_xfs_bmap_post_update(ip, *idx - 1, state, _THIS_IP_); -/* - * Compute the worst-case number of indirect blocks that will be used - * for ip's delayed extent of length "len". - */ -STATIC xfs_filblks_t -xfs_bmap_worst_indlen( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_filblks_t len) /* delayed extent length */ -{ - int level; /* btree level number */ - int maxrecs; /* maximum record count at this level */ - xfs_mount_t *mp; /* mount structure */ - xfs_filblks_t rval; /* return value */ + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); + xfs_bmbt_set_startblock(ep, + new->br_startblock + new->br_blockcount); + xfs_bmbt_set_blockcount(ep, + PREV.br_blockcount - new->br_blockcount); + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); - mp = ip->i_mount; - maxrecs = mp->m_bmap_dmxr[0]; - for (level = 0, rval = 0; - level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK); - level++) { - len += maxrecs - 1; - do_div(len, maxrecs); - rval += len; - if (len == 1) - return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - - level - 1; - if (level == 0) - maxrecs = mp->m_bmap_dmxr[1]; - } - return rval; -} + --*idx; -/* - * Convert inode from non-attributed to attributed. - * Must not be in a transaction, ip must not be locked. - */ -int /* error code */ -xfs_bmap_add_attrfork( - xfs_inode_t *ip, /* incore inode pointer */ - int size, /* space new attribute needs */ - int rsvd) /* xact may use reserved blks */ -{ - xfs_fsblock_t firstblock; /* 1st block/ag allocated */ - xfs_bmap_free_t flist; /* freed extent records */ - xfs_mount_t *mp; /* mount structure */ - xfs_trans_t *tp; /* transaction pointer */ - int blks; /* space reservation */ - int version = 1; /* superblock attr version */ - int committed; /* xaction was committed */ - int logflags; /* logging flags */ - int error; /* error return value */ + if (cur == NULL) + rval = XFS_ILOG_DEXT; + else { + rval = 0; + if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, + PREV.br_startblock, PREV.br_blockcount, + &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_bmbt_update(cur, + PREV.br_startoff + new->br_blockcount, + PREV.br_startblock + new->br_blockcount, + PREV.br_blockcount - new->br_blockcount, + oldext))) + goto done; + if ((error = xfs_btree_decrement(cur, 0, &i))) + goto done; + error = xfs_bmbt_update(cur, LEFT.br_startoff, + LEFT.br_startblock, + LEFT.br_blockcount + new->br_blockcount, + LEFT.br_state); + if (error) + goto done; + } + break; - ASSERT(XFS_IFORK_Q(ip) == 0); - ASSERT(ip->i_df.if_ext_max == - XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t)); + case BMAP_LEFT_FILLING: + /* + * Setting the first part of a previous oldext extent to newext. + * The left neighbor is not contiguous. + */ + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); + ASSERT(ep && xfs_bmbt_get_state(ep) == oldext); + xfs_bmbt_set_startoff(ep, new_endoff); + xfs_bmbt_set_blockcount(ep, + PREV.br_blockcount - new->br_blockcount); + xfs_bmbt_set_startblock(ep, + new->br_startblock + new->br_blockcount); + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); - mp = ip->i_mount; - ASSERT(!XFS_NOT_DQATTACHED(mp, ip)); - tp = xfs_trans_alloc(mp, XFS_TRANS_ADDAFORK); - blks = XFS_ADDAFORK_SPACE_RES(mp); - if (rsvd) - tp->t_flags |= XFS_TRANS_RESERVE; - if ((error = xfs_trans_reserve(tp, blks, XFS_ADDAFORK_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, XFS_ADDAFORK_LOG_COUNT))) - goto error0; - xfs_ilock(ip, XFS_ILOCK_EXCL); - error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ? - XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : - XFS_QMOPT_RES_REGBLKS); - if (error) { - xfs_iunlock(ip, XFS_ILOCK_EXCL); - xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES); - return error; - } - if (XFS_IFORK_Q(ip)) - goto error1; - if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) { + xfs_iext_insert(ip, *idx, 1, new, state); + ip->i_d.di_nextents++; + if (cur == NULL) + rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; + else { + rval = XFS_ILOG_CORE; + if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, + PREV.br_startblock, PREV.br_blockcount, + &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_bmbt_update(cur, + PREV.br_startoff + new->br_blockcount, + PREV.br_startblock + new->br_blockcount, + PREV.br_blockcount - new->br_blockcount, + oldext))) + goto done; + cur->bc_rec.b = *new; + if ((error = xfs_btree_insert(cur, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + } + break; + + case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* - * For inodes coming from pre-6.2 filesystems. + * Setting the last part of a previous oldext extent to newext. + * The right neighbor is contiguous with the new allocation. */ - ASSERT(ip->i_d.di_aformat == 0); - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; - } - ASSERT(ip->i_d.di_anextents == 0); + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); + xfs_bmbt_set_blockcount(ep, + PREV.br_blockcount - new->br_blockcount); + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); - xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL); - xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); + ++*idx; - switch (ip->i_d.di_format) { - case XFS_DINODE_FMT_DEV: - ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; - break; - case XFS_DINODE_FMT_UUID: - ip->i_d.di_forkoff = roundup(sizeof(uuid_t), 8) >> 3; - break; - case XFS_DINODE_FMT_LOCAL: - case XFS_DINODE_FMT_EXTENTS: - case XFS_DINODE_FMT_BTREE: - ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size); - if (!ip->i_d.di_forkoff) - ip->i_d.di_forkoff = xfs_default_attroffset(ip) >> 3; - else if (mp->m_flags & XFS_MOUNT_ATTR2) - version = 2; - break; - default: - ASSERT(0); - error = XFS_ERROR(EINVAL); - goto error1; - } - ip->i_df.if_ext_max = - XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); - ASSERT(ip->i_afp == NULL); - ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP); - ip->i_afp->if_ext_max = - XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); - ip->i_afp->if_flags = XFS_IFEXTENTS; - logflags = 0; - xfs_bmap_init(&flist, &firstblock); - switch (ip->i_d.di_format) { - case XFS_DINODE_FMT_LOCAL: - error = xfs_bmap_add_attrfork_local(tp, ip, &firstblock, &flist, - &logflags); - break; - case XFS_DINODE_FMT_EXTENTS: - error = xfs_bmap_add_attrfork_extents(tp, ip, &firstblock, - &flist, &logflags); - break; - case XFS_DINODE_FMT_BTREE: - error = xfs_bmap_add_attrfork_btree(tp, ip, &firstblock, &flist, - &logflags); - break; - default: - error = 0; - break; - } - if (logflags) - xfs_trans_log_inode(tp, ip, logflags); - if (error) - goto error2; - if (!xfs_sb_version_hasattr(&mp->m_sb) || - (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) { - __int64_t sbfields = 0; + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); + xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx), + new->br_startoff, new->br_startblock, + new->br_blockcount + RIGHT.br_blockcount, newext); + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); - spin_lock(&mp->m_sb_lock); - if (!xfs_sb_version_hasattr(&mp->m_sb)) { - xfs_sb_version_addattr(&mp->m_sb); - sbfields |= XFS_SB_VERSIONNUM; + if (cur == NULL) + rval = XFS_ILOG_DEXT; + else { + rval = 0; + if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, + PREV.br_startblock, + PREV.br_blockcount, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_bmbt_update(cur, PREV.br_startoff, + PREV.br_startblock, + PREV.br_blockcount - new->br_blockcount, + oldext))) + goto done; + if ((error = xfs_btree_increment(cur, 0, &i))) + goto done; + if ((error = xfs_bmbt_update(cur, new->br_startoff, + new->br_startblock, + new->br_blockcount + RIGHT.br_blockcount, + newext))) + goto done; } - if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) { - xfs_sb_version_addattr2(&mp->m_sb); - sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); + break; + + case BMAP_RIGHT_FILLING: + /* + * Setting the last part of a previous oldext extent to newext. + * The right neighbor is not contiguous. + */ + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); + xfs_bmbt_set_blockcount(ep, + PREV.br_blockcount - new->br_blockcount); + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); + + ++*idx; + xfs_iext_insert(ip, *idx, 1, new, state); + + ip->i_d.di_nextents++; + if (cur == NULL) + rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; + else { + rval = XFS_ILOG_CORE; + if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, + PREV.br_startblock, PREV.br_blockcount, + &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_bmbt_update(cur, PREV.br_startoff, + PREV.br_startblock, + PREV.br_blockcount - new->br_blockcount, + oldext))) + goto done; + if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, + new->br_startblock, new->br_blockcount, + &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 0, done); + cur->bc_rec.b.br_state = XFS_EXT_NORM; + if ((error = xfs_btree_insert(cur, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); } - if (sbfields) { - spin_unlock(&mp->m_sb_lock); - xfs_mod_sb(tp, sbfields); - } else - spin_unlock(&mp->m_sb_lock); - } - if ((error = xfs_bmap_finish(&tp, &flist, &committed))) - goto error2; - error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); - ASSERT(ip->i_df.if_ext_max == - XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t)); - return error; -error2: - xfs_bmap_cancel(&flist); -error1: - xfs_iunlock(ip, XFS_ILOCK_EXCL); -error0: - xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); - ASSERT(ip->i_df.if_ext_max == - XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t)); - return error; -} + break; -/* - * Add the extent to the list of extents to be free at transaction end. - * The list is maintained sorted (by block number). - */ -/* ARGSUSED */ -void -xfs_bmap_add_free( - xfs_fsblock_t bno, /* fs block number of extent */ - xfs_filblks_t len, /* length of extent */ - xfs_bmap_free_t *flist, /* list of extents */ - xfs_mount_t *mp) /* mount point structure */ -{ - xfs_bmap_free_item_t *cur; /* current (next) element */ - xfs_bmap_free_item_t *new; /* new element */ - xfs_bmap_free_item_t *prev; /* previous element */ -#ifdef DEBUG - xfs_agnumber_t agno; - xfs_agblock_t agbno; + case 0: + /* + * Setting the middle part of a previous oldext extent to + * newext. Contiguity is impossible here. + * One extent becomes three extents. + */ + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); + xfs_bmbt_set_blockcount(ep, + new->br_startoff - PREV.br_startoff); + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); - ASSERT(bno != NULLFSBLOCK); - ASSERT(len > 0); - ASSERT(len <= MAXEXTLEN); - ASSERT(!isnullstartblock(bno)); - agno = XFS_FSB_TO_AGNO(mp, bno); - agbno = XFS_FSB_TO_AGBNO(mp, bno); - ASSERT(agno < mp->m_sb.sb_agcount); - ASSERT(agbno < mp->m_sb.sb_agblocks); - ASSERT(len < mp->m_sb.sb_agblocks); - ASSERT(agbno + len <= mp->m_sb.sb_agblocks); + r[0] = *new; + r[1].br_startoff = new_endoff; + r[1].br_blockcount = + PREV.br_startoff + PREV.br_blockcount - new_endoff; + r[1].br_startblock = new->br_startblock + new->br_blockcount; + r[1].br_state = oldext; + + ++*idx; + xfs_iext_insert(ip, *idx, 2, &r[0], state); + + ip->i_d.di_nextents += 2; + if (cur == NULL) + rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; + else { + rval = XFS_ILOG_CORE; + if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, + PREV.br_startblock, PREV.br_blockcount, + &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + /* new right extent - oldext */ + if ((error = xfs_bmbt_update(cur, r[1].br_startoff, + r[1].br_startblock, r[1].br_blockcount, + r[1].br_state))) + goto done; + /* new left extent - oldext */ + cur->bc_rec.b = PREV; + cur->bc_rec.b.br_blockcount = + new->br_startoff - PREV.br_startoff; + if ((error = xfs_btree_insert(cur, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + /* + * Reset the cursor to the position of the new extent + * we are about to insert as we can't trust it after + * the previous insert. + */ + if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, + new->br_startblock, new->br_blockcount, + &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 0, done); + /* new middle extent - newext */ + cur->bc_rec.b.br_state = new->br_state; + if ((error = xfs_btree_insert(cur, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + } + break; + + case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: + case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: + case BMAP_LEFT_FILLING | BMAP_RIGHT_CONTIG: + case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: + case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: + case BMAP_LEFT_CONTIG: + case BMAP_RIGHT_CONTIG: + /* + * These cases are all impossible. + */ + ASSERT(0); + } + + /* convert to a btree if necessary */ + if (xfs_bmap_needs_btree(ip, XFS_DATA_FORK)) { + int tmp_logflags; /* partial log flag return val */ + + ASSERT(cur == NULL); + error = xfs_bmap_extents_to_btree(tp, ip, first, flist, &cur, + 0, &tmp_logflags, XFS_DATA_FORK); + *logflagsp |= tmp_logflags; + if (error) + goto done; + } + + /* clear out the allocated field, done with it now in any case. */ + if (cur) { + cur->bc_private.b.allocated = 0; + *curp = cur; + } + + xfs_bmap_check_leaf_extents(*curp, ip, XFS_DATA_FORK); +done: + *logflagsp |= rval; + return error; +#undef LEFT +#undef RIGHT +#undef PREV +} + +/* + * Convert a hole to a delayed allocation. + */ +STATIC void +xfs_bmap_add_extent_hole_delay( + xfs_inode_t *ip, /* incore inode pointer */ + xfs_extnum_t *idx, /* extent number to update/insert */ + xfs_bmbt_irec_t *new) /* new data to add to file extents */ +{ + xfs_ifork_t *ifp; /* inode fork pointer */ + xfs_bmbt_irec_t left; /* left neighbor extent entry */ + xfs_filblks_t newlen=0; /* new indirect size */ + xfs_filblks_t oldlen=0; /* old indirect size */ + xfs_bmbt_irec_t right; /* right neighbor extent entry */ + int state; /* state bits, accessed thru macros */ + xfs_filblks_t temp=0; /* temp for indirect calculations */ + + ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); + state = 0; + ASSERT(isnullstartblock(new->br_startblock)); + + /* + * Check and set flags if this segment has a left neighbor + */ + if (*idx > 0) { + state |= BMAP_LEFT_VALID; + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &left); + + if (isnullstartblock(left.br_startblock)) + state |= BMAP_LEFT_DELAY; + } + + /* + * Check and set flags if the current (right) segment exists. + * If it doesn't exist, we're converting the hole at end-of-file. + */ + if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { + state |= BMAP_RIGHT_VALID; + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx), &right); + + if (isnullstartblock(right.br_startblock)) + state |= BMAP_RIGHT_DELAY; + } + + /* + * Set contiguity flags on the left and right neighbors. + * Don't let extents get too large, even if the pieces are contiguous. + */ + if ((state & BMAP_LEFT_VALID) && (state & BMAP_LEFT_DELAY) && + left.br_startoff + left.br_blockcount == new->br_startoff && + left.br_blockcount + new->br_blockcount <= MAXEXTLEN) + state |= BMAP_LEFT_CONTIG; + + if ((state & BMAP_RIGHT_VALID) && (state & BMAP_RIGHT_DELAY) && + new->br_startoff + new->br_blockcount == right.br_startoff && + new->br_blockcount + right.br_blockcount <= MAXEXTLEN && + (!(state & BMAP_LEFT_CONTIG) || + (left.br_blockcount + new->br_blockcount + + right.br_blockcount <= MAXEXTLEN))) + state |= BMAP_RIGHT_CONTIG; + + /* + * Switch out based on the contiguity flags. + */ + switch (state & (BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG)) { + case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: + /* + * New allocation is contiguous with delayed allocations + * on the left and on the right. + * Merge all three into a single extent record. + */ + --*idx; + temp = left.br_blockcount + new->br_blockcount + + right.br_blockcount; + + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), temp); + oldlen = startblockval(left.br_startblock) + + startblockval(new->br_startblock) + + startblockval(right.br_startblock); + newlen = xfs_bmap_worst_indlen(ip, temp); + xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx), + nullstartblock((int)newlen)); + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); + + xfs_iext_remove(ip, *idx + 1, 1, state); + break; + + case BMAP_LEFT_CONTIG: + /* + * New allocation is contiguous with a delayed allocation + * on the left. + * Merge the new allocation with the left neighbor. + */ + --*idx; + temp = left.br_blockcount + new->br_blockcount; + + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), temp); + oldlen = startblockval(left.br_startblock) + + startblockval(new->br_startblock); + newlen = xfs_bmap_worst_indlen(ip, temp); + xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx), + nullstartblock((int)newlen)); + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); + break; + + case BMAP_RIGHT_CONTIG: + /* + * New allocation is contiguous with a delayed allocation + * on the right. + * Merge the new allocation with the right neighbor. + */ + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); + temp = new->br_blockcount + right.br_blockcount; + oldlen = startblockval(new->br_startblock) + + startblockval(right.br_startblock); + newlen = xfs_bmap_worst_indlen(ip, temp); + xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx), + new->br_startoff, + nullstartblock((int)newlen), temp, right.br_state); + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); + break; + + case 0: + /* + * New allocation is not contiguous with another + * delayed allocation. + * Insert a new entry. + */ + oldlen = newlen = 0; + xfs_iext_insert(ip, *idx, 1, new, state); + break; + } + if (oldlen != newlen) { + ASSERT(oldlen > newlen); + xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, + (int64_t)(oldlen - newlen), 0); + /* + * Nothing to do for disk quota accounting here. + */ + } +} + +/* + * Convert a hole to a real allocation. + */ +STATIC int /* error */ +xfs_bmap_add_extent_hole_real( + struct xfs_bmalloca *bma, + int whichfork) +{ + struct xfs_bmbt_irec *new = &bma->got; + int error; /* error return value */ + int i; /* temp state */ + xfs_ifork_t *ifp; /* inode fork pointer */ + xfs_bmbt_irec_t left; /* left neighbor extent entry */ + xfs_bmbt_irec_t right; /* right neighbor extent entry */ + int rval=0; /* return value (logging flags) */ + int state; /* state bits, accessed thru macros */ + + ifp = XFS_IFORK_PTR(bma->ip, whichfork); + + ASSERT(bma->idx >= 0); + ASSERT(bma->idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec)); + ASSERT(!isnullstartblock(new->br_startblock)); + ASSERT(!bma->cur || + !(bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL)); + + XFS_STATS_INC(xs_add_exlist); + + state = 0; + if (whichfork == XFS_ATTR_FORK) + state |= BMAP_ATTRFORK; + + /* + * Check and set flags if this segment has a left neighbor. + */ + if (bma->idx > 0) { + state |= BMAP_LEFT_VALID; + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx - 1), &left); + if (isnullstartblock(left.br_startblock)) + state |= BMAP_LEFT_DELAY; + } + + /* + * Check and set flags if this segment has a current value. + * Not true if we're inserting into the "hole" at eof. + */ + if (bma->idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { + state |= BMAP_RIGHT_VALID; + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx), &right); + if (isnullstartblock(right.br_startblock)) + state |= BMAP_RIGHT_DELAY; + } + + /* + * We're inserting a real allocation between "left" and "right". + * Set the contiguity flags. Don't let extents get too large. + */ + if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) && + left.br_startoff + left.br_blockcount == new->br_startoff && + left.br_startblock + left.br_blockcount == new->br_startblock && + left.br_state == new->br_state && + left.br_blockcount + new->br_blockcount <= MAXEXTLEN) + state |= BMAP_LEFT_CONTIG; + + if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) && + new->br_startoff + new->br_blockcount == right.br_startoff && + new->br_startblock + new->br_blockcount == right.br_startblock && + new->br_state == right.br_state && + new->br_blockcount + right.br_blockcount <= MAXEXTLEN && + (!(state & BMAP_LEFT_CONTIG) || + left.br_blockcount + new->br_blockcount + + right.br_blockcount <= MAXEXTLEN)) + state |= BMAP_RIGHT_CONTIG; + + error = 0; + /* + * Select which case we're in here, and implement it. + */ + switch (state & (BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG)) { + case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: + /* + * New allocation is contiguous with real allocations on the + * left and on the right. + * Merge all three into a single extent record. + */ + --bma->idx; + trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx), + left.br_blockcount + new->br_blockcount + + right.br_blockcount); + trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); + + xfs_iext_remove(bma->ip, bma->idx + 1, 1, state); + + XFS_IFORK_NEXT_SET(bma->ip, whichfork, + XFS_IFORK_NEXTENTS(bma->ip, whichfork) - 1); + if (bma->cur == NULL) { + rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); + } else { + rval = XFS_ILOG_CORE; + error = xfs_bmbt_lookup_eq(bma->cur, right.br_startoff, + right.br_startblock, right.br_blockcount, + &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + error = xfs_btree_delete(bma->cur, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + error = xfs_btree_decrement(bma->cur, 0, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + error = xfs_bmbt_update(bma->cur, left.br_startoff, + left.br_startblock, + left.br_blockcount + + new->br_blockcount + + right.br_blockcount, + left.br_state); + if (error) + goto done; + } + break; + + case BMAP_LEFT_CONTIG: + /* + * New allocation is contiguous with a real allocation + * on the left. + * Merge the new allocation with the left neighbor. + */ + --bma->idx; + trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx), + left.br_blockcount + new->br_blockcount); + trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); + + if (bma->cur == NULL) { + rval = xfs_ilog_fext(whichfork); + } else { + rval = 0; + error = xfs_bmbt_lookup_eq(bma->cur, left.br_startoff, + left.br_startblock, left.br_blockcount, + &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + error = xfs_bmbt_update(bma->cur, left.br_startoff, + left.br_startblock, + left.br_blockcount + + new->br_blockcount, + left.br_state); + if (error) + goto done; + } + break; + + case BMAP_RIGHT_CONTIG: + /* + * New allocation is contiguous with a real allocation + * on the right. + * Merge the new allocation with the right neighbor. + */ + trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); + xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, bma->idx), + new->br_startoff, new->br_startblock, + new->br_blockcount + right.br_blockcount, + right.br_state); + trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); + + if (bma->cur == NULL) { + rval = xfs_ilog_fext(whichfork); + } else { + rval = 0; + error = xfs_bmbt_lookup_eq(bma->cur, + right.br_startoff, + right.br_startblock, + right.br_blockcount, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + error = xfs_bmbt_update(bma->cur, new->br_startoff, + new->br_startblock, + new->br_blockcount + + right.br_blockcount, + right.br_state); + if (error) + goto done; + } + break; + + case 0: + /* + * New allocation is not contiguous with another + * real allocation. + * Insert a new entry. + */ + xfs_iext_insert(bma->ip, bma->idx, 1, new, state); + XFS_IFORK_NEXT_SET(bma->ip, whichfork, + XFS_IFORK_NEXTENTS(bma->ip, whichfork) + 1); + if (bma->cur == NULL) { + rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); + } else { + rval = XFS_ILOG_CORE; + error = xfs_bmbt_lookup_eq(bma->cur, + new->br_startoff, + new->br_startblock, + new->br_blockcount, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 0, done); + bma->cur->bc_rec.b.br_state = new->br_state; + error = xfs_btree_insert(bma->cur, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + } + break; + } + + /* convert to a btree if necessary */ + if (xfs_bmap_needs_btree(bma->ip, whichfork)) { + int tmp_logflags; /* partial log flag return val */ + + ASSERT(bma->cur == NULL); + error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, + bma->firstblock, bma->flist, &bma->cur, + 0, &tmp_logflags, whichfork); + bma->logflags |= tmp_logflags; + if (error) + goto done; + } + + /* clear out the allocated field, done with it now in any case. */ + if (bma->cur) + bma->cur->bc_private.b.allocated = 0; + + xfs_bmap_check_leaf_extents(bma->cur, bma->ip, whichfork); +done: + bma->logflags |= rval; + return error; +} + +/* + * Functions used in the extent read, allocate and remove paths + */ + +/* + * Adjust the size of the new extent based on di_extsize and rt extsize. + */ +int +xfs_bmap_extsize_align( + xfs_mount_t *mp, + xfs_bmbt_irec_t *gotp, /* next extent pointer */ + xfs_bmbt_irec_t *prevp, /* previous extent pointer */ + xfs_extlen_t extsz, /* align to this extent size */ + int rt, /* is this a realtime inode? */ + int eof, /* is extent at end-of-file? */ + int delay, /* creating delalloc extent? */ + int convert, /* overwriting unwritten extent? */ + xfs_fileoff_t *offp, /* in/out: aligned offset */ + xfs_extlen_t *lenp) /* in/out: aligned length */ +{ + xfs_fileoff_t orig_off; /* original offset */ + xfs_extlen_t orig_alen; /* original length */ + xfs_fileoff_t orig_end; /* original off+len */ + xfs_fileoff_t nexto; /* next file offset */ + xfs_fileoff_t prevo; /* previous file offset */ + xfs_fileoff_t align_off; /* temp for offset */ + xfs_extlen_t align_alen; /* temp for length */ + xfs_extlen_t temp; /* temp for calculations */ + + if (convert) + return 0; + + orig_off = align_off = *offp; + orig_alen = align_alen = *lenp; + orig_end = orig_off + orig_alen; + + /* + * If this request overlaps an existing extent, then don't + * attempt to perform any additional alignment. + */ + if (!delay && !eof && + (orig_off >= gotp->br_startoff) && + (orig_end <= gotp->br_startoff + gotp->br_blockcount)) { + return 0; + } + + /* + * If the file offset is unaligned vs. the extent size + * we need to align it. This will be possible unless + * the file was previously written with a kernel that didn't + * perform this alignment, or if a truncate shot us in the + * foot. + */ + temp = do_mod(orig_off, extsz); + if (temp) { + align_alen += temp; + align_off -= temp; + } + /* + * Same adjustment for the end of the requested area. + */ + if ((temp = (align_alen % extsz))) { + align_alen += extsz - temp; + } + /* + * If the previous block overlaps with this proposed allocation + * then move the start forward without adjusting the length. + */ + if (prevp->br_startoff != NULLFILEOFF) { + if (prevp->br_startblock == HOLESTARTBLOCK) + prevo = prevp->br_startoff; + else + prevo = prevp->br_startoff + prevp->br_blockcount; + } else + prevo = 0; + if (align_off != orig_off && align_off < prevo) + align_off = prevo; + /* + * If the next block overlaps with this proposed allocation + * then move the start back without adjusting the length, + * but not before offset 0. + * This may of course make the start overlap previous block, + * and if we hit the offset 0 limit then the next block + * can still overlap too. + */ + if (!eof && gotp->br_startoff != NULLFILEOFF) { + if ((delay && gotp->br_startblock == HOLESTARTBLOCK) || + (!delay && gotp->br_startblock == DELAYSTARTBLOCK)) + nexto = gotp->br_startoff + gotp->br_blockcount; + else + nexto = gotp->br_startoff; + } else + nexto = NULLFILEOFF; + if (!eof && + align_off + align_alen != orig_end && + align_off + align_alen > nexto) + align_off = nexto > align_alen ? nexto - align_alen : 0; + /* + * If we're now overlapping the next or previous extent that + * means we can't fit an extsz piece in this hole. Just move + * the start forward to the first valid spot and set + * the length so we hit the end. + */ + if (align_off != orig_off && align_off < prevo) + align_off = prevo; + if (align_off + align_alen != orig_end && + align_off + align_alen > nexto && + nexto != NULLFILEOFF) { + ASSERT(nexto > prevo); + align_alen = nexto - align_off; + } + + /* + * If realtime, and the result isn't a multiple of the realtime + * extent size we need to remove blocks until it is. + */ + if (rt && (temp = (align_alen % mp->m_sb.sb_rextsize))) { + /* + * We're not covering the original request, or + * we won't be able to once we fix the length. + */ + if (orig_off < align_off || + orig_end > align_off + align_alen || + align_alen - temp < orig_alen) + return XFS_ERROR(EINVAL); + /* + * Try to fix it by moving the start up. + */ + if (align_off + temp <= orig_off) { + align_alen -= temp; + align_off += temp; + } + /* + * Try to fix it by moving the end in. + */ + else if (align_off + align_alen - temp >= orig_end) + align_alen -= temp; + /* + * Set the start to the minimum then trim the length. + */ + else { + align_alen -= orig_off - align_off; + align_off = orig_off; + align_alen -= align_alen % mp->m_sb.sb_rextsize; + } + /* + * Result doesn't cover the request, fail it. + */ + if (orig_off < align_off || orig_end > align_off + align_alen) + return XFS_ERROR(EINVAL); + } else { + ASSERT(orig_off >= align_off); + ASSERT(orig_end <= align_off + align_alen); + } + +#ifdef DEBUG + if (!eof && gotp->br_startoff != NULLFILEOFF) + ASSERT(align_off + align_alen <= gotp->br_startoff); + if (prevp->br_startoff != NULLFILEOFF) + ASSERT(align_off >= prevp->br_startoff + prevp->br_blockcount); #endif - ASSERT(xfs_bmap_free_item_zone != NULL); - new = kmem_zone_alloc(xfs_bmap_free_item_zone, KM_SLEEP); - new->xbfi_startblock = bno; - new->xbfi_blockcount = (xfs_extlen_t)len; - for (prev = NULL, cur = flist->xbf_first; - cur != NULL; - prev = cur, cur = cur->xbfi_next) { - if (cur->xbfi_startblock >= bno) + + *lenp = align_alen; + *offp = align_off; + return 0; +} + +#define XFS_ALLOC_GAP_UNITS 4 + +void +xfs_bmap_adjacent( + struct xfs_bmalloca *ap) /* bmap alloc argument struct */ +{ + xfs_fsblock_t adjust; /* adjustment to block numbers */ + xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ + xfs_mount_t *mp; /* mount point structure */ + int nullfb; /* true if ap->firstblock isn't set */ + int rt; /* true if inode is realtime */ + +#define ISVALID(x,y) \ + (rt ? \ + (x) < mp->m_sb.sb_rblocks : \ + XFS_FSB_TO_AGNO(mp, x) == XFS_FSB_TO_AGNO(mp, y) && \ + XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \ + XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks) + + mp = ap->ip->i_mount; + nullfb = *ap->firstblock == NULLFSBLOCK; + rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata; + fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock); + /* + * If allocating at eof, and there's a previous real block, + * try to use its last block as our starting point. + */ + if (ap->eof && ap->prev.br_startoff != NULLFILEOFF && + !isnullstartblock(ap->prev.br_startblock) && + ISVALID(ap->prev.br_startblock + ap->prev.br_blockcount, + ap->prev.br_startblock)) { + ap->blkno = ap->prev.br_startblock + ap->prev.br_blockcount; + /* + * Adjust for the gap between prevp and us. + */ + adjust = ap->offset - + (ap->prev.br_startoff + ap->prev.br_blockcount); + if (adjust && + ISVALID(ap->blkno + adjust, ap->prev.br_startblock)) + ap->blkno += adjust; + } + /* + * If not at eof, then compare the two neighbor blocks. + * Figure out whether either one gives us a good starting point, + * and pick the better one. + */ + else if (!ap->eof) { + xfs_fsblock_t gotbno; /* right side block number */ + xfs_fsblock_t gotdiff=0; /* right side difference */ + xfs_fsblock_t prevbno; /* left side block number */ + xfs_fsblock_t prevdiff=0; /* left side difference */ + + /* + * If there's a previous (left) block, select a requested + * start block based on it. + */ + if (ap->prev.br_startoff != NULLFILEOFF && + !isnullstartblock(ap->prev.br_startblock) && + (prevbno = ap->prev.br_startblock + + ap->prev.br_blockcount) && + ISVALID(prevbno, ap->prev.br_startblock)) { + /* + * Calculate gap to end of previous block. + */ + adjust = prevdiff = ap->offset - + (ap->prev.br_startoff + + ap->prev.br_blockcount); + /* + * Figure the startblock based on the previous block's + * end and the gap size. + * Heuristic! + * If the gap is large relative to the piece we're + * allocating, or using it gives us an invalid block + * number, then just use the end of the previous block. + */ + if (prevdiff <= XFS_ALLOC_GAP_UNITS * ap->length && + ISVALID(prevbno + prevdiff, + ap->prev.br_startblock)) + prevbno += adjust; + else + prevdiff += adjust; + /* + * If the firstblock forbids it, can't use it, + * must use default. + */ + if (!rt && !nullfb && + XFS_FSB_TO_AGNO(mp, prevbno) != fb_agno) + prevbno = NULLFSBLOCK; + } + /* + * No previous block or can't follow it, just default. + */ + else + prevbno = NULLFSBLOCK; + /* + * If there's a following (right) block, select a requested + * start block based on it. + */ + if (!isnullstartblock(ap->got.br_startblock)) { + /* + * Calculate gap to start of next block. + */ + adjust = gotdiff = ap->got.br_startoff - ap->offset; + /* + * Figure the startblock based on the next block's + * start and the gap size. + */ + gotbno = ap->got.br_startblock; + /* + * Heuristic! + * If the gap is large relative to the piece we're + * allocating, or using it gives us an invalid block + * number, then just use the start of the next block + * offset by our length. + */ + if (gotdiff <= XFS_ALLOC_GAP_UNITS * ap->length && + ISVALID(gotbno - gotdiff, gotbno)) + gotbno -= adjust; + else if (ISVALID(gotbno - ap->length, gotbno)) { + gotbno -= ap->length; + gotdiff += adjust - ap->length; + } else + gotdiff += adjust; + /* + * If the firstblock forbids it, can't use it, + * must use default. + */ + if (!rt && !nullfb && + XFS_FSB_TO_AGNO(mp, gotbno) != fb_agno) + gotbno = NULLFSBLOCK; + } + /* + * No next block, just default. + */ + else + gotbno = NULLFSBLOCK; + /* + * If both valid, pick the better one, else the only good + * one, else ap->blkno is already set (to 0 or the inode block). + */ + if (prevbno != NULLFSBLOCK && gotbno != NULLFSBLOCK) + ap->blkno = prevdiff <= gotdiff ? prevbno : gotbno; + else if (prevbno != NULLFSBLOCK) + ap->blkno = prevbno; + else if (gotbno != NULLFSBLOCK) + ap->blkno = gotbno; + } +#undef ISVALID +} + +STATIC int +xfs_bmap_btalloc_nullfb( + struct xfs_bmalloca *ap, + struct xfs_alloc_arg *args, + xfs_extlen_t *blen) +{ + struct xfs_mount *mp = ap->ip->i_mount; + struct xfs_perag *pag; + xfs_agnumber_t ag, startag; + int notinit = 0; + int error; + + if (ap->userdata && xfs_inode_is_filestream(ap->ip)) + args->type = XFS_ALLOCTYPE_NEAR_BNO; + else + args->type = XFS_ALLOCTYPE_START_BNO; + args->total = ap->total; + + /* + * Search for an allocation group with a single extent large enough + * for the request. If one isn't found, then adjust the minimum + * allocation size to the largest space found. + */ + startag = ag = XFS_FSB_TO_AGNO(mp, args->fsbno); + if (startag == NULLAGNUMBER) + startag = ag = 0; + + pag = xfs_perag_get(mp, ag); + while (*blen < args->maxlen) { + if (!pag->pagf_init) { + error = xfs_alloc_pagf_init(mp, args->tp, ag, + XFS_ALLOC_FLAG_TRYLOCK); + if (error) { + xfs_perag_put(pag); + return error; + } + } + + /* + * See xfs_alloc_fix_freelist... + */ + if (pag->pagf_init) { + xfs_extlen_t longest; + longest = xfs_alloc_longest_free_extent(mp, pag); + if (*blen < longest) + *blen = longest; + } else + notinit = 1; + + if (xfs_inode_is_filestream(ap->ip)) { + if (*blen >= args->maxlen) + break; + + if (ap->userdata) { + /* + * If startag is an invalid AG, we've + * come here once before and + * xfs_filestream_new_ag picked the + * best currently available. + * + * Don't continue looping, since we + * could loop forever. + */ + if (startag == NULLAGNUMBER) + break; + + error = xfs_filestream_new_ag(ap, &ag); + xfs_perag_put(pag); + if (error) + return error; + + /* loop again to set 'blen'*/ + startag = NULLAGNUMBER; + pag = xfs_perag_get(mp, ag); + continue; + } + } + if (++ag == mp->m_sb.sb_agcount) + ag = 0; + if (ag == startag) break; + xfs_perag_put(pag); + pag = xfs_perag_get(mp, ag); + } + xfs_perag_put(pag); + + /* + * Since the above loop did a BUF_TRYLOCK, it is + * possible that there is space for this request. + */ + if (notinit || *blen < ap->minlen) + args->minlen = ap->minlen; + /* + * If the best seen length is less than the request + * length, use the best as the minimum. + */ + else if (*blen < args->maxlen) + args->minlen = *blen; + /* + * Otherwise we've seen an extent as big as maxlen, + * use that as the minimum. + */ + else + args->minlen = args->maxlen; + + /* + * set the failure fallback case to look in the selected + * AG as the stream may have moved. + */ + if (xfs_inode_is_filestream(ap->ip)) + ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, ag, 0); + + return 0; +} + +STATIC int +xfs_bmap_btalloc( + struct xfs_bmalloca *ap) /* bmap alloc argument struct */ +{ + xfs_mount_t *mp; /* mount point structure */ + xfs_alloctype_t atype = 0; /* type for allocation routines */ + xfs_extlen_t align; /* minimum allocation alignment */ + xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ + xfs_agnumber_t ag; + xfs_alloc_arg_t args; + xfs_extlen_t blen; + xfs_extlen_t nextminlen = 0; + int nullfb; /* true if ap->firstblock isn't set */ + int isaligned; + int tryagain; + int error; + + ASSERT(ap->length); + + mp = ap->ip->i_mount; + align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0; + if (unlikely(align)) { + error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, + align, 0, ap->eof, 0, ap->conv, + &ap->offset, &ap->length); + ASSERT(!error); + ASSERT(ap->length); + } + nullfb = *ap->firstblock == NULLFSBLOCK; + fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock); + if (nullfb) { + if (ap->userdata && xfs_inode_is_filestream(ap->ip)) { + ag = xfs_filestream_lookup_ag(ap->ip); + ag = (ag != NULLAGNUMBER) ? ag : 0; + ap->blkno = XFS_AGB_TO_FSB(mp, ag, 0); + } else { + ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino); + } + } else + ap->blkno = *ap->firstblock; + + xfs_bmap_adjacent(ap); + + /* + * If allowed, use ap->blkno; otherwise must use firstblock since + * it's in the right allocation group. + */ + if (nullfb || XFS_FSB_TO_AGNO(mp, ap->blkno) == fb_agno) + ; + else + ap->blkno = *ap->firstblock; + /* + * Normal allocation, done through xfs_alloc_vextent. + */ + tryagain = isaligned = 0; + memset(&args, 0, sizeof(args)); + args.tp = ap->tp; + args.mp = mp; + args.fsbno = ap->blkno; + + /* Trim the allocation back to the maximum an AG can fit. */ + args.maxlen = MIN(ap->length, XFS_ALLOC_AG_MAX_USABLE(mp)); + args.firstblock = *ap->firstblock; + blen = 0; + if (nullfb) { + error = xfs_bmap_btalloc_nullfb(ap, &args, &blen); + if (error) + return error; + } else if (ap->flist->xbf_low) { + if (xfs_inode_is_filestream(ap->ip)) + args.type = XFS_ALLOCTYPE_FIRST_AG; + else + args.type = XFS_ALLOCTYPE_START_BNO; + args.total = args.minlen = ap->minlen; + } else { + args.type = XFS_ALLOCTYPE_NEAR_BNO; + args.total = ap->total; + args.minlen = ap->minlen; + } + /* apply extent size hints if obtained earlier */ + if (unlikely(align)) { + args.prod = align; + if ((args.mod = (xfs_extlen_t)do_mod(ap->offset, args.prod))) + args.mod = (xfs_extlen_t)(args.prod - args.mod); + } else if (mp->m_sb.sb_blocksize >= PAGE_CACHE_SIZE) { + args.prod = 1; + args.mod = 0; + } else { + args.prod = PAGE_CACHE_SIZE >> mp->m_sb.sb_blocklog; + if ((args.mod = (xfs_extlen_t)(do_mod(ap->offset, args.prod)))) + args.mod = (xfs_extlen_t)(args.prod - args.mod); + } + /* + * If we are not low on available data blocks, and the + * underlying logical volume manager is a stripe, and + * the file offset is zero then try to allocate data + * blocks on stripe unit boundary. + * NOTE: ap->aeof is only set if the allocation length + * is >= the stripe unit and the allocation offset is + * at the end of file. + */ + if (!ap->flist->xbf_low && ap->aeof) { + if (!ap->offset) { + args.alignment = mp->m_dalign; + atype = args.type; + isaligned = 1; + /* + * Adjust for alignment + */ + if (blen > args.alignment && blen <= args.maxlen) + args.minlen = blen - args.alignment; + args.minalignslop = 0; + } else { + /* + * First try an exact bno allocation. + * If it fails then do a near or start bno + * allocation with alignment turned on. + */ + atype = args.type; + tryagain = 1; + args.type = XFS_ALLOCTYPE_THIS_BNO; + args.alignment = 1; + /* + * Compute the minlen+alignment for the + * next case. Set slop so that the value + * of minlen+alignment+slop doesn't go up + * between the calls. + */ + if (blen > mp->m_dalign && blen <= args.maxlen) + nextminlen = blen - mp->m_dalign; + else + nextminlen = args.minlen; + if (nextminlen + mp->m_dalign > args.minlen + 1) + args.minalignslop = + nextminlen + mp->m_dalign - + args.minlen - 1; + else + args.minalignslop = 0; + } + } else { + args.alignment = 1; + args.minalignslop = 0; + } + args.minleft = ap->minleft; + args.wasdel = ap->wasdel; + args.isfl = 0; + args.userdata = ap->userdata; + if ((error = xfs_alloc_vextent(&args))) + return error; + if (tryagain && args.fsbno == NULLFSBLOCK) { + /* + * Exact allocation failed. Now try with alignment + * turned on. + */ + args.type = atype; + args.fsbno = ap->blkno; + args.alignment = mp->m_dalign; + args.minlen = nextminlen; + args.minalignslop = 0; + isaligned = 1; + if ((error = xfs_alloc_vextent(&args))) + return error; + } + if (isaligned && args.fsbno == NULLFSBLOCK) { + /* + * allocation failed, so turn off alignment and + * try again. + */ + args.type = atype; + args.fsbno = ap->blkno; + args.alignment = 0; + if ((error = xfs_alloc_vextent(&args))) + return error; + } + if (args.fsbno == NULLFSBLOCK && nullfb && + args.minlen > ap->minlen) { + args.minlen = ap->minlen; + args.type = XFS_ALLOCTYPE_START_BNO; + args.fsbno = ap->blkno; + if ((error = xfs_alloc_vextent(&args))) + return error; } - if (prev) - prev->xbfi_next = new; - else - flist->xbf_first = new; - new->xbfi_next = cur; - flist->xbf_count++; + if (args.fsbno == NULLFSBLOCK && nullfb) { + args.fsbno = 0; + args.type = XFS_ALLOCTYPE_FIRST_AG; + args.total = ap->minlen; + args.minleft = 0; + if ((error = xfs_alloc_vextent(&args))) + return error; + ap->flist->xbf_low = 1; + } + if (args.fsbno != NULLFSBLOCK) { + /* + * check the allocation happened at the same or higher AG than + * the first block that was allocated. + */ + ASSERT(*ap->firstblock == NULLFSBLOCK || + XFS_FSB_TO_AGNO(mp, *ap->firstblock) == + XFS_FSB_TO_AGNO(mp, args.fsbno) || + (ap->flist->xbf_low && + XFS_FSB_TO_AGNO(mp, *ap->firstblock) < + XFS_FSB_TO_AGNO(mp, args.fsbno))); + + ap->blkno = args.fsbno; + if (*ap->firstblock == NULLFSBLOCK) + *ap->firstblock = args.fsbno; + ASSERT(nullfb || fb_agno == args.agno || + (ap->flist->xbf_low && fb_agno < args.agno)); + ap->length = args.len; + ap->ip->i_d.di_nblocks += args.len; + xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); + if (ap->wasdel) + ap->ip->i_delayed_blks -= args.len; + /* + * Adjust the disk quota also. This was reserved + * earlier. + */ + xfs_trans_mod_dquot_byino(ap->tp, ap->ip, + ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT : + XFS_TRANS_DQ_BCOUNT, + (long) args.len); + } else { + ap->blkno = NULLFSBLOCK; + ap->length = 0; + } + return 0; } /* - * Compute and fill in the value of the maximum depth of a bmap btree - * in this filesystem. Done once, during mount. + * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. + * It figures out where to ask the underlying allocator to put the new extent. */ -void -xfs_bmap_compute_maxlevels( - xfs_mount_t *mp, /* file system mount structure */ - int whichfork) /* data or attr fork */ +STATIC int +xfs_bmap_alloc( + struct xfs_bmalloca *ap) /* bmap alloc argument struct */ { - int level; /* btree level */ - uint maxblocks; /* max blocks at this level */ - uint maxleafents; /* max leaf entries possible */ - int maxrootrecs; /* max records in root block */ - int minleafrecs; /* min records in leaf block */ - int minnoderecs; /* min records in node block */ - int sz; /* root block size */ - - /* - * The maximum number of extents in a file, hence the maximum - * number of leaf entries, is controlled by the type of di_nextents - * (a signed 32-bit number, xfs_extnum_t), or by di_anextents - * (a signed 16-bit number, xfs_aextnum_t). - * - * Note that we can no longer assume that if we are in ATTR1 that - * the fork offset of all the inodes will be - * (xfs_default_attroffset(ip) >> 3) because we could have mounted - * with ATTR2 and then mounted back with ATTR1, keeping the - * di_forkoff's fixed but probably at various positions. Therefore, - * for both ATTR1 and ATTR2 we have to assume the worst case scenario - * of a minimum size available. - */ - if (whichfork == XFS_DATA_FORK) { - maxleafents = MAXEXTNUM; - sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS); - } else { - maxleafents = MAXAEXTNUM; - sz = XFS_BMDR_SPACE_CALC(MINABTPTRS); - } - maxrootrecs = xfs_bmdr_maxrecs(mp, sz, 0); - minleafrecs = mp->m_bmap_dmnr[0]; - minnoderecs = mp->m_bmap_dmnr[1]; - maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs; - for (level = 1; maxblocks > 1; level++) { - if (maxblocks <= maxrootrecs) - maxblocks = 1; - else - maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs; - } - mp->m_bm_maxlevels[whichfork] = level; + if (XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata) + return xfs_bmap_rtalloc(ap); + return xfs_bmap_btalloc(ap); } /* - * Free up any items left in the list. + * Trim the returned map to the required bounds */ -void -xfs_bmap_cancel( - xfs_bmap_free_t *flist) /* list of bmap_free_items */ -{ - xfs_bmap_free_item_t *free; /* free list item */ - xfs_bmap_free_item_t *next; - - if (flist->xbf_count == 0) +STATIC void +xfs_bmapi_trim_map( + struct xfs_bmbt_irec *mval, + struct xfs_bmbt_irec *got, + xfs_fileoff_t *bno, + xfs_filblks_t len, + xfs_fileoff_t obno, + xfs_fileoff_t end, + int n, + int flags) +{ + if ((flags & XFS_BMAPI_ENTIRE) || + got->br_startoff + got->br_blockcount <= obno) { + *mval = *got; + if (isnullstartblock(got->br_startblock)) + mval->br_startblock = DELAYSTARTBLOCK; return; - ASSERT(flist->xbf_first != NULL); - for (free = flist->xbf_first; free; free = next) { - next = free->xbfi_next; - xfs_bmap_del_free(flist, NULL, free); } - ASSERT(flist->xbf_count == 0); + + if (obno > *bno) + *bno = obno; + ASSERT((*bno >= obno) || (n == 0)); + ASSERT(*bno < end); + mval->br_startoff = *bno; + if (isnullstartblock(got->br_startblock)) + mval->br_startblock = DELAYSTARTBLOCK; + else + mval->br_startblock = got->br_startblock + + (*bno - got->br_startoff); + /* + * Return the minimum of what we got and what we asked for for + * the length. We can use the len variable here because it is + * modified below and we could have been there before coming + * here if the first part of the allocation didn't overlap what + * was asked for. + */ + mval->br_blockcount = XFS_FILBLKS_MIN(end - *bno, + got->br_blockcount - (*bno - got->br_startoff)); + mval->br_state = got->br_state; + ASSERT(mval->br_blockcount <= len); + return; } /* - * Returns the file-relative block number of the first unused block(s) - * in the file with at least "len" logically contiguous blocks free. - * This is the lowest-address hole if the file has holes, else the first block - * past the end of file. - * Return 0 if the file is currently local (in-inode). + * Update and validate the extent map to return */ -int /* error */ -xfs_bmap_first_unused( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode */ - xfs_extlen_t len, /* size of hole to find */ - xfs_fileoff_t *first_unused, /* unused block */ - int whichfork) /* data or attr fork */ +STATIC void +xfs_bmapi_update_map( + struct xfs_bmbt_irec **map, + xfs_fileoff_t *bno, + xfs_filblks_t *len, + xfs_fileoff_t obno, + xfs_fileoff_t end, + int *n, + int flags) +{ + xfs_bmbt_irec_t *mval = *map; + + ASSERT((flags & XFS_BMAPI_ENTIRE) || + ((mval->br_startoff + mval->br_blockcount) <= end)); + ASSERT((flags & XFS_BMAPI_ENTIRE) || (mval->br_blockcount <= *len) || + (mval->br_startoff < obno)); + + *bno = mval->br_startoff + mval->br_blockcount; + *len = end - *bno; + if (*n > 0 && mval->br_startoff == mval[-1].br_startoff) { + /* update previous map with new information */ + ASSERT(mval->br_startblock == mval[-1].br_startblock); + ASSERT(mval->br_blockcount > mval[-1].br_blockcount); + ASSERT(mval->br_state == mval[-1].br_state); + mval[-1].br_blockcount = mval->br_blockcount; + mval[-1].br_state = mval->br_state; + } else if (*n > 0 && mval->br_startblock != DELAYSTARTBLOCK && + mval[-1].br_startblock != DELAYSTARTBLOCK && + mval[-1].br_startblock != HOLESTARTBLOCK && + mval->br_startblock == mval[-1].br_startblock + + mval[-1].br_blockcount && + ((flags & XFS_BMAPI_IGSTATE) || + mval[-1].br_state == mval->br_state)) { + ASSERT(mval->br_startoff == + mval[-1].br_startoff + mval[-1].br_blockcount); + mval[-1].br_blockcount += mval->br_blockcount; + } else if (*n > 0 && + mval->br_startblock == DELAYSTARTBLOCK && + mval[-1].br_startblock == DELAYSTARTBLOCK && + mval->br_startoff == + mval[-1].br_startoff + mval[-1].br_blockcount) { + mval[-1].br_blockcount += mval->br_blockcount; + mval[-1].br_state = mval->br_state; + } else if (!((*n == 0) && + ((mval->br_startoff + mval->br_blockcount) <= + obno))) { + mval++; + (*n)++; + } + *map = mval; +} + +/* + * Map file blocks to filesystem blocks without allocation. + */ +int +xfs_bmapi_read( + struct xfs_inode *ip, + xfs_fileoff_t bno, + xfs_filblks_t len, + struct xfs_bmbt_irec *mval, + int *nmap, + int flags) { - int error; /* error return value */ - int idx; /* extent record index */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_fileoff_t lastaddr; /* last block number seen */ - xfs_fileoff_t lowest; /* lowest useful block */ - xfs_fileoff_t max; /* starting useful block */ - xfs_fileoff_t off; /* offset for this block */ - xfs_extnum_t nextents; /* number of extent entries */ + struct xfs_mount *mp = ip->i_mount; + struct xfs_ifork *ifp; + struct xfs_bmbt_irec got; + struct xfs_bmbt_irec prev; + xfs_fileoff_t obno; + xfs_fileoff_t end; + xfs_extnum_t lastx; + int error; + int eof; + int n = 0; + int whichfork = (flags & XFS_BMAPI_ATTRFORK) ? + XFS_ATTR_FORK : XFS_DATA_FORK; - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE || - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS || - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { - *first_unused = 0; - return 0; + ASSERT(*nmap >= 1); + ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK|XFS_BMAPI_ENTIRE| + XFS_BMAPI_IGSTATE))); + + if (unlikely(XFS_TEST_ERROR( + (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && + XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), + mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) { + XFS_ERROR_REPORT("xfs_bmapi_read", XFS_ERRLEVEL_LOW, mp); + return XFS_ERROR(EFSCORRUPTED); } + + if (XFS_FORCED_SHUTDOWN(mp)) + return XFS_ERROR(EIO); + + XFS_STATS_INC(xs_blk_mapr); + ifp = XFS_IFORK_PTR(ip, whichfork); - if (!(ifp->if_flags & XFS_IFEXTENTS) && - (error = xfs_iread_extents(tp, ip, whichfork))) - return error; - lowest = *first_unused; - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) { - xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx); - off = xfs_bmbt_get_startoff(ep); - /* - * See if the hole before this extent will work. - */ - if (off >= lowest + len && off - max >= len) { - *first_unused = max; - return 0; + + if (!(ifp->if_flags & XFS_IFEXTENTS)) { + error = xfs_iread_extents(NULL, ip, whichfork); + if (error) + return error; + } + + xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev); + end = bno + len; + obno = bno; + + while (bno < end && n < *nmap) { + /* Reading past eof, act as though there's a hole up to end. */ + if (eof) + got.br_startoff = end; + if (got.br_startoff > bno) { + /* Reading in a hole. */ + mval->br_startoff = bno; + mval->br_startblock = HOLESTARTBLOCK; + mval->br_blockcount = + XFS_FILBLKS_MIN(len, got.br_startoff - bno); + mval->br_state = XFS_EXT_NORM; + bno += mval->br_blockcount; + len -= mval->br_blockcount; + mval++; + n++; + continue; } - lastaddr = off + xfs_bmbt_get_blockcount(ep); - max = XFS_FILEOFF_MAX(lastaddr, lowest); + + /* set up the extent map to return. */ + xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags); + xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags); + + /* If we're done, stop now. */ + if (bno >= end || n >= *nmap) + break; + + /* Else go on to the next record. */ + if (++lastx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)) + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx), &got); + else + eof = 1; } - *first_unused = max; + *nmap = n; return 0; } -/* - * Returns the file-relative block number of the last block + 1 before - * last_block (input value) in the file. - * This is not based on i_size, it is based on the extent records. - * Returns 0 for local files, as they do not have extent records. - */ -int /* error */ -xfs_bmap_last_before( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode */ - xfs_fileoff_t *last_block, /* last block */ - int whichfork) /* data or attr fork */ +STATIC int +xfs_bmapi_reserve_delalloc( + struct xfs_inode *ip, + xfs_fileoff_t aoff, + xfs_filblks_t len, + struct xfs_bmbt_irec *got, + struct xfs_bmbt_irec *prev, + xfs_extnum_t *lastx, + int eof) { - xfs_fileoff_t bno; /* input file offset */ - int eof; /* hit end of file */ - xfs_bmbt_rec_host_t *ep; /* pointer to last extent */ - int error; /* error return value */ - xfs_bmbt_irec_t got; /* current extent value */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_extnum_t lastx; /* last extent used */ - xfs_bmbt_irec_t prev; /* previous extent value */ + struct xfs_mount *mp = ip->i_mount; + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); + xfs_extlen_t alen; + xfs_extlen_t indlen; + char rt = XFS_IS_REALTIME_INODE(ip); + xfs_extlen_t extsz; + int error; - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) - return XFS_ERROR(EIO); - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { - *last_block = 0; - return 0; + alen = XFS_FILBLKS_MIN(len, MAXEXTLEN); + if (!eof) + alen = XFS_FILBLKS_MIN(alen, got->br_startoff - aoff); + + /* Figure out the extent size, adjust alen */ + extsz = xfs_get_extsz_hint(ip); + if (extsz) { + /* + * Make sure we don't exceed a single extent length when we + * align the extent by reducing length we are going to + * allocate by the maximum amount extent size aligment may + * require. + */ + alen = XFS_FILBLKS_MIN(len, MAXEXTLEN - (2 * extsz - 1)); + error = xfs_bmap_extsize_align(mp, got, prev, extsz, rt, eof, + 1, 0, &aoff, &alen); + ASSERT(!error); } - ifp = XFS_IFORK_PTR(ip, whichfork); - if (!(ifp->if_flags & XFS_IFEXTENTS) && - (error = xfs_iread_extents(tp, ip, whichfork))) + + if (rt) + extsz = alen / mp->m_sb.sb_rextsize; + + /* + * Make a transaction-less quota reservation for delayed allocation + * blocks. This number gets adjusted later. We return if we haven't + * allocated blocks already inside this loop. + */ + error = xfs_trans_reserve_quota_nblks(NULL, ip, (long)alen, 0, + rt ? XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS); + if (error) return error; - bno = *last_block - 1; - ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, - &prev); - if (eof || xfs_bmbt_get_startoff(ep) > bno) { - if (prev.br_startoff == NULLFILEOFF) - *last_block = 0; - else - *last_block = prev.br_startoff + prev.br_blockcount; + + /* + * Split changing sb for alen and indlen since they could be coming + * from different places. + */ + indlen = (xfs_extlen_t)xfs_bmap_worst_indlen(ip, alen); + ASSERT(indlen > 0); + + if (rt) { + error = xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, + -((int64_t)extsz), 0); + } else { + error = xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, + -((int64_t)alen), 0); } + + if (error) + goto out_unreserve_quota; + + error = xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, + -((int64_t)indlen), 0); + if (error) + goto out_unreserve_blocks; + + + ip->i_delayed_blks += alen; + + got->br_startoff = aoff; + got->br_startblock = nullstartblock(indlen); + got->br_blockcount = alen; + got->br_state = XFS_EXT_NORM; + xfs_bmap_add_extent_hole_delay(ip, lastx, got); + /* - * Otherwise *last_block is already the right answer. + * Update our extent pointer, given that xfs_bmap_add_extent_hole_delay + * might have merged it into one of the neighbouring ones. */ + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *lastx), got); + + ASSERT(got->br_startoff <= aoff); + ASSERT(got->br_startoff + got->br_blockcount >= aoff + alen); + ASSERT(isnullstartblock(got->br_startblock)); + ASSERT(got->br_state == XFS_EXT_NORM); return 0; + +out_unreserve_blocks: + if (rt) + xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, extsz, 0); + else + xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, alen, 0); +out_unreserve_quota: + if (XFS_IS_QUOTA_ON(mp)) + xfs_trans_unreserve_quota_nblks(NULL, ip, (long)alen, 0, rt ? + XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS); + return error; } /* - * Returns the file-relative block number of the first block past eof in - * the file. This is not based on i_size, it is based on the extent records. - * Returns 0 for local files, as they do not have extent records. + * Map file blocks to filesystem blocks, adding delayed allocations as needed. */ -int /* error */ -xfs_bmap_last_offset( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode */ - xfs_fileoff_t *last_block, /* last block */ - int whichfork) /* data or attr fork */ +int +xfs_bmapi_delay( + struct xfs_inode *ip, /* incore inode */ + xfs_fileoff_t bno, /* starting file offs. mapped */ + xfs_filblks_t len, /* length to map in file */ + struct xfs_bmbt_irec *mval, /* output: map values */ + int *nmap, /* i/o: mval size/count */ + int flags) /* XFS_BMAPI_... */ { - xfs_bmbt_rec_host_t *ep; /* pointer to last extent */ - int error; /* error return value */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_extnum_t nextents; /* number of extent entries */ + struct xfs_mount *mp = ip->i_mount; + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); + struct xfs_bmbt_irec got; /* current file extent record */ + struct xfs_bmbt_irec prev; /* previous file extent record */ + xfs_fileoff_t obno; /* old block number (offset) */ + xfs_fileoff_t end; /* end of mapped file region */ + xfs_extnum_t lastx; /* last useful extent number */ + int eof; /* we've hit the end of extents */ + int n = 0; /* current extent index */ + int error = 0; - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) - return XFS_ERROR(EIO); - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { - *last_block = 0; - return 0; + ASSERT(*nmap >= 1); + ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); + ASSERT(!(flags & ~XFS_BMAPI_ENTIRE)); + + if (unlikely(XFS_TEST_ERROR( + (XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_EXTENTS && + XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_BTREE), + mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) { + XFS_ERROR_REPORT("xfs_bmapi_delay", XFS_ERRLEVEL_LOW, mp); + return XFS_ERROR(EFSCORRUPTED); } - ifp = XFS_IFORK_PTR(ip, whichfork); - if (!(ifp->if_flags & XFS_IFEXTENTS) && - (error = xfs_iread_extents(tp, ip, whichfork))) - return error; - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - if (!nextents) { - *last_block = 0; - return 0; + + if (XFS_FORCED_SHUTDOWN(mp)) + return XFS_ERROR(EIO); + + XFS_STATS_INC(xs_blk_mapw); + + if (!(ifp->if_flags & XFS_IFEXTENTS)) { + error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK); + if (error) + return error; } - ep = xfs_iext_get_ext(ifp, nextents - 1); - *last_block = xfs_bmbt_get_startoff(ep) + xfs_bmbt_get_blockcount(ep); - return 0; -} -/* - * Returns whether the selected fork of the inode has exactly one - * block or not. For the data fork we check this matches di_size, - * implying the file's range is 0..bsize-1. - */ -int /* 1=>1 block, 0=>otherwise */ -xfs_bmap_one_block( - xfs_inode_t *ip, /* incore inode */ - int whichfork) /* data or attr fork */ -{ - xfs_bmbt_rec_host_t *ep; /* ptr to fork's extent */ - xfs_ifork_t *ifp; /* inode fork pointer */ - int rval; /* return value */ - xfs_bmbt_irec_t s; /* internal version of extent */ + xfs_bmap_search_extents(ip, bno, XFS_DATA_FORK, &eof, &lastx, &got, &prev); + end = bno + len; + obno = bno; -#ifndef DEBUG - if (whichfork == XFS_DATA_FORK) { - return ((ip->i_d.di_mode & S_IFMT) == S_IFREG) ? - (ip->i_size == ip->i_mount->m_sb.sb_blocksize) : - (ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize); + while (bno < end && n < *nmap) { + if (eof || got.br_startoff > bno) { + error = xfs_bmapi_reserve_delalloc(ip, bno, len, &got, + &prev, &lastx, eof); + if (error) { + if (n == 0) { + *nmap = 0; + return error; + } + break; + } + } + + /* set up the extent map to return. */ + xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags); + xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags); + + /* If we're done, stop now. */ + if (bno >= end || n >= *nmap) + break; + + /* Else go on to the next record. */ + prev = got; + if (++lastx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)) + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx), &got); + else + eof = 1; } -#endif /* !DEBUG */ - if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1) - return 0; - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) - return 0; - ifp = XFS_IFORK_PTR(ip, whichfork); - ASSERT(ifp->if_flags & XFS_IFEXTENTS); - ep = xfs_iext_get_ext(ifp, 0); - xfs_bmbt_get_all(ep, &s); - rval = s.br_startoff == 0 && s.br_blockcount == 1; - if (rval && whichfork == XFS_DATA_FORK) - ASSERT(ip->i_size == ip->i_mount->m_sb.sb_blocksize); - return rval; + + *nmap = n; + return 0; } -STATIC int -xfs_bmap_sanity_check( - struct xfs_mount *mp, - struct xfs_buf *bp, - int level) -{ - struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); - if (be32_to_cpu(block->bb_magic) != XFS_BMAP_MAGIC || - be16_to_cpu(block->bb_level) != level || - be16_to_cpu(block->bb_numrecs) == 0 || - be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[level != 0]) - return 0; - return 1; -} +int +__xfs_bmapi_allocate( + struct xfs_bmalloca *bma) +{ + struct xfs_mount *mp = bma->ip->i_mount; + int whichfork = (bma->flags & XFS_BMAPI_ATTRFORK) ? + XFS_ATTR_FORK : XFS_DATA_FORK; + struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork); + int tmp_logflags = 0; + int error; -/* - * Read in the extents to if_extents. - * All inode fields are set up by caller, we just traverse the btree - * and copy the records in. If the file system cannot contain unwritten - * extents, the records are checked for no "state" flags. - */ -int /* error */ -xfs_bmap_read_extents( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode */ - int whichfork) /* data or attr fork */ -{ - struct xfs_btree_block *block; /* current btree block */ - xfs_fsblock_t bno; /* block # of "block" */ - xfs_buf_t *bp; /* buffer for "block" */ - int error; /* error return value */ - xfs_exntfmt_t exntf; /* XFS_EXTFMT_NOSTATE, if checking */ - xfs_extnum_t i, j; /* index into the extents list */ - xfs_ifork_t *ifp; /* fork structure */ - int level; /* btree level, for checking */ - xfs_mount_t *mp; /* file system mount structure */ - __be64 *pp; /* pointer to block address */ - /* REFERENCED */ - xfs_extnum_t room; /* number of entries there's room for */ + ASSERT(bma->length > 0); - bno = NULLFSBLOCK; - mp = ip->i_mount; - ifp = XFS_IFORK_PTR(ip, whichfork); - exntf = (whichfork != XFS_DATA_FORK) ? XFS_EXTFMT_NOSTATE : - XFS_EXTFMT_INODE(ip); - block = ifp->if_broot; - /* - * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. - */ - level = be16_to_cpu(block->bb_level); - ASSERT(level > 0); - pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); - bno = be64_to_cpu(*pp); - ASSERT(bno != NULLDFSBNO); - ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); - ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); /* - * Go down the tree until leaf level is reached, following the first - * pointer (leftmost) at each level. + * For the wasdelay case, we could also just allocate the stuff asked + * for in this bmap call but that wouldn't be as good. */ - while (level-- > 0) { - if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, - XFS_BMAP_BTREE_REF))) - return error; - block = XFS_BUF_TO_BLOCK(bp); - XFS_WANT_CORRUPTED_GOTO( - xfs_bmap_sanity_check(mp, bp, level), - error0); - if (level == 0) - break; - pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); - bno = be64_to_cpu(*pp); - XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0); - xfs_trans_brelse(tp, bp); + if (bma->wasdel) { + bma->length = (xfs_extlen_t)bma->got.br_blockcount; + bma->offset = bma->got.br_startoff; + if (bma->idx != NULLEXTNUM && bma->idx) { + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx - 1), + &bma->prev); + } + } else { + bma->length = XFS_FILBLKS_MIN(bma->length, MAXEXTLEN); + if (!bma->eof) + bma->length = XFS_FILBLKS_MIN(bma->length, + bma->got.br_startoff - bma->offset); } + /* - * Here with bp and block set to the leftmost leaf node in the tree. - */ - room = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - i = 0; - /* - * Loop over all leaf nodes. Copy information to the extent records. + * Indicate if this is the first user data in the file, or just any + * user data. */ - for (;;) { - xfs_bmbt_rec_t *frp; - xfs_fsblock_t nextbno; - xfs_extnum_t num_recs; - xfs_extnum_t start; + if (!(bma->flags & XFS_BMAPI_METADATA)) { + bma->userdata = (bma->offset == 0) ? + XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA; + } + bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1; - num_recs = xfs_btree_get_numrecs(block); - if (unlikely(i + num_recs > room)) { - ASSERT(i + num_recs <= room); - xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt dinode %Lu, (btree extents).", - (unsigned long long) ip->i_ino); - XFS_ERROR_REPORT("xfs_bmap_read_extents(1)", - XFS_ERRLEVEL_LOW, - ip->i_mount); - goto error0; - } - XFS_WANT_CORRUPTED_GOTO( - xfs_bmap_sanity_check(mp, bp, 0), - error0); - /* - * Read-ahead the next leaf block, if any. - */ - nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib); - if (nextbno != NULLFSBLOCK) - xfs_btree_reada_bufl(mp, nextbno, 1); - /* - * Copy records into the extent records. - */ - frp = XFS_BMBT_REC_ADDR(mp, block, 1); - start = i; - for (j = 0; j < num_recs; j++, i++, frp++) { - xfs_bmbt_rec_host_t *trp = xfs_iext_get_ext(ifp, i); - trp->l0 = be64_to_cpu(frp->l0); - trp->l1 = be64_to_cpu(frp->l1); - } - if (exntf == XFS_EXTFMT_NOSTATE) { - /* - * Check all attribute bmap btree records and - * any "older" data bmap btree records for a - * set bit in the "extent flag" position. - */ - if (unlikely(xfs_check_nostate_extents(ifp, - start, num_recs))) { - XFS_ERROR_REPORT("xfs_bmap_read_extents(2)", - XFS_ERRLEVEL_LOW, - ip->i_mount); - goto error0; - } - } - xfs_trans_brelse(tp, bp); - bno = nextbno; - /* - * If we've reached the end, stop. - */ - if (bno == NULLFSBLOCK) - break; - if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, - XFS_BMAP_BTREE_REF))) + /* + * Only want to do the alignment at the eof if it is userdata and + * allocation length is larger than a stripe unit. + */ + if (mp->m_dalign && bma->length >= mp->m_dalign && + !(bma->flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) { + error = xfs_bmap_isaeof(bma, whichfork); + if (error) return error; - block = XFS_BUF_TO_BLOCK(bp); } - ASSERT(i == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))); - ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork)); - XFS_BMAP_TRACE_EXLIST(ip, i, whichfork); - return 0; -error0: - xfs_trans_brelse(tp, bp); - return XFS_ERROR(EFSCORRUPTED); -} -#ifdef DEBUG -/* - * Add bmap trace insert entries for all the contents of the extent records. - */ -void -xfs_bmap_trace_exlist( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t cnt, /* count of entries in the list */ - int whichfork, /* data or attr fork */ - unsigned long caller_ip) -{ - xfs_extnum_t idx; /* extent record index */ - xfs_ifork_t *ifp; /* inode fork pointer */ - int state = 0; + error = xfs_bmap_alloc(bma); + if (error) + return error; - if (whichfork == XFS_ATTR_FORK) - state |= BMAP_ATTRFORK; + if (bma->flist->xbf_low) + bma->minleft = 0; + if (bma->cur) + bma->cur->bc_private.b.firstblock = *bma->firstblock; + if (bma->blkno == NULLFSBLOCK) + return 0; + if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur) { + bma->cur = xfs_bmbt_init_cursor(mp, bma->tp, bma->ip, whichfork); + bma->cur->bc_private.b.firstblock = *bma->firstblock; + bma->cur->bc_private.b.flist = bma->flist; + } + /* + * Bump the number of extents we've allocated + * in this call. + */ + bma->nallocs++; - ifp = XFS_IFORK_PTR(ip, whichfork); - ASSERT(cnt == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))); - for (idx = 0; idx < cnt; idx++) - trace_xfs_extlist(ip, idx, whichfork, caller_ip); + if (bma->cur) + bma->cur->bc_private.b.flags = + bma->wasdel ? XFS_BTCUR_BPRV_WASDEL : 0; + + bma->got.br_startoff = bma->offset; + bma->got.br_startblock = bma->blkno; + bma->got.br_blockcount = bma->length; + bma->got.br_state = XFS_EXT_NORM; + + /* + * A wasdelay extent has been initialized, so shouldn't be flagged + * as unwritten. + */ + if (!bma->wasdel && (bma->flags & XFS_BMAPI_PREALLOC) && + xfs_sb_version_hasextflgbit(&mp->m_sb)) + bma->got.br_state = XFS_EXT_UNWRITTEN; + + if (bma->wasdel) + error = xfs_bmap_add_extent_delay_real(bma); + else + error = xfs_bmap_add_extent_hole_real(bma, whichfork); + + bma->logflags |= tmp_logflags; + if (error) + return error; + + /* + * Update our extent pointer, given that xfs_bmap_add_extent_delay_real + * or xfs_bmap_add_extent_hole_real might have merged it into one of + * the neighbouring ones. + */ + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx), &bma->got); + + ASSERT(bma->got.br_startoff <= bma->offset); + ASSERT(bma->got.br_startoff + bma->got.br_blockcount >= + bma->offset + bma->length); + ASSERT(bma->got.br_state == XFS_EXT_NORM || + bma->got.br_state == XFS_EXT_UNWRITTEN); + return 0; } -/* - * Validate that the bmbt_irecs being returned from bmapi are valid - * given the callers original parameters. Specifically check the - * ranges of the returned irecs to ensure that they only extent beyond - * the given parameters if the XFS_BMAPI_ENTIRE flag was set. - */ -STATIC void -xfs_bmap_validate_ret( - xfs_fileoff_t bno, +STATIC int +xfs_bmapi_convert_unwritten( + struct xfs_bmalloca *bma, + struct xfs_bmbt_irec *mval, xfs_filblks_t len, - int flags, - xfs_bmbt_irec_t *mval, - int nmap, - int ret_nmap) + int flags) { - int i; /* index to map values */ + int whichfork = (flags & XFS_BMAPI_ATTRFORK) ? + XFS_ATTR_FORK : XFS_DATA_FORK; + struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork); + int tmp_logflags = 0; + int error; - ASSERT(ret_nmap <= nmap); + /* check if we need to do unwritten->real conversion */ + if (mval->br_state == XFS_EXT_UNWRITTEN && + (flags & XFS_BMAPI_PREALLOC)) + return 0; - for (i = 0; i < ret_nmap; i++) { - ASSERT(mval[i].br_blockcount > 0); - if (!(flags & XFS_BMAPI_ENTIRE)) { - ASSERT(mval[i].br_startoff >= bno); - ASSERT(mval[i].br_blockcount <= len); - ASSERT(mval[i].br_startoff + mval[i].br_blockcount <= - bno + len); - } else { - ASSERT(mval[i].br_startoff < bno + len); - ASSERT(mval[i].br_startoff + mval[i].br_blockcount > - bno); - } - ASSERT(i == 0 || - mval[i - 1].br_startoff + mval[i - 1].br_blockcount == - mval[i].br_startoff); - if ((flags & XFS_BMAPI_WRITE) && !(flags & XFS_BMAPI_DELAY)) - ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK && - mval[i].br_startblock != HOLESTARTBLOCK); - ASSERT(mval[i].br_state == XFS_EXT_NORM || - mval[i].br_state == XFS_EXT_UNWRITTEN); - } -} -#endif /* DEBUG */ + /* check if we need to do real->unwritten conversion */ + if (mval->br_state == XFS_EXT_NORM && + (flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_CONVERT)) != + (XFS_BMAPI_PREALLOC | XFS_BMAPI_CONVERT)) + return 0; + + /* + * Modify (by adding) the state flag, if writing. + */ + ASSERT(mval->br_blockcount <= len); + if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur) { + bma->cur = xfs_bmbt_init_cursor(bma->ip->i_mount, bma->tp, + bma->ip, whichfork); + bma->cur->bc_private.b.firstblock = *bma->firstblock; + bma->cur->bc_private.b.flist = bma->flist; + } + mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) + ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; + + error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx, + &bma->cur, mval, bma->firstblock, bma->flist, + &tmp_logflags); + bma->logflags |= tmp_logflags; + if (error) + return error; + /* + * Update our extent pointer, given that + * xfs_bmap_add_extent_unwritten_real might have merged it into one + * of the neighbouring ones. + */ + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx), &bma->got); + + /* + * We may have combined previously unwritten space with written space, + * so generate another request. + */ + if (mval->br_blockcount < len) + return EAGAIN; + return 0; +} /* - * Map file blocks to filesystem blocks. - * File range is given by the bno/len pair. - * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set) - * into a hole or past eof. - * Only allocates blocks from a single allocation group, - * to avoid locking problems. + * Map file blocks to filesystem blocks, and allocate blocks or convert the + * extent state if necessary. Details behaviour is controlled by the flags + * parameter. Only allocates blocks from a single allocation group, to avoid + * locking problems. + * * The returned value in "firstblock" from the first call in a transaction * must be remembered and presented to subsequent calls in "firstblock". * An upper bound for the number of blocks to be allocated is supplied to * the first call in "total"; if no allocation group has that many free * blocks then the call will fail (return NULLFSBLOCK in "firstblock"). */ -int /* error */ -xfs_bmapi( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode */ - xfs_fileoff_t bno, /* starting file offs. mapped */ - xfs_filblks_t len, /* length to map in file */ - int flags, /* XFS_BMAPI_... */ - xfs_fsblock_t *firstblock, /* first allocated block - controls a.g. for allocs */ - xfs_extlen_t total, /* total blocks needed */ - xfs_bmbt_irec_t *mval, /* output: map values */ - int *nmap, /* i/o: mval size/count */ - xfs_bmap_free_t *flist) /* i/o: list extents to free */ -{ - xfs_fsblock_t abno; /* allocated block number */ - xfs_extlen_t alen; /* allocated extent length */ - xfs_fileoff_t aoff; /* allocated file offset */ - xfs_bmalloca_t bma = { 0 }; /* args for xfs_bmap_alloc */ - xfs_btree_cur_t *cur; /* bmap btree cursor */ - xfs_fileoff_t end; /* end of mapped file region */ - int eof; /* we've hit the end of extents */ - xfs_bmbt_rec_host_t *ep; /* extent record pointer */ - int error; /* error return */ - xfs_bmbt_irec_t got; /* current file extent record */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_extlen_t indlen; /* indirect blocks length */ - xfs_extnum_t lastx; /* last useful extent number */ - int logflags; /* flags for transaction logging */ - xfs_extlen_t minleft; /* min blocks left after allocation */ - xfs_extlen_t minlen; /* min allocation size */ - xfs_mount_t *mp; /* xfs mount structure */ - int n; /* current extent index */ - int nallocs; /* number of extents alloc'd */ - xfs_extnum_t nextents; /* number of extents in file */ - xfs_fileoff_t obno; /* old block number (offset) */ - xfs_bmbt_irec_t prev; /* previous file extent record */ - int tmp_logflags; /* temp flags holder */ - int whichfork; /* data or attr fork */ - char inhole; /* current location is hole in file */ - char wasdelay; /* old extent was delayed */ - char wr; /* this is a write request */ - char rt; /* this is a realtime file */ +int +xfs_bmapi_write( + struct xfs_trans *tp, /* transaction pointer */ + struct xfs_inode *ip, /* incore inode */ + xfs_fileoff_t bno, /* starting file offs. mapped */ + xfs_filblks_t len, /* length to map in file */ + int flags, /* XFS_BMAPI_... */ + xfs_fsblock_t *firstblock, /* first allocated block + controls a.g. for allocs */ + xfs_extlen_t total, /* total blocks needed */ + struct xfs_bmbt_irec *mval, /* output: map values */ + int *nmap, /* i/o: mval size/count */ + struct xfs_bmap_free *flist) /* i/o: list extents to free */ +{ + struct xfs_mount *mp = ip->i_mount; + struct xfs_ifork *ifp; + struct xfs_bmalloca bma = { NULL }; /* args for xfs_bmap_alloc */ + xfs_fileoff_t end; /* end of mapped file region */ + int eof; /* after the end of extents */ + int error; /* error return */ + int n; /* current extent index */ + xfs_fileoff_t obno; /* old block number (offset) */ + int whichfork; /* data or attr fork */ + char inhole; /* current location is hole in file */ + char wasdelay; /* old extent was delayed */ + #ifdef DEBUG - xfs_fileoff_t orig_bno; /* original block number value */ - int orig_flags; /* original flags arg value */ - xfs_filblks_t orig_len; /* original value of len arg */ - xfs_bmbt_irec_t *orig_mval; /* original value of mval */ - int orig_nmap; /* original value of *nmap */ + xfs_fileoff_t orig_bno; /* original block number value */ + int orig_flags; /* original flags arg value */ + xfs_filblks_t orig_len; /* original value of len arg */ + struct xfs_bmbt_irec *orig_mval; /* original value of mval */ + int orig_nmap; /* original value of *nmap */ orig_bno = bno; orig_len = len; @@ -4120,585 +4438,508 @@ orig_mval = mval; orig_nmap = *nmap; #endif - ASSERT(*nmap >= 1); - ASSERT(*nmap <= XFS_BMAP_MAX_NMAP || !(flags & XFS_BMAPI_WRITE)); whichfork = (flags & XFS_BMAPI_ATTRFORK) ? XFS_ATTR_FORK : XFS_DATA_FORK; - mp = ip->i_mount; + + ASSERT(*nmap >= 1); + ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); + ASSERT(!(flags & XFS_BMAPI_IGSTATE)); + ASSERT(tp != NULL); + ASSERT(len > 0); + ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); + if (unlikely(XFS_TEST_ERROR( (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL), + XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) { - XFS_ERROR_REPORT("xfs_bmapi", XFS_ERRLEVEL_LOW, mp); + XFS_ERROR_REPORT("xfs_bmapi_write", XFS_ERRLEVEL_LOW, mp); return XFS_ERROR(EFSCORRUPTED); } + if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); - rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); + ifp = XFS_IFORK_PTR(ip, whichfork); - ASSERT(ifp->if_ext_max == - XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); - if ((wr = (flags & XFS_BMAPI_WRITE)) != 0) - XFS_STATS_INC(xs_blk_mapw); - else - XFS_STATS_INC(xs_blk_mapr); - /* - * IGSTATE flag is used to combine extents which - * differ only due to the state of the extents. - * This technique is used from xfs_getbmap() - * when the caller does not wish to see the - * separation (which is the default). - * - * This technique is also used when writing a - * buffer which has been partially written, - * (usually by being flushed during a chunkread), - * to ensure one write takes place. This also - * prevents a change in the xfs inode extents at - * this time, intentionally. This change occurs - * on completion of the write operation, in - * xfs_strat_comp(), where the xfs_bmapi() call - * is transactioned, and the extents combined. - */ - if ((flags & XFS_BMAPI_IGSTATE) && wr) /* if writing unwritten space */ - wr = 0; /* no allocations are allowed */ - ASSERT(wr || !(flags & XFS_BMAPI_DELAY)); - logflags = 0; - nallocs = 0; - cur = NULL; - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { - ASSERT(wr && tp); - if ((error = xfs_bmap_local_to_extents(tp, ip, - firstblock, total, &logflags, whichfork))) - goto error0; - } - if (wr && *firstblock == NULLFSBLOCK) { + + XFS_STATS_INC(xs_blk_mapw); + + if (*firstblock == NULLFSBLOCK) { if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE) - minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1; + bma.minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1; else - minleft = 1; - } else - minleft = 0; - if (!(ifp->if_flags & XFS_IFEXTENTS) && - (error = xfs_iread_extents(tp, ip, whichfork))) - goto error0; - ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, - &prev); - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + bma.minleft = 1; + } else { + bma.minleft = 0; + } + + if (!(ifp->if_flags & XFS_IFEXTENTS)) { + error = xfs_iread_extents(tp, ip, whichfork); + if (error) + goto error0; + } + + xfs_bmap_search_extents(ip, bno, whichfork, &eof, &bma.idx, &bma.got, + &bma.prev); n = 0; end = bno + len; obno = bno; - bma.ip = NULL; - while (bno < end && n < *nmap) { + bma.tp = tp; + bma.ip = ip; + bma.total = total; + bma.userdata = 0; + bma.flist = flist; + bma.firstblock = firstblock; + + if (flags & XFS_BMAPI_STACK_SWITCH) + bma.stack_switch = 1; + + while (bno < end && n < *nmap) { + inhole = eof || bma.got.br_startoff > bno; + wasdelay = !inhole && isnullstartblock(bma.got.br_startblock); + + /* + * First, deal with the hole before the allocated space + * that we found, if any. + */ + if (inhole || wasdelay) { + bma.eof = eof; + bma.conv = !!(flags & XFS_BMAPI_CONVERT); + bma.wasdel = wasdelay; + bma.offset = bno; + bma.flags = flags; + + /* + * There's a 32/64 bit type mismatch between the + * allocation length request (which can be 64 bits in + * length) and the bma length request, which is + * xfs_extlen_t and therefore 32 bits. Hence we have to + * check for 32-bit overflows and handle them here. + */ + if (len > (xfs_filblks_t)MAXEXTLEN) + bma.length = MAXEXTLEN; + else + bma.length = len; + + ASSERT(len > 0); + ASSERT(bma.length > 0); + error = xfs_bmapi_allocate(&bma); + if (error) + goto error0; + if (bma.blkno == NULLFSBLOCK) + break; + } + + /* Deal with the allocated space we found. */ + xfs_bmapi_trim_map(mval, &bma.got, &bno, len, obno, + end, n, flags); + + /* Execute unwritten extent conversion if necessary */ + error = xfs_bmapi_convert_unwritten(&bma, mval, len, flags); + if (error == EAGAIN) + continue; + if (error) + goto error0; + + /* update the extent map to return */ + xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags); + + /* + * If we're done, stop now. Stop when we've allocated + * XFS_BMAP_MAX_NMAP extents no matter what. Otherwise + * the transaction may get too big. + */ + if (bno >= end || n >= *nmap || bma.nallocs >= *nmap) + break; + + /* Else go on to the next record. */ + bma.prev = bma.got; + if (++bma.idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)) { + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma.idx), + &bma.got); + } else + eof = 1; + } + *nmap = n; + + /* + * Transform from btree to extents, give it cur. + */ + if (xfs_bmap_wants_extents(ip, whichfork)) { + int tmp_logflags = 0; + + ASSERT(bma.cur); + error = xfs_bmap_btree_to_extents(tp, ip, bma.cur, + &tmp_logflags, whichfork); + bma.logflags |= tmp_logflags; + if (error) + goto error0; + } + + ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || + XFS_IFORK_NEXTENTS(ip, whichfork) > + XFS_IFORK_MAXEXT(ip, whichfork)); + error = 0; +error0: + /* + * Log everything. Do this after conversion, there's no point in + * logging the extent records if we've converted to btree format. + */ + if ((bma.logflags & xfs_ilog_fext(whichfork)) && + XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) + bma.logflags &= ~xfs_ilog_fext(whichfork); + else if ((bma.logflags & xfs_ilog_fbroot(whichfork)) && + XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) + bma.logflags &= ~xfs_ilog_fbroot(whichfork); + /* + * Log whatever the flags say, even if error. Otherwise we might miss + * detecting a case where the data is changed, there's an error, + * and it's not logged so we don't shutdown when we should. + */ + if (bma.logflags) + xfs_trans_log_inode(tp, ip, bma.logflags); + + if (bma.cur) { + if (!error) { + ASSERT(*firstblock == NULLFSBLOCK || + XFS_FSB_TO_AGNO(mp, *firstblock) == + XFS_FSB_TO_AGNO(mp, + bma.cur->bc_private.b.firstblock) || + (flist->xbf_low && + XFS_FSB_TO_AGNO(mp, *firstblock) < + XFS_FSB_TO_AGNO(mp, + bma.cur->bc_private.b.firstblock))); + *firstblock = bma.cur->bc_private.b.firstblock; + } + xfs_btree_del_cursor(bma.cur, + error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + } + if (!error) + xfs_bmap_validate_ret(orig_bno, orig_len, orig_flags, orig_mval, + orig_nmap, *nmap); + return error; +} + +/* + * Called by xfs_bmapi to update file extent records and the btree + * after removing space (or undoing a delayed allocation). + */ +STATIC int /* error */ +xfs_bmap_del_extent( + xfs_inode_t *ip, /* incore inode pointer */ + xfs_trans_t *tp, /* current transaction pointer */ + xfs_extnum_t *idx, /* extent number to update/delete */ + xfs_bmap_free_t *flist, /* list of extents to be freed */ + xfs_btree_cur_t *cur, /* if null, not a btree */ + xfs_bmbt_irec_t *del, /* data to remove from extents */ + int *logflagsp, /* inode logging flags */ + int whichfork) /* data or attr fork */ +{ + xfs_filblks_t da_new; /* new delay-alloc indirect blocks */ + xfs_filblks_t da_old; /* old delay-alloc indirect blocks */ + xfs_fsblock_t del_endblock=0; /* first block past del */ + xfs_fileoff_t del_endoff; /* first offset past del */ + int delay; /* current block is delayed allocated */ + int do_fx; /* free extent at end of routine */ + xfs_bmbt_rec_host_t *ep; /* current extent entry pointer */ + int error; /* error return value */ + int flags; /* inode logging flags */ + xfs_bmbt_irec_t got; /* current extent entry */ + xfs_fileoff_t got_endoff; /* first offset past got */ + int i; /* temp state */ + xfs_ifork_t *ifp; /* inode fork pointer */ + xfs_mount_t *mp; /* mount structure */ + xfs_filblks_t nblks; /* quota/sb block count */ + xfs_bmbt_irec_t new; /* new record to be inserted */ + /* REFERENCED */ + uint qfield; /* quota field to update */ + xfs_filblks_t temp; /* for indirect length calculations */ + xfs_filblks_t temp2; /* for indirect length calculations */ + int state = 0; + + XFS_STATS_INC(xs_del_exlist); + + if (whichfork == XFS_ATTR_FORK) + state |= BMAP_ATTRFORK; + + mp = ip->i_mount; + ifp = XFS_IFORK_PTR(ip, whichfork); + ASSERT((*idx >= 0) && (*idx < ifp->if_bytes / + (uint)sizeof(xfs_bmbt_rec_t))); + ASSERT(del->br_blockcount > 0); + ep = xfs_iext_get_ext(ifp, *idx); + xfs_bmbt_get_all(ep, &got); + ASSERT(got.br_startoff <= del->br_startoff); + del_endoff = del->br_startoff + del->br_blockcount; + got_endoff = got.br_startoff + got.br_blockcount; + ASSERT(got_endoff >= del_endoff); + delay = isnullstartblock(got.br_startblock); + ASSERT(isnullstartblock(del->br_startblock) == delay); + flags = 0; + qfield = 0; + error = 0; + /* + * If deleting a real allocation, must free up the disk space. + */ + if (!delay) { + flags = XFS_ILOG_CORE; + /* + * Realtime allocation. Free it and record di_nblocks update. + */ + if (whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip)) { + xfs_fsblock_t bno; + xfs_filblks_t len; + + ASSERT(do_mod(del->br_blockcount, + mp->m_sb.sb_rextsize) == 0); + ASSERT(do_mod(del->br_startblock, + mp->m_sb.sb_rextsize) == 0); + bno = del->br_startblock; + len = del->br_blockcount; + do_div(bno, mp->m_sb.sb_rextsize); + do_div(len, mp->m_sb.sb_rextsize); + error = xfs_rtfree_extent(tp, bno, (xfs_extlen_t)len); + if (error) + goto done; + do_fx = 0; + nblks = len * mp->m_sb.sb_rextsize; + qfield = XFS_TRANS_DQ_RTBCOUNT; + } /* - * Reading past eof, act as though there's a hole - * up to end. + * Ordinary allocation. */ - if (eof && !wr) - got.br_startoff = end; - inhole = eof || got.br_startoff > bno; - wasdelay = wr && !inhole && !(flags & XFS_BMAPI_DELAY) && - isnullstartblock(got.br_startblock); + else { + do_fx = 1; + nblks = del->br_blockcount; + qfield = XFS_TRANS_DQ_BCOUNT; + } /* - * First, deal with the hole before the allocated space - * that we found, if any. + * Set up del_endblock and cur for later. */ - if (wr && (inhole || wasdelay)) { - /* - * For the wasdelay case, we could also just - * allocate the stuff asked for in this bmap call - * but that wouldn't be as good. - */ - if (wasdelay) { - alen = (xfs_extlen_t)got.br_blockcount; - aoff = got.br_startoff; - if (lastx != NULLEXTNUM && lastx) { - ep = xfs_iext_get_ext(ifp, lastx - 1); - xfs_bmbt_get_all(ep, &prev); - } - } else { - alen = (xfs_extlen_t) - XFS_FILBLKS_MIN(len, MAXEXTLEN); - if (!eof) - alen = (xfs_extlen_t) - XFS_FILBLKS_MIN(alen, - got.br_startoff - bno); - aoff = bno; - } - minlen = (flags & XFS_BMAPI_CONTIG) ? alen : 1; - if (flags & XFS_BMAPI_DELAY) { - xfs_extlen_t extsz; - - /* Figure out the extent size, adjust alen */ - extsz = xfs_get_extsz_hint(ip); - if (extsz) { - error = xfs_bmap_extsize_align(mp, - &got, &prev, extsz, - rt, eof, - flags&XFS_BMAPI_DELAY, - flags&XFS_BMAPI_CONVERT, - &aoff, &alen); - ASSERT(!error); - } - - if (rt) - extsz = alen / mp->m_sb.sb_rextsize; - - /* - * Make a transaction-less quota reservation for - * delayed allocation blocks. This number gets - * adjusted later. We return if we haven't - * allocated blocks already inside this loop. - */ - error = xfs_trans_reserve_quota_nblks( - NULL, ip, (long)alen, 0, - rt ? XFS_QMOPT_RES_RTBLKS : - XFS_QMOPT_RES_REGBLKS); - if (error) { - if (n == 0) { - *nmap = 0; - ASSERT(cur == NULL); - return error; - } - break; - } - - /* - * Split changing sb for alen and indlen since - * they could be coming from different places. - */ - indlen = (xfs_extlen_t) - xfs_bmap_worst_indlen(ip, alen); - ASSERT(indlen > 0); - - if (rt) { - error = xfs_mod_incore_sb(mp, - XFS_SBS_FREXTENTS, - -((int64_t)extsz), (flags & - XFS_BMAPI_RSVBLOCKS)); - } else { - error = xfs_icsb_modify_counters(mp, - XFS_SBS_FDBLOCKS, - -((int64_t)alen), (flags & - XFS_BMAPI_RSVBLOCKS)); - } - if (!error) { - error = xfs_icsb_modify_counters(mp, - XFS_SBS_FDBLOCKS, - -((int64_t)indlen), (flags & - XFS_BMAPI_RSVBLOCKS)); - if (error && rt) - xfs_mod_incore_sb(mp, - XFS_SBS_FREXTENTS, - (int64_t)extsz, (flags & - XFS_BMAPI_RSVBLOCKS)); - else if (error) - xfs_icsb_modify_counters(mp, - XFS_SBS_FDBLOCKS, - (int64_t)alen, (flags & - XFS_BMAPI_RSVBLOCKS)); - } + del_endblock = del->br_startblock + del->br_blockcount; + if (cur) { + if ((error = xfs_bmbt_lookup_eq(cur, got.br_startoff, + got.br_startblock, got.br_blockcount, + &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + } + da_old = da_new = 0; + } else { + da_old = startblockval(got.br_startblock); + da_new = 0; + nblks = 0; + do_fx = 0; + } + /* + * Set flag value to use in switch statement. + * Left-contig is 2, right-contig is 1. + */ + switch (((got.br_startoff == del->br_startoff) << 1) | + (got_endoff == del_endoff)) { + case 3: + /* + * Matches the whole extent. Delete the entry. + */ + xfs_iext_remove(ip, *idx, 1, + whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); + --*idx; + if (delay) + break; - if (error) { - if (XFS_IS_QUOTA_ON(mp)) - /* unreserve the blocks now */ - (void) - xfs_trans_unreserve_quota_nblks( - NULL, ip, - (long)alen, 0, rt ? - XFS_QMOPT_RES_RTBLKS : - XFS_QMOPT_RES_REGBLKS); - break; - } + XFS_IFORK_NEXT_SET(ip, whichfork, + XFS_IFORK_NEXTENTS(ip, whichfork) - 1); + flags |= XFS_ILOG_CORE; + if (!cur) { + flags |= xfs_ilog_fext(whichfork); + break; + } + if ((error = xfs_btree_delete(cur, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + break; - ip->i_delayed_blks += alen; - abno = nullstartblock(indlen); - } else { - /* - * If first time, allocate and fill in - * once-only bma fields. - */ - if (bma.ip == NULL) { - bma.tp = tp; - bma.ip = ip; - bma.prevp = &prev; - bma.gotp = &got; - bma.total = total; - bma.userdata = 0; - } - /* Indicate if this is the first user data - * in the file, or just any user data. - */ - if (!(flags & XFS_BMAPI_METADATA)) { - bma.userdata = (aoff == 0) ? - XFS_ALLOC_INITIAL_USER_DATA : - XFS_ALLOC_USERDATA; - } - /* - * Fill in changeable bma fields. - */ - bma.eof = eof; - bma.firstblock = *firstblock; - bma.alen = alen; - bma.off = aoff; - bma.conv = !!(flags & XFS_BMAPI_CONVERT); - bma.wasdel = wasdelay; - bma.minlen = minlen; - bma.low = flist->xbf_low; - bma.minleft = minleft; - /* - * Only want to do the alignment at the - * eof if it is userdata and allocation length - * is larger than a stripe unit. - */ - if (mp->m_dalign && alen >= mp->m_dalign && - (!(flags & XFS_BMAPI_METADATA)) && - (whichfork == XFS_DATA_FORK)) { - if ((error = xfs_bmap_isaeof(ip, aoff, - whichfork, &bma.aeof))) - goto error0; - } else - bma.aeof = 0; - /* - * Call allocator. - */ - if ((error = xfs_bmap_alloc(&bma))) - goto error0; - /* - * Copy out result fields. - */ - abno = bma.rval; - if ((flist->xbf_low = bma.low)) - minleft = 0; - alen = bma.alen; - aoff = bma.off; - ASSERT(*firstblock == NULLFSBLOCK || - XFS_FSB_TO_AGNO(mp, *firstblock) == - XFS_FSB_TO_AGNO(mp, bma.firstblock) || - (flist->xbf_low && - XFS_FSB_TO_AGNO(mp, *firstblock) < - XFS_FSB_TO_AGNO(mp, bma.firstblock))); - *firstblock = bma.firstblock; - if (cur) - cur->bc_private.b.firstblock = - *firstblock; - if (abno == NULLFSBLOCK) - break; - if ((ifp->if_flags & XFS_IFBROOT) && !cur) { - cur = xfs_bmbt_init_cursor(mp, tp, - ip, whichfork); - cur->bc_private.b.firstblock = - *firstblock; - cur->bc_private.b.flist = flist; - } - /* - * Bump the number of extents we've allocated - * in this call. - */ - nallocs++; - } - if (cur) - cur->bc_private.b.flags = - wasdelay ? XFS_BTCUR_BPRV_WASDEL : 0; - got.br_startoff = aoff; - got.br_startblock = abno; - got.br_blockcount = alen; - got.br_state = XFS_EXT_NORM; /* assume normal */ - /* - * Determine state of extent, and the filesystem. - * A wasdelay extent has been initialized, so - * shouldn't be flagged as unwritten. - */ - if (wr && xfs_sb_version_hasextflgbit(&mp->m_sb)) { - if (!wasdelay && (flags & XFS_BMAPI_PREALLOC)) - got.br_state = XFS_EXT_UNWRITTEN; - } - error = xfs_bmap_add_extent(ip, lastx, &cur, &got, - firstblock, flist, &tmp_logflags, - whichfork, (flags & XFS_BMAPI_RSVBLOCKS)); - logflags |= tmp_logflags; - if (error) - goto error0; - lastx = ifp->if_lastex; - ep = xfs_iext_get_ext(ifp, lastx); - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - xfs_bmbt_get_all(ep, &got); - ASSERT(got.br_startoff <= aoff); - ASSERT(got.br_startoff + got.br_blockcount >= - aoff + alen); -#ifdef DEBUG - if (flags & XFS_BMAPI_DELAY) { - ASSERT(isnullstartblock(got.br_startblock)); - ASSERT(startblockval(got.br_startblock) > 0); - } - ASSERT(got.br_state == XFS_EXT_NORM || - got.br_state == XFS_EXT_UNWRITTEN); -#endif - /* - * Fall down into the found allocated space case. - */ - } else if (inhole) { - /* - * Reading in a hole. - */ - mval->br_startoff = bno; - mval->br_startblock = HOLESTARTBLOCK; - mval->br_blockcount = - XFS_FILBLKS_MIN(len, got.br_startoff - bno); - mval->br_state = XFS_EXT_NORM; - bno += mval->br_blockcount; - len -= mval->br_blockcount; - mval++; - n++; - continue; + case 2: + /* + * Deleting the first part of the extent. + */ + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); + xfs_bmbt_set_startoff(ep, del_endoff); + temp = got.br_blockcount - del->br_blockcount; + xfs_bmbt_set_blockcount(ep, temp); + if (delay) { + temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), + da_old); + xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); + da_new = temp; + break; + } + xfs_bmbt_set_startblock(ep, del_endblock); + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); + if (!cur) { + flags |= xfs_ilog_fext(whichfork); + break; } + if ((error = xfs_bmbt_update(cur, del_endoff, del_endblock, + got.br_blockcount - del->br_blockcount, + got.br_state))) + goto done; + break; + + case 1: /* - * Then deal with the allocated space we found. + * Deleting the last part of the extent. */ - ASSERT(ep != NULL); - if (!(flags & XFS_BMAPI_ENTIRE) && - (got.br_startoff + got.br_blockcount > obno)) { - if (obno > bno) - bno = obno; - ASSERT((bno >= obno) || (n == 0)); - ASSERT(bno < end); - mval->br_startoff = bno; - if (isnullstartblock(got.br_startblock)) { - ASSERT(!wr || (flags & XFS_BMAPI_DELAY)); - mval->br_startblock = DELAYSTARTBLOCK; - } else - mval->br_startblock = - got.br_startblock + - (bno - got.br_startoff); - /* - * Return the minimum of what we got and what we - * asked for for the length. We can use the len - * variable here because it is modified below - * and we could have been there before coming - * here if the first part of the allocation - * didn't overlap what was asked for. - */ - mval->br_blockcount = - XFS_FILBLKS_MIN(end - bno, got.br_blockcount - - (bno - got.br_startoff)); - mval->br_state = got.br_state; - ASSERT(mval->br_blockcount <= len); - } else { - *mval = got; - if (isnullstartblock(mval->br_startblock)) { - ASSERT(!wr || (flags & XFS_BMAPI_DELAY)); - mval->br_startblock = DELAYSTARTBLOCK; - } + temp = got.br_blockcount - del->br_blockcount; + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); + xfs_bmbt_set_blockcount(ep, temp); + if (delay) { + temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), + da_old); + xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); + da_new = temp; + break; + } + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); + if (!cur) { + flags |= xfs_ilog_fext(whichfork); + break; } + if ((error = xfs_bmbt_update(cur, got.br_startoff, + got.br_startblock, + got.br_blockcount - del->br_blockcount, + got.br_state))) + goto done; + break; + case 0: /* - * Check if writing previously allocated but - * unwritten extents. + * Deleting the middle of the extent. */ - if (wr && - ((mval->br_state == XFS_EXT_UNWRITTEN && - ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_DELAY)) == 0)) || - (mval->br_state == XFS_EXT_NORM && - ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT)) == - (XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT))))) { - /* - * Modify (by adding) the state flag, if writing. - */ - ASSERT(mval->br_blockcount <= len); - if ((ifp->if_flags & XFS_IFBROOT) && !cur) { - cur = xfs_bmbt_init_cursor(mp, - tp, ip, whichfork); - cur->bc_private.b.firstblock = - *firstblock; - cur->bc_private.b.flist = flist; + temp = del->br_startoff - got.br_startoff; + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); + xfs_bmbt_set_blockcount(ep, temp); + new.br_startoff = del_endoff; + temp2 = got_endoff - del_endoff; + new.br_blockcount = temp2; + new.br_state = got.br_state; + if (!delay) { + new.br_startblock = del_endblock; + flags |= XFS_ILOG_CORE; + if (cur) { + if ((error = xfs_bmbt_update(cur, + got.br_startoff, + got.br_startblock, temp, + got.br_state))) + goto done; + if ((error = xfs_btree_increment(cur, 0, &i))) + goto done; + cur->bc_rec.b = new; + error = xfs_btree_insert(cur, &i); + if (error && error != ENOSPC) + goto done; + /* + * If get no-space back from btree insert, + * it tried a split, and we have a zero + * block reservation. + * Fix up our state and return the error. + */ + if (error == ENOSPC) { + /* + * Reset the cursor, don't trust + * it after any insert operation. + */ + if ((error = xfs_bmbt_lookup_eq(cur, + got.br_startoff, + got.br_startblock, + temp, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + /* + * Update the btree record back + * to the original value. + */ + if ((error = xfs_bmbt_update(cur, + got.br_startoff, + got.br_startblock, + got.br_blockcount, + got.br_state))) + goto done; + /* + * Reset the extent record back + * to the original value. + */ + xfs_bmbt_set_blockcount(ep, + got.br_blockcount); + flags = 0; + error = XFS_ERROR(ENOSPC); + goto done; + } + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + } else + flags |= xfs_ilog_fext(whichfork); + XFS_IFORK_NEXT_SET(ip, whichfork, + XFS_IFORK_NEXTENTS(ip, whichfork) + 1); + } else { + ASSERT(whichfork == XFS_DATA_FORK); + temp = xfs_bmap_worst_indlen(ip, temp); + xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); + temp2 = xfs_bmap_worst_indlen(ip, temp2); + new.br_startblock = nullstartblock((int)temp2); + da_new = temp + temp2; + while (da_new > da_old) { + if (temp) { + temp--; + da_new--; + xfs_bmbt_set_startblock(ep, + nullstartblock((int)temp)); + } + if (da_new == da_old) + break; + if (temp2) { + temp2--; + da_new--; + new.br_startblock = + nullstartblock((int)temp2); + } } - mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) - ? XFS_EXT_NORM - : XFS_EXT_UNWRITTEN; - error = xfs_bmap_add_extent(ip, lastx, &cur, mval, - firstblock, flist, &tmp_logflags, - whichfork, (flags & XFS_BMAPI_RSVBLOCKS)); - logflags |= tmp_logflags; - if (error) - goto error0; - lastx = ifp->if_lastex; - ep = xfs_iext_get_ext(ifp, lastx); - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - xfs_bmbt_get_all(ep, &got); - /* - * We may have combined previously unwritten - * space with written space, so generate - * another request. - */ - if (mval->br_blockcount < len) - continue; - } - - ASSERT((flags & XFS_BMAPI_ENTIRE) || - ((mval->br_startoff + mval->br_blockcount) <= end)); - ASSERT((flags & XFS_BMAPI_ENTIRE) || - (mval->br_blockcount <= len) || - (mval->br_startoff < obno)); - bno = mval->br_startoff + mval->br_blockcount; - len = end - bno; - if (n > 0 && mval->br_startoff == mval[-1].br_startoff) { - ASSERT(mval->br_startblock == mval[-1].br_startblock); - ASSERT(mval->br_blockcount > mval[-1].br_blockcount); - ASSERT(mval->br_state == mval[-1].br_state); - mval[-1].br_blockcount = mval->br_blockcount; - mval[-1].br_state = mval->br_state; - } else if (n > 0 && mval->br_startblock != DELAYSTARTBLOCK && - mval[-1].br_startblock != DELAYSTARTBLOCK && - mval[-1].br_startblock != HOLESTARTBLOCK && - mval->br_startblock == - mval[-1].br_startblock + mval[-1].br_blockcount && - ((flags & XFS_BMAPI_IGSTATE) || - mval[-1].br_state == mval->br_state)) { - ASSERT(mval->br_startoff == - mval[-1].br_startoff + mval[-1].br_blockcount); - mval[-1].br_blockcount += mval->br_blockcount; - } else if (n > 0 && - mval->br_startblock == DELAYSTARTBLOCK && - mval[-1].br_startblock == DELAYSTARTBLOCK && - mval->br_startoff == - mval[-1].br_startoff + mval[-1].br_blockcount) { - mval[-1].br_blockcount += mval->br_blockcount; - mval[-1].br_state = mval->br_state; - } else if (!((n == 0) && - ((mval->br_startoff + mval->br_blockcount) <= - obno))) { - mval++; - n++; } - /* - * If we're done, stop now. Stop when we've allocated - * XFS_BMAP_MAX_NMAP extents no matter what. Otherwise - * the transaction may get too big. - */ - if (bno >= end || n >= *nmap || nallocs >= *nmap) - break; - /* - * Else go on to the next record. - */ - ep = xfs_iext_get_ext(ifp, ++lastx); - prev = got; - if (lastx >= nextents) - eof = 1; - else - xfs_bmbt_get_all(ep, &got); + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); + xfs_iext_insert(ip, *idx + 1, 1, &new, state); + ++*idx; + break; } - ifp->if_lastex = lastx; - *nmap = n; /* - * Transform from btree to extents, give it cur. + * If we need to, add to list of extents to delete. */ - if (tp && XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && - XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) { - ASSERT(wr && cur); - error = xfs_bmap_btree_to_extents(tp, ip, cur, - &tmp_logflags, whichfork); - logflags |= tmp_logflags; - if (error) - goto error0; - } - ASSERT(ifp->if_ext_max == - XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || - XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max); - error = 0; -error0: + if (do_fx) + xfs_bmap_add_free(del->br_startblock, del->br_blockcount, flist, + mp); /* - * Log everything. Do this after conversion, there's no point in - * logging the extent records if we've converted to btree format. + * Adjust inode # blocks in the file. */ - if ((logflags & xfs_ilog_fext(whichfork)) && - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) - logflags &= ~xfs_ilog_fext(whichfork); - else if ((logflags & xfs_ilog_fbroot(whichfork)) && - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) - logflags &= ~xfs_ilog_fbroot(whichfork); + if (nblks) + ip->i_d.di_nblocks -= nblks; /* - * Log whatever the flags say, even if error. Otherwise we might miss - * detecting a case where the data is changed, there's an error, - * and it's not logged so we don't shutdown when we should. + * Adjust quota data. */ - if (logflags) { - ASSERT(tp && wr); - xfs_trans_log_inode(tp, ip, logflags); - } - if (cur) { - if (!error) { - ASSERT(*firstblock == NULLFSBLOCK || - XFS_FSB_TO_AGNO(mp, *firstblock) == - XFS_FSB_TO_AGNO(mp, - cur->bc_private.b.firstblock) || - (flist->xbf_low && - XFS_FSB_TO_AGNO(mp, *firstblock) < - XFS_FSB_TO_AGNO(mp, - cur->bc_private.b.firstblock))); - *firstblock = cur->bc_private.b.firstblock; - } - xfs_btree_del_cursor(cur, - error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); - } - if (!error) - xfs_bmap_validate_ret(orig_bno, orig_len, orig_flags, orig_mval, - orig_nmap, *nmap); - return error; -} - -/* - * Map file blocks to filesystem blocks, simple version. - * One block (extent) only, read-only. - * For flags, only the XFS_BMAPI_ATTRFORK flag is examined. - * For the other flag values, the effect is as if XFS_BMAPI_METADATA - * was set and all the others were clear. - */ -int /* error */ -xfs_bmapi_single( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode */ - int whichfork, /* data or attr fork */ - xfs_fsblock_t *fsb, /* output: mapped block */ - xfs_fileoff_t bno) /* starting file offs. mapped */ -{ - int eof; /* we've hit the end of extents */ - int error; /* error return */ - xfs_bmbt_irec_t got; /* current file extent record */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_extnum_t lastx; /* last useful extent number */ - xfs_bmbt_irec_t prev; /* previous file extent record */ + if (qfield) + xfs_trans_mod_dquot_byino(tp, ip, qfield, (long)-nblks); - ifp = XFS_IFORK_PTR(ip, whichfork); - if (unlikely( - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)) { - XFS_ERROR_REPORT("xfs_bmapi_single", XFS_ERRLEVEL_LOW, - ip->i_mount); - return XFS_ERROR(EFSCORRUPTED); - } - if (XFS_FORCED_SHUTDOWN(ip->i_mount)) - return XFS_ERROR(EIO); - XFS_STATS_INC(xs_blk_mapr); - if (!(ifp->if_flags & XFS_IFEXTENTS) && - (error = xfs_iread_extents(tp, ip, whichfork))) - return error; - (void)xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, - &prev); /* - * Reading past eof, act as though there's a hole - * up to end. + * Account for change in delayed indirect blocks. + * Nothing to do for disk quota accounting here. */ - if (eof || got.br_startoff > bno) { - *fsb = NULLFSBLOCK; - return 0; + ASSERT(da_old >= da_new); + if (da_old > da_new) { + xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, + (int64_t)(da_old - da_new), 0); } - ASSERT(!isnullstartblock(got.br_startblock)); - ASSERT(bno < got.br_startoff + got.br_blockcount); - *fsb = got.br_startblock + (bno - got.br_startoff); - ifp->if_lastex = lastx; - return 0; +done: + *logflagsp = flags; + return error; } /* @@ -4739,7 +4980,6 @@ int tmp_logflags; /* partial logging flags */ int wasdel; /* was a delayed alloc extent */ int whichfork; /* data or attribute fork */ - int rsvd; /* OK to allocate reserved blocks */ xfs_fsblock_t sum; trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_); @@ -4757,11 +4997,10 @@ mp = ip->i_mount; if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); - rsvd = (flags & XFS_BMAPI_RSVBLOCKS) != 0; + ASSERT(len > 0); ASSERT(nexts >= 0); - ASSERT(ifp->if_ext_max == - XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); + if (!(ifp->if_flags & XFS_IFEXTENTS) && (error = xfs_iread_extents(tp, ip, whichfork))) return error; @@ -4795,6 +5034,15 @@ cur->bc_private.b.flags = 0; } else cur = NULL; + + if (isrt) { + /* + * Synchronize by locking the bitmap inode. + */ + xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL); + xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL); + } + extno = 0; while (bno != (xfs_fileoff_t)-1 && bno >= start && lastx >= 0 && (nexts == 0 || extno < nexts)) { @@ -4873,9 +5121,9 @@ del.br_blockcount = mod; } del.br_state = XFS_EXT_UNWRITTEN; - error = xfs_bmap_add_extent(ip, lastx, &cur, &del, - firstblock, flist, &logflags, - XFS_DATA_FORK, 0); + error = xfs_bmap_add_extent_unwritten_real(tp, ip, + &lastx, &cur, &del, firstblock, flist, + &logflags); if (error) goto error0; goto nodelete; @@ -4901,9 +5149,12 @@ */ ASSERT(bno >= del.br_blockcount); bno -= del.br_blockcount; - if (bno < got.br_startoff) { - if (--lastx >= 0) - xfs_bmbt_get_all(--ep, &got); + if (got.br_startoff > bno) { + if (--lastx >= 0) { + ep = xfs_iext_get_ext(ifp, + lastx); + xfs_bmbt_get_all(ep, &got); + } } continue; } else if (del.br_state == XFS_EXT_UNWRITTEN) { @@ -4927,18 +5178,19 @@ prev.br_startoff = start; } prev.br_state = XFS_EXT_UNWRITTEN; - error = xfs_bmap_add_extent(ip, lastx - 1, &cur, - &prev, firstblock, flist, &logflags, - XFS_DATA_FORK, 0); + lastx--; + error = xfs_bmap_add_extent_unwritten_real(tp, + ip, &lastx, &cur, &prev, + firstblock, flist, &logflags); if (error) goto error0; goto nodelete; } else { ASSERT(del.br_state == XFS_EXT_NORM); del.br_state = XFS_EXT_UNWRITTEN; - error = xfs_bmap_add_extent(ip, lastx, &cur, - &del, firstblock, flist, &logflags, - XFS_DATA_FORK, 0); + error = xfs_bmap_add_extent_unwritten_real(tp, + ip, &lastx, &cur, &del, + firstblock, flist, &logflags); if (error) goto error0; goto nodelete; @@ -4953,13 +5205,13 @@ rtexts = XFS_FSB_TO_B(mp, del.br_blockcount); do_div(rtexts, mp->m_sb.sb_rextsize); xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, - (int64_t)rtexts, rsvd); + (int64_t)rtexts, 0); (void)xfs_trans_reserve_quota_nblks(NULL, ip, -((long)del.br_blockcount), 0, XFS_QMOPT_RES_RTBLKS); } else { xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, - (int64_t)del.br_blockcount, rsvd); + (int64_t)del.br_blockcount, 0); (void)xfs_trans_reserve_quota_nblks(NULL, ip, -((long)del.br_blockcount), 0, XFS_QMOPT_RES_REGBLKS); @@ -4983,46 +5235,43 @@ */ if (!wasdel && xfs_trans_get_block_res(tp) == 0 && XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && - XFS_IFORK_NEXTENTS(ip, whichfork) >= ifp->if_ext_max && + XFS_IFORK_NEXTENTS(ip, whichfork) >= /* Note the >= */ + XFS_IFORK_MAXEXT(ip, whichfork) && del.br_startoff > got.br_startoff && del.br_startoff + del.br_blockcount < got.br_startoff + got.br_blockcount) { error = XFS_ERROR(ENOSPC); goto error0; } - error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del, - &tmp_logflags, whichfork, rsvd); + error = xfs_bmap_del_extent(ip, tp, &lastx, flist, cur, &del, + &tmp_logflags, whichfork); logflags |= tmp_logflags; if (error) goto error0; bno = del.br_startoff - 1; nodelete: - lastx = ifp->if_lastex; /* * If not done go on to the next (previous) record. - * Reset ep in case the extents array was re-alloced. */ - ep = xfs_iext_get_ext(ifp, lastx); if (bno != (xfs_fileoff_t)-1 && bno >= start) { - if (lastx >= XFS_IFORK_NEXTENTS(ip, whichfork) || - xfs_bmbt_get_startoff(ep) > bno) { - if (--lastx >= 0) - ep = xfs_iext_get_ext(ifp, lastx); - } - if (lastx >= 0) + if (lastx >= 0) { + ep = xfs_iext_get_ext(ifp, lastx); + if (xfs_bmbt_get_startoff(ep) > bno) { + if (--lastx >= 0) + ep = xfs_iext_get_ext(ifp, + lastx); + } xfs_bmbt_get_all(ep, &got); + } extno++; } } - ifp->if_lastex = lastx; *done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0; - ASSERT(ifp->if_ext_max == - XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); + /* * Convert to a btree if necessary. */ - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && - XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max) { + if (xfs_bmap_needs_btree(ip, whichfork)) { ASSERT(cur == NULL); error = xfs_bmap_extents_to_btree(tp, ip, firstblock, flist, &cur, 0, &tmp_logflags, whichfork); @@ -5033,8 +5282,7 @@ /* * transform from btree to extents, give it cur */ - else if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && - XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) { + else if (xfs_bmap_wants_extents(ip, whichfork)) { ASSERT(cur != NULL); error = xfs_bmap_btree_to_extents(tp, ip, cur, &tmp_logflags, whichfork); @@ -5045,8 +5293,6 @@ /* * transform from extents to local? */ - ASSERT(ifp->if_ext_max == - XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); error = 0; error0: /* @@ -5075,243 +5321,3 @@ } return error; } - -/* - * Check the last inode extent to determine whether this allocation will result - * in blocks being allocated at the end of the file. When we allocate new data - * blocks at the end of the file which do not start at the previous data block, - * we will try to align the new blocks at stripe unit boundaries. - */ -STATIC int /* error */ -xfs_bmap_isaeof( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_fileoff_t off, /* file offset in fsblocks */ - int whichfork, /* data or attribute fork */ - char *aeof) /* return value */ -{ - int error; /* error return value */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_bmbt_rec_host_t *lastrec; /* extent record pointer */ - xfs_extnum_t nextents; /* number of file extents */ - xfs_bmbt_irec_t s; /* expanded extent record */ - - ASSERT(whichfork == XFS_DATA_FORK); - ifp = XFS_IFORK_PTR(ip, whichfork); - if (!(ifp->if_flags & XFS_IFEXTENTS) && - (error = xfs_iread_extents(NULL, ip, whichfork))) - return error; - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - if (nextents == 0) { - *aeof = 1; - return 0; - } - /* - * Go to the last extent - */ - lastrec = xfs_iext_get_ext(ifp, nextents - 1); - xfs_bmbt_get_all(lastrec, &s); - /* - * Check we are allocating in the last extent (for delayed allocations) - * or past the last extent for non-delayed allocations. - */ - *aeof = (off >= s.br_startoff && - off < s.br_startoff + s.br_blockcount && - isnullstartblock(s.br_startblock)) || - off >= s.br_startoff + s.br_blockcount; - return 0; -} - -/* - * Check if the endoff is outside the last extent. If so the caller will grow - * the allocation to a stripe unit boundary. - */ -int /* error */ -xfs_bmap_eof( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_fileoff_t endoff, /* file offset in fsblocks */ - int whichfork, /* data or attribute fork */ - int *eof) /* result value */ -{ - xfs_fsblock_t blockcount; /* extent block count */ - int error; /* error return value */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_bmbt_rec_host_t *lastrec; /* extent record pointer */ - xfs_extnum_t nextents; /* number of file extents */ - xfs_fileoff_t startoff; /* extent starting file offset */ - - ASSERT(whichfork == XFS_DATA_FORK); - ifp = XFS_IFORK_PTR(ip, whichfork); - if (!(ifp->if_flags & XFS_IFEXTENTS) && - (error = xfs_iread_extents(NULL, ip, whichfork))) - return error; - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - if (nextents == 0) { - *eof = 1; - return 0; - } - /* - * Go to the last extent - */ - lastrec = xfs_iext_get_ext(ifp, nextents - 1); - startoff = xfs_bmbt_get_startoff(lastrec); - blockcount = xfs_bmbt_get_blockcount(lastrec); - *eof = endoff >= startoff + blockcount; - return 0; -} - -/* - * Count fsblocks of the given fork. - */ -int /* error */ -xfs_bmap_count_blocks( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode */ - int whichfork, /* data or attr fork */ - int *count) /* out: count of blocks */ -{ - struct xfs_btree_block *block; /* current btree block */ - xfs_fsblock_t bno; /* block # of "block" */ - xfs_ifork_t *ifp; /* fork structure */ - int level; /* btree level, for checking */ - xfs_mount_t *mp; /* file system mount structure */ - __be64 *pp; /* pointer to block address */ - - bno = NULLFSBLOCK; - mp = ip->i_mount; - ifp = XFS_IFORK_PTR(ip, whichfork); - if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) { - xfs_bmap_count_leaves(ifp, 0, - ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t), - count); - return 0; - } - - /* - * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. - */ - block = ifp->if_broot; - level = be16_to_cpu(block->bb_level); - ASSERT(level > 0); - pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); - bno = be64_to_cpu(*pp); - ASSERT(bno != NULLDFSBNO); - ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); - ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); - - if (unlikely(xfs_bmap_count_tree(mp, tp, ifp, bno, level, count) < 0)) { - XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW, - mp); - return XFS_ERROR(EFSCORRUPTED); - } - - return 0; -} - -/* - * Recursively walks each level of a btree - * to count total fsblocks is use. - */ -STATIC int /* error */ -xfs_bmap_count_tree( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_ifork_t *ifp, /* inode fork pointer */ - xfs_fsblock_t blockno, /* file system block number */ - int levelin, /* level in btree */ - int *count) /* Count of blocks */ -{ - int error; - xfs_buf_t *bp, *nbp; - int level = levelin; - __be64 *pp; - xfs_fsblock_t bno = blockno; - xfs_fsblock_t nextbno; - struct xfs_btree_block *block, *nextblock; - int numrecs; - - if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF))) - return error; - *count += 1; - block = XFS_BUF_TO_BLOCK(bp); - - if (--level) { - /* Not at node above leaves, count this level of nodes */ - nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib); - while (nextbno != NULLFSBLOCK) { - if ((error = xfs_btree_read_bufl(mp, tp, nextbno, - 0, &nbp, XFS_BMAP_BTREE_REF))) - return error; - *count += 1; - nextblock = XFS_BUF_TO_BLOCK(nbp); - nextbno = be64_to_cpu(nextblock->bb_u.l.bb_rightsib); - xfs_trans_brelse(tp, nbp); - } - - /* Dive to the next level */ - pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); - bno = be64_to_cpu(*pp); - if (unlikely((error = - xfs_bmap_count_tree(mp, tp, ifp, bno, level, count)) < 0)) { - xfs_trans_brelse(tp, bp); - XFS_ERROR_REPORT("xfs_bmap_count_tree(1)", - XFS_ERRLEVEL_LOW, mp); - return XFS_ERROR(EFSCORRUPTED); - } - xfs_trans_brelse(tp, bp); - } else { - /* count all level 1 nodes and their leaves */ - for (;;) { - nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib); - numrecs = be16_to_cpu(block->bb_numrecs); - xfs_bmap_disk_count_leaves(mp, block, numrecs, count); - xfs_trans_brelse(tp, bp); - if (nextbno == NULLFSBLOCK) - break; - bno = nextbno; - if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, - XFS_BMAP_BTREE_REF))) - return error; - *count += 1; - block = XFS_BUF_TO_BLOCK(bp); - } - } - return 0; -} - -/* - * Count leaf blocks given a range of extent records. - */ -STATIC void -xfs_bmap_count_leaves( - xfs_ifork_t *ifp, - xfs_extnum_t idx, - int numrecs, - int *count) -{ - int b; - - for (b = 0; b < numrecs; b++) { - xfs_bmbt_rec_host_t *frp = xfs_iext_get_ext(ifp, idx + b); - *count += xfs_bmbt_get_blockcount(frp); - } -} - -/* - * Count leaf blocks given a range of extent records originally - * in btree format. - */ -STATIC void -xfs_bmap_disk_count_leaves( - struct xfs_mount *mp, - struct xfs_btree_block *block, - int numrecs, - int *count) -{ - int b; - xfs_bmbt_rec_t *frp; - - for (b = 1; b <= numrecs; b++) { - frp = XFS_BMBT_REC_ADDR(mp, block, b); - *count += xfs_bmbt_disk_get_blockcount(frp); - } -} diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_btree.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_btree.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_btree.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_btree.c 2014-06-19 22:42:17.000000000 +0000 @@ -26,9 +26,14 @@ /* * Btree magic numbers. */ -const __uint32_t xfs_magics[XFS_BTNUM_MAX] = { - XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, XFS_BMAP_MAGIC, XFS_IBT_MAGIC +static const __uint32_t xfs_magics[2][XFS_BTNUM_MAX] = { + { XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, XFS_BMAP_MAGIC, XFS_IBT_MAGIC, + XFS_FIBT_MAGIC }, + { XFS_ABTB_CRC_MAGIC, XFS_ABTC_CRC_MAGIC, + XFS_BMAP_CRC_MAGIC, XFS_IBT_CRC_MAGIC, XFS_FIBT_CRC_MAGIC } }; +#define xfs_btree_magic(cur) \ + xfs_magics[!!((cur)->bc_flags & XFS_BTREE_CRC_BLOCKS)][cur->bc_btnum] STATIC int /* error (0 or EFSCORRUPTED) */ @@ -38,30 +43,38 @@ int level, /* level of the btree block */ struct xfs_buf *bp) /* buffer for block, if any */ { - int lblock_ok; /* block passes checks */ + int lblock_ok = 1; /* block passes checks */ struct xfs_mount *mp; /* file system mount point */ mp = cur->bc_mp; - lblock_ok = - be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] && + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + lblock_ok = lblock_ok && + uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid) && + block->bb_u.l.bb_blkno == cpu_to_be64( + bp ? bp->b_bn : XFS_BUF_DADDR_NULL); + } + + lblock_ok = lblock_ok && + be32_to_cpu(block->bb_magic) == xfs_btree_magic(cur) && be16_to_cpu(block->bb_level) == level && be16_to_cpu(block->bb_numrecs) <= cur->bc_ops->get_maxrecs(cur, level) && block->bb_u.l.bb_leftsib && - (be64_to_cpu(block->bb_u.l.bb_leftsib) == NULLDFSBNO || + (block->bb_u.l.bb_leftsib == cpu_to_be64(NULLDFSBNO) || XFS_FSB_SANITY_CHECK(mp, - be64_to_cpu(block->bb_u.l.bb_leftsib))) && + be64_to_cpu(block->bb_u.l.bb_leftsib))) && block->bb_u.l.bb_rightsib && - (be64_to_cpu(block->bb_u.l.bb_rightsib) == NULLDFSBNO || + (block->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO) || XFS_FSB_SANITY_CHECK(mp, - be64_to_cpu(block->bb_u.l.bb_rightsib))); + be64_to_cpu(block->bb_u.l.bb_rightsib))); + if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK, XFS_RANDOM_BTREE_CHECK_LBLOCK))) { if (bp) trace_xfs_btree_corrupt(bp, _RET_IP_); - XFS_ERROR_REPORT("xfs_btree_check_lblock", XFS_ERRLEVEL_LOW, - mp); + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); return XFS_ERROR(EFSCORRUPTED); } return 0; @@ -74,32 +87,42 @@ int level, /* level of the btree block */ struct xfs_buf *bp) /* buffer containing block */ { + struct xfs_mount *mp; /* file system mount point */ struct xfs_buf *agbp; /* buffer for ag. freespace struct */ struct xfs_agf *agf; /* ag. freespace structure */ xfs_agblock_t agflen; /* native ag. freespace length */ - int sblock_ok; /* block passes checks */ + int sblock_ok = 1; /* block passes checks */ + mp = cur->bc_mp; agbp = cur->bc_private.a.agbp; agf = XFS_BUF_TO_AGF(agbp); agflen = be32_to_cpu(agf->agf_length); - sblock_ok = - be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] && + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + sblock_ok = sblock_ok && + uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid) && + block->bb_u.s.bb_blkno == cpu_to_be64( + bp ? bp->b_bn : XFS_BUF_DADDR_NULL); + } + + sblock_ok = sblock_ok && + be32_to_cpu(block->bb_magic) == xfs_btree_magic(cur) && be16_to_cpu(block->bb_level) == level && be16_to_cpu(block->bb_numrecs) <= cur->bc_ops->get_maxrecs(cur, level) && - (be32_to_cpu(block->bb_u.s.bb_leftsib) == NULLAGBLOCK || + (block->bb_u.s.bb_leftsib == cpu_to_be32(NULLAGBLOCK) || be32_to_cpu(block->bb_u.s.bb_leftsib) < agflen) && block->bb_u.s.bb_leftsib && - (be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK || + (block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK) || be32_to_cpu(block->bb_u.s.bb_rightsib) < agflen) && block->bb_u.s.bb_rightsib; - if (unlikely(XFS_TEST_ERROR(!sblock_ok, cur->bc_mp, + + if (unlikely(XFS_TEST_ERROR(!sblock_ok, mp, XFS_ERRTAG_BTREE_CHECK_SBLOCK, XFS_RANDOM_BTREE_CHECK_SBLOCK))) { if (bp) trace_xfs_btree_corrupt(bp, _RET_IP_); - XFS_CORRUPTION_ERROR("xfs_btree_check_sblock", - XFS_ERRLEVEL_LOW, cur->bc_mp, block); + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); return XFS_ERROR(EFSCORRUPTED); } return 0; @@ -178,6 +201,70 @@ #endif /* + * Calculate CRC on the whole btree block and stuff it into the + * long-form btree header. + * + * Prior to calculting the CRC, pull the LSN out of the buffer log item and put + * it into the buffer so recovery knows what the last modifcation was that made + * it to disk. + */ +void +xfs_btree_lblock_calc_crc( + struct xfs_buf *bp) +{ + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); + struct xfs_buf_log_item *bip = bp->b_fspriv; + + if (!xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb)) + return; + if (bip) + block->bb_u.l.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn); + xfs_buf_update_cksum(bp, XFS_BTREE_LBLOCK_CRC_OFF); +} + +bool +xfs_btree_lblock_verify_crc( + struct xfs_buf *bp) +{ + if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb)) + return xfs_buf_verify_cksum(bp, XFS_BTREE_LBLOCK_CRC_OFF); + + return true; +} + +/* + * Calculate CRC on the whole btree block and stuff it into the + * short-form btree header. + * + * Prior to calculting the CRC, pull the LSN out of the buffer log item and put + * it into the buffer so recovery knows what the last modifcation was that made + * it to disk. + */ +void +xfs_btree_sblock_calc_crc( + struct xfs_buf *bp) +{ + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); + struct xfs_buf_log_item *bip = bp->b_fspriv; + + if (!xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb)) + return; + if (bip) + block->bb_u.s.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn); + xfs_buf_update_cksum(bp, XFS_BTREE_SBLOCK_CRC_OFF); +} + +bool +xfs_btree_sblock_verify_crc( + struct xfs_buf *bp) +{ + if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb)) + return xfs_buf_verify_cksum(bp, XFS_BTREE_SBLOCK_CRC_OFF); + + return true; +} + +/* * Delete the btree cursor. */ void @@ -250,18 +337,19 @@ for (i = 0; i < new->bc_nlevels; i++) { new->bc_ptrs[i] = cur->bc_ptrs[i]; new->bc_ra[i] = cur->bc_ra[i]; - if ((bp = cur->bc_bufs[i])) { - if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, - XFS_BUF_ADDR(bp), mp->m_bsize, 0, &bp))) { + bp = cur->bc_bufs[i]; + if (bp) { + error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, + XFS_BUF_ADDR(bp), mp->m_bsize, + 0, &bp, + cur->bc_ops->buf_ops); + if (error) { xfs_btree_del_cursor(new, error); *ncur = NULL; return error; } - new->bc_bufs[i] = bp; - ASSERT(bp); - ASSERT(!XFS_BUF_GETERROR(bp)); - } else - new->bc_bufs[i] = NULL; + } + new->bc_bufs[i] = bp; } *ncur = new; return 0; @@ -302,9 +390,14 @@ */ static inline size_t xfs_btree_block_len(struct xfs_btree_cur *cur) { - return (cur->bc_flags & XFS_BTREE_LONG_PTRS) ? - XFS_BTREE_LBLOCK_LEN : - XFS_BTREE_SBLOCK_LEN; + if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { + if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS) + return XFS_BTREE_LBLOCK_CRC_LEN; + return XFS_BTREE_LBLOCK_LEN; + } + if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS) + return XFS_BTREE_SBLOCK_CRC_LEN; + return XFS_BTREE_SBLOCK_LEN; } /* @@ -398,7 +491,7 @@ } /* - * Get a the root block which is stored in the inode. + * Get the root block which is stored in the inode. * * For now this btree implementation assumes the btree root is always * stored in the if_broot field of an inode fork. @@ -450,8 +543,7 @@ ASSERT(fsbno != NULLFSBLOCK); d = XFS_FSB_TO_DADDR(mp, fsbno); bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock); - ASSERT(bp); - ASSERT(!XFS_BUF_GETERROR(bp)); + ASSERT(!xfs_buf_geterror(bp)); return bp; } @@ -474,8 +566,7 @@ ASSERT(agbno != NULLAGBLOCK); d = XFS_AGB_TO_DADDR(mp, agno, agbno); bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock); - ASSERT(bp); - ASSERT(!XFS_BUF_GETERROR(bp)); + ASSERT(!xfs_buf_geterror(bp)); return bp; } @@ -493,9 +584,9 @@ block = xfs_btree_get_block(cur, level, &bp); xfs_btree_check_block(cur, block, level, bp); if (cur->bc_flags & XFS_BTREE_LONG_PTRS) - return be64_to_cpu(block->bb_u.l.bb_rightsib) == NULLDFSBNO; + return block->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO); else - return be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK; + return block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK); } /* @@ -596,71 +687,71 @@ * Get a buffer for the block, return it read in. * Long-form addressing. */ -int /* error */ +int xfs_btree_read_bufl( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_fsblock_t fsbno, /* file system block number */ - uint lock, /* lock flags for read_buf */ - xfs_buf_t **bpp, /* buffer for fsbno */ - int refval) /* ref count value for buffer */ + struct xfs_mount *mp, /* file system mount point */ + struct xfs_trans *tp, /* transaction pointer */ + xfs_fsblock_t fsbno, /* file system block number */ + uint lock, /* lock flags for read_buf */ + struct xfs_buf **bpp, /* buffer for fsbno */ + int refval, /* ref count value for buffer */ + const struct xfs_buf_ops *ops) { - xfs_buf_t *bp; /* return value */ + struct xfs_buf *bp; /* return value */ xfs_daddr_t d; /* real disk block address */ - int error; + int error; ASSERT(fsbno != NULLFSBLOCK); d = XFS_FSB_TO_DADDR(mp, fsbno); - if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d, - mp->m_bsize, lock, &bp))) { + error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d, + mp->m_bsize, lock, &bp, ops); + if (error) return error; - } - ASSERT(!bp || !XFS_BUF_GETERROR(bp)); - if (bp != NULL) { - XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval); - } + ASSERT(!xfs_buf_geterror(bp)); + if (bp) + xfs_buf_set_ref(bp, refval); *bpp = bp; return 0; } /* - * Get a buffer for the block, return it read in. + * Read-ahead the block, don't wait for it, don't return a buffer. + * Long-form addressing. + */ +/* ARGSUSED */ +void +xfs_btree_reada_bufl( + struct xfs_mount *mp, /* file system mount point */ + xfs_fsblock_t fsbno, /* file system block number */ + xfs_extlen_t count, /* count of filesystem blocks */ + const struct xfs_buf_ops *ops) +{ + xfs_daddr_t d; + + ASSERT(fsbno != NULLFSBLOCK); + d = XFS_FSB_TO_DADDR(mp, fsbno); + xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, ops); +} + +/* + * Read-ahead the block, don't wait for it, don't return a buffer. * Short-form addressing. */ -int /* error */ -xfs_btree_read_bufs( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_agnumber_t agno, /* allocation group number */ - xfs_agblock_t agbno, /* allocation group block number */ - uint lock, /* lock flags for read_buf */ - xfs_buf_t **bpp, /* buffer for agno/agbno */ - int refval) /* ref count value for buffer */ -{ - xfs_buf_t *bp; /* return value */ - xfs_daddr_t d; /* real disk block address */ - int error; +/* ARGSUSED */ +void +xfs_btree_reada_bufs( + struct xfs_mount *mp, /* file system mount point */ + xfs_agnumber_t agno, /* allocation group number */ + xfs_agblock_t agbno, /* allocation group block number */ + xfs_extlen_t count, /* count of filesystem blocks */ + const struct xfs_buf_ops *ops) +{ + xfs_daddr_t d; ASSERT(agno != NULLAGNUMBER); ASSERT(agbno != NULLAGBLOCK); d = XFS_AGB_TO_DADDR(mp, agno, agbno); - if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d, - mp->m_bsize, lock, &bp))) { - return error; - } - ASSERT(!bp || !XFS_BUF_GETERROR(bp)); - if (bp != NULL) { - switch (refval) { - case XFS_ALLOC_BTREE_REF: - XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval); - break; - case XFS_INO_BTREE_REF: - XFS_BUF_SET_VTYPE_REF(bp, B_FS_INOMAP, refval); - break; - } - } - *bpp = bp; - return 0; + xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, ops); } STATIC int @@ -674,12 +765,14 @@ xfs_dfsbno_t right = be64_to_cpu(block->bb_u.l.bb_rightsib); if ((lr & XFS_BTCUR_LEFTRA) && left != NULLDFSBNO) { - xfs_btree_reada_bufl(cur->bc_mp, left, 1); + xfs_btree_reada_bufl(cur->bc_mp, left, 1, + cur->bc_ops->buf_ops); rval++; } if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLDFSBNO) { - xfs_btree_reada_bufl(cur->bc_mp, right, 1); + xfs_btree_reada_bufl(cur->bc_mp, right, 1, + cur->bc_ops->buf_ops); rval++; } @@ -699,13 +792,13 @@ if ((lr & XFS_BTCUR_LEFTRA) && left != NULLAGBLOCK) { xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, - left, 1); + left, 1, cur->bc_ops->buf_ops); rval++; } if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLAGBLOCK) { xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, - right, 1); + right, 1, cur->bc_ops->buf_ops); rval++; } @@ -743,6 +836,41 @@ return xfs_btree_readahead_sblock(cur, lr, block); } +STATIC xfs_daddr_t +xfs_btree_ptr_to_daddr( + struct xfs_btree_cur *cur, + union xfs_btree_ptr *ptr) +{ + if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { + ASSERT(ptr->l != cpu_to_be64(NULLDFSBNO)); + + return XFS_FSB_TO_DADDR(cur->bc_mp, be64_to_cpu(ptr->l)); + } else { + ASSERT(cur->bc_private.a.agno != NULLAGNUMBER); + ASSERT(ptr->s != cpu_to_be32(NULLAGBLOCK)); + + return XFS_AGB_TO_DADDR(cur->bc_mp, cur->bc_private.a.agno, + be32_to_cpu(ptr->s)); + } +} + +/* + * Readahead @count btree blocks at the given @ptr location. + * + * We don't need to care about long or short form btrees here as we have a + * method of converting the ptr directly to a daddr available to us. + */ +STATIC void +xfs_btree_readahead_ptr( + struct xfs_btree_cur *cur, + union xfs_btree_ptr *ptr, + xfs_extlen_t count) +{ + xfs_buf_readahead(cur->bc_mp->m_ddev_targp, + xfs_btree_ptr_to_daddr(cur, ptr), + cur->bc_mp->m_bsize * count, cur->bc_ops->buf_ops); +} + /* * Set the buffer for level "lev" in the cursor to bp, releasing * any previous buffer. @@ -762,14 +890,14 @@ b = XFS_BUF_TO_BLOCK(bp); if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { - if (be64_to_cpu(b->bb_u.l.bb_leftsib) == NULLDFSBNO) + if (b->bb_u.l.bb_leftsib == cpu_to_be64(NULLDFSBNO)) cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA; - if (be64_to_cpu(b->bb_u.l.bb_rightsib) == NULLDFSBNO) + if (b->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO)) cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA; } else { - if (be32_to_cpu(b->bb_u.s.bb_leftsib) == NULLAGBLOCK) + if (b->bb_u.s.bb_leftsib == cpu_to_be32(NULLAGBLOCK)) cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA; - if (be32_to_cpu(b->bb_u.s.bb_rightsib) == NULLAGBLOCK) + if (b->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK)) cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA; } } @@ -780,9 +908,9 @@ union xfs_btree_ptr *ptr) { if (cur->bc_flags & XFS_BTREE_LONG_PTRS) - return be64_to_cpu(ptr->l) == NULLDFSBNO; + return ptr->l == cpu_to_be64(NULLDFSBNO); else - return be32_to_cpu(ptr->s) == NULLAGBLOCK; + return ptr->s == cpu_to_be32(NULLAGBLOCK); } STATIC void @@ -843,29 +971,88 @@ } } -STATIC void +void +xfs_btree_init_block_int( + struct xfs_mount *mp, + struct xfs_btree_block *buf, + xfs_daddr_t blkno, + __u32 magic, + __u16 level, + __u16 numrecs, + __u64 owner, + unsigned int flags) +{ + buf->bb_magic = cpu_to_be32(magic); + buf->bb_level = cpu_to_be16(level); + buf->bb_numrecs = cpu_to_be16(numrecs); + + if (flags & XFS_BTREE_LONG_PTRS) { + buf->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO); + buf->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO); + if (flags & XFS_BTREE_CRC_BLOCKS) { + buf->bb_u.l.bb_blkno = cpu_to_be64(blkno); + buf->bb_u.l.bb_owner = cpu_to_be64(owner); + uuid_copy(&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid); + buf->bb_u.l.bb_pad = 0; + buf->bb_u.l.bb_lsn = 0; + } + } else { + /* owner is a 32 bit value on short blocks */ + __u32 __owner = (__u32)owner; + + buf->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); + buf->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); + if (flags & XFS_BTREE_CRC_BLOCKS) { + buf->bb_u.s.bb_blkno = cpu_to_be64(blkno); + buf->bb_u.s.bb_owner = cpu_to_be32(__owner); + uuid_copy(&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid); + buf->bb_u.s.bb_lsn = 0; + } + } +} + +void xfs_btree_init_block( + struct xfs_mount *mp, + struct xfs_buf *bp, + __u32 magic, + __u16 level, + __u16 numrecs, + __u64 owner, + unsigned int flags) +{ + xfs_btree_init_block_int(mp, XFS_BUF_TO_BLOCK(bp), bp->b_bn, + magic, level, numrecs, owner, flags); +} + +STATIC void +xfs_btree_init_block_cur( struct xfs_btree_cur *cur, + struct xfs_buf *bp, int level, - int numrecs, - struct xfs_btree_block *new) /* new block */ + int numrecs) { - new->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]); - new->bb_level = cpu_to_be16(level); - new->bb_numrecs = cpu_to_be16(numrecs); + __u64 owner; - if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { - new->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO); - new->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO); - } else { - new->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); - new->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); - } + /* + * we can pull the owner from the cursor right now as the different + * owners align directly with the pointer size of the btree. This may + * change in future, but is safe for current users of the generic btree + * code. + */ + if (cur->bc_flags & XFS_BTREE_LONG_PTRS) + owner = cur->bc_private.b.ip->i_ino; + else + owner = cur->bc_private.a.agno; + + xfs_btree_init_block_int(cur->bc_mp, XFS_BUF_TO_BLOCK(bp), bp->b_bn, + xfs_btree_magic(cur), level, numrecs, + owner, cur->bc_flags); } /* * Return true if ptr is the last record in the btree and - * we need to track updateѕ to this record. The decision + * we need to track updates to this record. The decision * will be further refined in the update_lastrec method. */ STATIC int @@ -902,24 +1089,6 @@ } } -STATIC xfs_daddr_t -xfs_btree_ptr_to_daddr( - struct xfs_btree_cur *cur, - union xfs_btree_ptr *ptr) -{ - if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { - ASSERT(be64_to_cpu(ptr->l) != NULLDFSBNO); - - return XFS_FSB_TO_DADDR(cur->bc_mp, be64_to_cpu(ptr->l)); - } else { - ASSERT(cur->bc_private.a.agno != NULLAGNUMBER); - ASSERT(be32_to_cpu(ptr->s) != NULLAGBLOCK); - - return XFS_AGB_TO_DADDR(cur->bc_mp, cur->bc_private.a.agno, - be32_to_cpu(ptr->s)); - } -} - STATIC void xfs_btree_set_refs( struct xfs_btree_cur *cur, @@ -928,13 +1097,14 @@ switch (cur->bc_btnum) { case XFS_BTNUM_BNO: case XFS_BTNUM_CNT: - XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, XFS_ALLOC_BTREE_REF); + xfs_buf_set_ref(bp, XFS_ALLOC_BTREE_REF); break; case XFS_BTNUM_INO: - XFS_BUF_SET_VTYPE_REF(bp, B_FS_INOMAP, XFS_INO_BTREE_REF); + case XFS_BTNUM_FINO: + xfs_buf_set_ref(bp, XFS_INO_BTREE_REF); break; case XFS_BTNUM_BMAP: - XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, XFS_BMAP_BTREE_REF); + xfs_buf_set_ref(bp, XFS_BMAP_BTREE_REF); break; default: ASSERT(0); @@ -959,9 +1129,10 @@ *bpp = xfs_trans_get_buf(cur->bc_tp, mp->m_ddev_targp, d, mp->m_bsize, flags); - ASSERT(*bpp); - ASSERT(!XFS_BUF_GETERROR(*bpp)); + if (!*bpp) + return ENOMEM; + (*bpp)->b_ops = cur->bc_ops->buf_ops; *block = XFS_BUF_TO_BLOCK(*bpp); return 0; } @@ -988,20 +1159,15 @@ d = xfs_btree_ptr_to_daddr(cur, ptr); error = xfs_trans_read_buf(mp, cur->bc_tp, mp->m_ddev_targp, d, - mp->m_bsize, flags, bpp); + mp->m_bsize, flags, bpp, + cur->bc_ops->buf_ops); if (error) return error; - ASSERT(*bpp != NULL); - ASSERT(!XFS_BUF_GETERROR(*bpp)); - + ASSERT(!xfs_buf_geterror(*bpp)); xfs_btree_set_refs(cur, *bpp); *block = XFS_BUF_TO_BLOCK(*bpp); - - error = xfs_btree_check_block(cur, *block, level, *bpp); - if (error) - xfs_trans_brelse(cur->bc_tp, *bpp); - return error; + return 0; } /* @@ -1117,6 +1283,7 @@ XFS_BTREE_TRACE_ARGBII(cur, bp, first, last); if (bp) { + xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF); xfs_trans_log_buf(cur->bc_tp, bp, xfs_btree_key_offset(cur, first), xfs_btree_key_offset(cur, last + 1) - 1); @@ -1141,6 +1308,7 @@ XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_TRACE_ARGBII(cur, bp, first, last); + xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF); xfs_trans_log_buf(cur->bc_tp, bp, xfs_btree_rec_offset(cur, first), xfs_btree_rec_offset(cur, last + 1) - 1); @@ -1165,6 +1333,7 @@ struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); int level = xfs_btree_get_level(block); + xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF); xfs_trans_log_buf(cur->bc_tp, bp, xfs_btree_ptr_offset(cur, first, level), xfs_btree_ptr_offset(cur, last + 1, level) - 1); @@ -1193,7 +1362,12 @@ offsetof(struct xfs_btree_block, bb_numrecs), offsetof(struct xfs_btree_block, bb_u.s.bb_leftsib), offsetof(struct xfs_btree_block, bb_u.s.bb_rightsib), - XFS_BTREE_SBLOCK_LEN + offsetof(struct xfs_btree_block, bb_u.s.bb_blkno), + offsetof(struct xfs_btree_block, bb_u.s.bb_lsn), + offsetof(struct xfs_btree_block, bb_u.s.bb_uuid), + offsetof(struct xfs_btree_block, bb_u.s.bb_owner), + offsetof(struct xfs_btree_block, bb_u.s.bb_crc), + XFS_BTREE_SBLOCK_CRC_LEN }; static const short loffsets[] = { /* table of offsets (long) */ offsetof(struct xfs_btree_block, bb_magic), @@ -1201,17 +1375,40 @@ offsetof(struct xfs_btree_block, bb_numrecs), offsetof(struct xfs_btree_block, bb_u.l.bb_leftsib), offsetof(struct xfs_btree_block, bb_u.l.bb_rightsib), - XFS_BTREE_LBLOCK_LEN + offsetof(struct xfs_btree_block, bb_u.l.bb_blkno), + offsetof(struct xfs_btree_block, bb_u.l.bb_lsn), + offsetof(struct xfs_btree_block, bb_u.l.bb_uuid), + offsetof(struct xfs_btree_block, bb_u.l.bb_owner), + offsetof(struct xfs_btree_block, bb_u.l.bb_crc), + offsetof(struct xfs_btree_block, bb_u.l.bb_pad), + XFS_BTREE_LBLOCK_CRC_LEN }; XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_TRACE_ARGBI(cur, bp, fields); if (bp) { + int nbits; + + if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS) { + /* + * We don't log the CRC when updating a btree + * block but instead recreate it during log + * recovery. As the log buffers have checksums + * of their own this is safe and avoids logging a crc + * update in a lot of places. + */ + if (fields == XFS_BB_ALL_BITS) + fields = XFS_BB_ALL_BITS_CRC; + nbits = XFS_BB_NUM_BITS_CRC; + } else { + nbits = XFS_BB_NUM_BITS; + } xfs_btree_offsets(fields, (cur->bc_flags & XFS_BTREE_LONG_PTRS) ? loffsets : soffsets, - XFS_BB_NUM_BITS, &first, &last); + nbits, &first, &last); + xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF); xfs_trans_log_buf(cur->bc_tp, bp, first, last); } else { xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, @@ -1488,7 +1685,7 @@ /* * Lookup the record. The cursor is made to point to it, based on dir. - * Return 0 if can't find any such record, 1 for success. + * stat is set to 0 if can't find any such record, 1 for success. */ int /* error */ xfs_btree_lookup( @@ -2174,7 +2371,7 @@ goto error0; /* Fill in the btree header for the new right block. */ - xfs_btree_init_block(cur, xfs_btree_get_level(left), 0, right); + xfs_btree_init_block_cur(cur, rbp, xfs_btree_get_level(left), 0); /* * Split the entries between the old and the new block evenly. @@ -2348,7 +2545,17 @@ if (error) goto error0; + /* + * we can't just memcpy() the root in for CRC enabled btree blocks. + * In that case have to also ensure the blkno remains correct + */ memcpy(cblock, block, xfs_btree_block_len(cur)); + if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS) { + if (cur->bc_flags & XFS_BTREE_LONG_PTRS) + cblock->bb_u.l.bb_blkno = cpu_to_be64(cbp->b_bn); + else + cblock->bb_u.s.bb_blkno = cpu_to_be64(cbp->b_bn); + } be16_add_cpu(&block->bb_level, 1); xfs_btree_set_numrecs(block, 1); @@ -2483,7 +2690,7 @@ nptr = 2; } /* Fill in the new block's btree header and log it. */ - xfs_btree_init_block(cur, cur->bc_nlevels, 2, new); + xfs_btree_init_block_cur(cur, nbp, cur->bc_nlevels, 2); xfs_btree_log_block(cur, nbp, XFS_BB_ALL_BITS); ASSERT(!xfs_btree_ptr_is_null(cur, &lptr) && !xfs_btree_ptr_is_null(cur, &rptr)); @@ -2550,7 +2757,6 @@ if (numrecs < cur->bc_ops->get_dmaxrecs(cur, level)) { /* A root block that can be made bigger. */ - xfs_iroot_realloc(ip, 1, cur->bc_private.b.whichfork); } else { /* A root block that needs replacing */ @@ -3662,3 +3868,120 @@ *stat = 1; return 0; } + +/* + * Change the owner of a btree. + * + * The mechanism we use here is ordered buffer logging. Because we don't know + * how many buffers were are going to need to modify, we don't really want to + * have to make transaction reservations for the worst case of every buffer in a + * full size btree as that may be more space that we can fit in the log.... + * + * We do the btree walk in the most optimal manner possible - we have sibling + * pointers so we can just walk all the blocks on each level from left to right + * in a single pass, and then move to the next level and do the same. We can + * also do readahead on the sibling pointers to get IO moving more quickly, + * though for slow disks this is unlikely to make much difference to performance + * as the amount of CPU work we have to do before moving to the next block is + * relatively small. + * + * For each btree block that we load, modify the owner appropriately, set the + * buffer as an ordered buffer and log it appropriately. We need to ensure that + * we mark the region we change dirty so that if the buffer is relogged in + * a subsequent transaction the changes we make here as an ordered buffer are + * correctly relogged in that transaction. If we are in recovery context, then + * just queue the modified buffer as delayed write buffer so the transaction + * recovery completion writes the changes to disk. + */ +static int +xfs_btree_block_change_owner( + struct xfs_btree_cur *cur, + int level, + __uint64_t new_owner, + struct list_head *buffer_list) +{ + struct xfs_btree_block *block; + struct xfs_buf *bp; + union xfs_btree_ptr rptr; + + /* do right sibling readahead */ + xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA); + + /* modify the owner */ + block = xfs_btree_get_block(cur, level, &bp); + if (cur->bc_flags & XFS_BTREE_LONG_PTRS) + block->bb_u.l.bb_owner = cpu_to_be64(new_owner); + else + block->bb_u.s.bb_owner = cpu_to_be32(new_owner); + + /* + * If the block is a root block hosted in an inode, we might not have a + * buffer pointer here and we shouldn't attempt to log the change as the + * information is already held in the inode and discarded when the root + * block is formatted into the on-disk inode fork. We still change it, + * though, so everything is consistent in memory. + */ + if (bp) { + if (cur->bc_tp) { + xfs_trans_ordered_buf(cur->bc_tp, bp); + xfs_btree_log_block(cur, bp, XFS_BB_OWNER); + } else { + xfs_buf_delwri_queue(bp, buffer_list); + } + } else { + ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE); + ASSERT(level == cur->bc_nlevels - 1); + } + + /* now read rh sibling block for next iteration */ + xfs_btree_get_sibling(cur, block, &rptr, XFS_BB_RIGHTSIB); + if (xfs_btree_ptr_is_null(cur, &rptr)) + return ENOENT; + + return xfs_btree_lookup_get_block(cur, level, &rptr, &block); +} + +int +xfs_btree_change_owner( + struct xfs_btree_cur *cur, + __uint64_t new_owner, + struct list_head *buffer_list) +{ + union xfs_btree_ptr lptr; + int level; + struct xfs_btree_block *block = NULL; + int error = 0; + + cur->bc_ops->init_ptr_from_cur(cur, &lptr); + + /* for each level */ + for (level = cur->bc_nlevels - 1; level >= 0; level--) { + /* grab the left hand block */ + error = xfs_btree_lookup_get_block(cur, level, &lptr, &block); + if (error) + return error; + + /* readahead the left most block for the next level down */ + if (level > 0) { + union xfs_btree_ptr *ptr; + + ptr = xfs_btree_ptr_addr(cur, 1, block); + xfs_btree_readahead_ptr(cur, ptr, 1); + + /* save for the next iteration of the loop */ + lptr = *ptr; + } + + /* for each buffer in the level */ + do { + error = xfs_btree_block_change_owner(cur, level, + new_owner, + buffer_list); + } while (!error); + + if (error != ENOENT) + return error; + } + + return 0; +} diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_da_btree.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_da_btree.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_da_btree.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_da_btree.c 2014-06-19 22:42:17.000000000 +0000 @@ -1,5 +1,6 @@ /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * Copyright (c) 2013 Red Hat, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -31,44 +32,284 @@ /* * Routines used for growing the Btree. */ -STATIC int xfs_da_root_split(xfs_da_state_t *state, +STATIC int xfs_da3_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *existing_root, xfs_da_state_blk_t *new_child); -STATIC int xfs_da_node_split(xfs_da_state_t *state, +STATIC int xfs_da3_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *existing_blk, xfs_da_state_blk_t *split_blk, xfs_da_state_blk_t *blk_to_add, int treelevel, int *result); -STATIC void xfs_da_node_rebalance(xfs_da_state_t *state, +STATIC void xfs_da3_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *node_blk_1, xfs_da_state_blk_t *node_blk_2); -STATIC void xfs_da_node_add(xfs_da_state_t *state, +STATIC void xfs_da3_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *old_node_blk, xfs_da_state_blk_t *new_node_blk); /* * Routines used for shrinking the Btree. */ -STATIC int xfs_da_root_join(xfs_da_state_t *state, +STATIC int xfs_da3_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk); -STATIC int xfs_da_node_toosmall(xfs_da_state_t *state, int *retval); -STATIC void xfs_da_node_remove(xfs_da_state_t *state, +STATIC int xfs_da3_node_toosmall(xfs_da_state_t *state, int *retval); +STATIC void xfs_da3_node_remove(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk); -STATIC void xfs_da_node_unbalance(xfs_da_state_t *state, +STATIC void xfs_da3_node_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *src_node_blk, xfs_da_state_blk_t *dst_node_blk); /* * Utility routines. */ -STATIC uint xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count); -STATIC int xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp); -STATIC xfs_dabuf_t *xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra); -STATIC int xfs_da_blk_unlink(xfs_da_state_t *state, +STATIC int xfs_da3_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, xfs_da_state_blk_t *save_blk); -STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state); + + +kmem_zone_t *xfs_da_state_zone; /* anchor for state struct zone */ + +/* + * Allocate a dir-state structure. + * We don't put them on the stack since they're large. + */ +xfs_da_state_t * +xfs_da_state_alloc(void) +{ + return kmem_zone_zalloc(xfs_da_state_zone, KM_NOFS); +} + +/* + * Kill the altpath contents of a da-state structure. + */ +STATIC void +xfs_da_state_kill_altpath(xfs_da_state_t *state) +{ + int i; + + for (i = 0; i < state->altpath.active; i++) + state->altpath.blk[i].bp = NULL; + state->altpath.active = 0; +} + +/* + * Free a da-state structure. + */ +void +xfs_da_state_free(xfs_da_state_t *state) +{ + xfs_da_state_kill_altpath(state); +#ifdef DEBUG + memset((char *)state, 0, sizeof(*state)); +#endif /* DEBUG */ + kmem_zone_free(xfs_da_state_zone, state); +} + +void +xfs_da3_node_hdr_from_disk( + struct xfs_da3_icnode_hdr *to, + struct xfs_da_intnode *from) +{ + ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC) || + from->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC)); + + if (from->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC)) { + struct xfs_da3_node_hdr *hdr3 = (struct xfs_da3_node_hdr *)from; + + to->forw = be32_to_cpu(hdr3->info.hdr.forw); + to->back = be32_to_cpu(hdr3->info.hdr.back); + to->magic = be16_to_cpu(hdr3->info.hdr.magic); + to->count = be16_to_cpu(hdr3->__count); + to->level = be16_to_cpu(hdr3->__level); + return; + } + to->forw = be32_to_cpu(from->hdr.info.forw); + to->back = be32_to_cpu(from->hdr.info.back); + to->magic = be16_to_cpu(from->hdr.info.magic); + to->count = be16_to_cpu(from->hdr.__count); + to->level = be16_to_cpu(from->hdr.__level); +} + +void +xfs_da3_node_hdr_to_disk( + struct xfs_da_intnode *to, + struct xfs_da3_icnode_hdr *from) +{ + ASSERT(from->magic == XFS_DA_NODE_MAGIC || + from->magic == XFS_DA3_NODE_MAGIC); + + if (from->magic == XFS_DA3_NODE_MAGIC) { + struct xfs_da3_node_hdr *hdr3 = (struct xfs_da3_node_hdr *)to; + + hdr3->info.hdr.forw = cpu_to_be32(from->forw); + hdr3->info.hdr.back = cpu_to_be32(from->back); + hdr3->info.hdr.magic = cpu_to_be16(from->magic); + hdr3->__count = cpu_to_be16(from->count); + hdr3->__level = cpu_to_be16(from->level); + return; + } + to->hdr.info.forw = cpu_to_be32(from->forw); + to->hdr.info.back = cpu_to_be32(from->back); + to->hdr.info.magic = cpu_to_be16(from->magic); + to->hdr.__count = cpu_to_be16(from->count); + to->hdr.__level = cpu_to_be16(from->level); +} + +static bool +xfs_da3_node_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_da_intnode *hdr = bp->b_addr; + struct xfs_da3_icnode_hdr ichdr; + + xfs_da3_node_hdr_from_disk(&ichdr, hdr); + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + struct xfs_da3_node_hdr *hdr3 = bp->b_addr; + + if (ichdr.magic != XFS_DA3_NODE_MAGIC) + return false; + + if (!uuid_equal(&hdr3->info.uuid, &mp->m_sb.sb_uuid)) + return false; + if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn) + return false; + } else { + if (ichdr.magic != XFS_DA_NODE_MAGIC) + return false; + } + if (ichdr.level == 0) + return false; + if (ichdr.level > XFS_DA_NODE_MAXDEPTH) + return false; + if (ichdr.count == 0) + return false; + + /* + * we don't know if the node is for and attribute or directory tree, + * so only fail if the count is outside both bounds + */ + if (ichdr.count > mp->m_dir_node_ents && + ichdr.count > mp->m_attr_node_ents) + return false; + + /* XXX: hash order check? */ + + return true; +} + +static void +xfs_da3_node_write_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_da3_node_hdr *hdr3 = bp->b_addr; + + if (!xfs_da3_node_verify(bp)) { + xfs_buf_ioerror(bp, EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return; + + if (bip) + hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn); + + xfs_buf_update_cksum(bp, XFS_DA3_NODE_CRC_OFF); +} + +/* + * leaf/node format detection on trees is sketchy, so a node read can be done on + * leaf level blocks when detection identifies the tree as a node format tree + * incorrectly. In this case, we need to swap the verifier to match the correct + * format of the block being read. + */ +static void +xfs_da3_node_read_verify( + struct xfs_buf *bp) +{ + struct xfs_da_blkinfo *info = bp->b_addr; + + switch (be16_to_cpu(info->magic)) { + case XFS_DA3_NODE_MAGIC: + if (!xfs_buf_verify_cksum(bp, XFS_DA3_NODE_CRC_OFF)) { + xfs_buf_ioerror(bp, EFSBADCRC); + break; + } + /* fall through */ + case XFS_DA_NODE_MAGIC: + if (!xfs_da3_node_verify(bp)) { + xfs_buf_ioerror(bp, EFSCORRUPTED); + break; + } + return; + case XFS_ATTR_LEAF_MAGIC: + case XFS_ATTR3_LEAF_MAGIC: + bp->b_ops = &xfs_attr3_leaf_buf_ops; + bp->b_ops->verify_read(bp); + return; + case XFS_DIR2_LEAFN_MAGIC: + case XFS_DIR3_LEAFN_MAGIC: + bp->b_ops = &xfs_dir3_leafn_buf_ops; + bp->b_ops->verify_read(bp); + return; + default: + break; + } + + /* corrupt block */ + xfs_verifier_error(bp); +} + +const struct xfs_buf_ops xfs_da3_node_buf_ops = { + .verify_read = xfs_da3_node_read_verify, + .verify_write = xfs_da3_node_write_verify, +}; + +int +xfs_da3_node_read( + struct xfs_trans *tp, + struct xfs_inode *dp, + xfs_dablk_t bno, + xfs_daddr_t mappedbno, + struct xfs_buf **bpp, + int which_fork) +{ + int err; + + err = xfs_da_read_buf(tp, dp, bno, mappedbno, bpp, + which_fork, &xfs_da3_node_buf_ops); + if (!err && tp) { + struct xfs_da_blkinfo *info = (*bpp)->b_addr; + int type; + + switch (be16_to_cpu(info->magic)) { + case XFS_DA_NODE_MAGIC: + case XFS_DA3_NODE_MAGIC: + type = XFS_BLFT_DA_NODE_BUF; + break; + case XFS_ATTR_LEAF_MAGIC: + case XFS_ATTR3_LEAF_MAGIC: + type = XFS_BLFT_ATTR_LEAF_BUF; + break; + case XFS_DIR2_LEAFN_MAGIC: + case XFS_DIR3_LEAFN_MAGIC: + type = XFS_BLFT_DIR_LEAFN_BUF; + break; + default: + type = 0; + ASSERT(0); + break; + } + xfs_trans_buf_set_type(tp, *bpp, type); + } + return err; +} /*======================================================================== * Routines used for growing the Btree. @@ -78,29 +319,45 @@ * Create the initial contents of an intermediate node. */ int -xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level, - xfs_dabuf_t **bpp, int whichfork) -{ - xfs_da_intnode_t *node; - xfs_dabuf_t *bp; - int error; - xfs_trans_t *tp; +xfs_da3_node_create( + struct xfs_da_args *args, + xfs_dablk_t blkno, + int level, + struct xfs_buf **bpp, + int whichfork) +{ + struct xfs_da_intnode *node; + struct xfs_trans *tp = args->trans; + struct xfs_mount *mp = tp->t_mountp; + struct xfs_da3_icnode_hdr ichdr = {0}; + struct xfs_buf *bp; + int error; + + trace_xfs_da_node_create(args); + ASSERT(level <= XFS_DA_NODE_MAXDEPTH); - tp = args->trans; error = xfs_da_get_buf(tp, args->dp, blkno, -1, &bp, whichfork); if (error) return(error); - ASSERT(bp != NULL); - node = bp->data; - node->hdr.info.forw = 0; - node->hdr.info.back = 0; - node->hdr.info.magic = cpu_to_be16(XFS_DA_NODE_MAGIC); - node->hdr.info.pad = 0; - node->hdr.count = 0; - node->hdr.level = cpu_to_be16(level); + bp->b_ops = &xfs_da3_node_buf_ops; + xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DA_NODE_BUF); + node = bp->b_addr; + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + struct xfs_da3_node_hdr *hdr3 = bp->b_addr; + + ichdr.magic = XFS_DA3_NODE_MAGIC; + hdr3->info.blkno = cpu_to_be64(bp->b_bn); + hdr3->info.owner = cpu_to_be64(args->dp->i_ino); + uuid_copy(&hdr3->info.uuid, &mp->m_sb.sb_uuid); + } else { + ichdr.magic = XFS_DA_NODE_MAGIC; + } + ichdr.level = level; - xfs_da_log_buf(tp, bp, - XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); + xfs_da3_node_hdr_to_disk(node, &ichdr); + xfs_trans_log_buf(tp, bp, + XFS_DA_LOGRANGE(node, &node->hdr, xfs_da3_node_hdr_size(node))); *bpp = bp; return(0); @@ -111,12 +368,20 @@ * intermediate nodes, rebalance, etc. */ int /* error */ -xfs_da_split(xfs_da_state_t *state) +xfs_da3_split( + struct xfs_da_state *state) { - xfs_da_state_blk_t *oldblk, *newblk, *addblk; - xfs_da_intnode_t *node; - xfs_dabuf_t *bp; - int max, action, error, i; + struct xfs_da_state_blk *oldblk; + struct xfs_da_state_blk *newblk; + struct xfs_da_state_blk *addblk; + struct xfs_da_intnode *node; + struct xfs_buf *bp; + int max; + int action = 0; + int error; + int i; + + trace_xfs_da_split(state->args); /* * Walk back up the tree splitting/inserting/adjusting as necessary. @@ -142,7 +407,7 @@ */ switch (oldblk->magic) { case XFS_ATTR_LEAF_MAGIC: - error = xfs_attr_leaf_split(state, oldblk, newblk); + error = xfs_attr3_leaf_split(state, oldblk, newblk); if ((error != 0) && (error != ENOSPC)) { return(error); /* GROT: attr is inconsistent */ } @@ -156,11 +421,13 @@ state->extravalid = 1; if (state->inleaf) { state->extraafter = 0; /* before newblk */ - error = xfs_attr_leaf_split(state, oldblk, + trace_xfs_attr_leaf_split_before(state->args); + error = xfs_attr3_leaf_split(state, oldblk, &state->extrablk); } else { state->extraafter = 1; /* after newblk */ - error = xfs_attr_leaf_split(state, newblk, + trace_xfs_attr_leaf_split_after(state->args); + error = xfs_attr3_leaf_split(state, newblk, &state->extrablk); } if (error) @@ -174,9 +441,8 @@ addblk = newblk; break; case XFS_DA_NODE_MAGIC: - error = xfs_da_node_split(state, oldblk, newblk, addblk, + error = xfs_da3_node_split(state, oldblk, newblk, addblk, max - i, &action); - xfs_da_buf_done(addblk->bp); addblk->bp = NULL; if (error) return(error); /* GROT: dir is inconsistent */ @@ -193,14 +459,7 @@ /* * Update the btree to show the new hashval for this child. */ - xfs_da_fixhashpath(state, &state->path); - /* - * If we won't need this block again, it's getting dropped - * from the active path by the loop control, so we need - * to mark it done now. - */ - if (i > 0 || !addblk) - xfs_da_buf_done(oldblk->bp); + xfs_da3_fixhashpath(state, &state->path); } if (!addblk) return(0); @@ -210,10 +469,8 @@ */ ASSERT(state->path.active == 0); oldblk = &state->path.blk[0]; - error = xfs_da_root_split(state, oldblk, addblk); + error = xfs_da3_root_split(state, oldblk, addblk); if (error) { - xfs_da_buf_done(oldblk->bp); - xfs_da_buf_done(addblk->bp); addblk->bp = NULL; return(error); /* GROT: dir is inconsistent */ } @@ -223,9 +480,13 @@ * just got bumped because of the addition of a new root node. * There might be three blocks involved if a double split occurred, * and the original block 0 could be at any position in the list. + * + * Note: the magic numbers and sibling pointers are in the same + * physical place for both v2 and v3 headers (by design). Hence it + * doesn't matter which version of the xfs_da_intnode structure we use + * here as the result will be the same using either structure. */ - - node = oldblk->bp->data; + node = oldblk->bp->b_addr; if (node->hdr.info.forw) { if (be32_to_cpu(node->hdr.info.forw) == addblk->blkno) { bp = addblk->bp; @@ -233,13 +494,13 @@ ASSERT(state->extravalid); bp = state->extrablk.bp; } - node = bp->data; + node = bp->b_addr; node->hdr.info.back = cpu_to_be32(oldblk->blkno); - xfs_da_log_buf(state->args->trans, bp, + xfs_trans_log_buf(state->args->trans, bp, XFS_DA_LOGRANGE(node, &node->hdr.info, sizeof(node->hdr.info))); } - node = oldblk->bp->data; + node = oldblk->bp->b_addr; if (node->hdr.info.back) { if (be32_to_cpu(node->hdr.info.back) == addblk->blkno) { bp = addblk->bp; @@ -247,14 +508,12 @@ ASSERT(state->extravalid); bp = state->extrablk.bp; } - node = bp->data; + node = bp->b_addr; node->hdr.info.forw = cpu_to_be32(oldblk->blkno); - xfs_da_log_buf(state->args->trans, bp, + xfs_trans_log_buf(state->args->trans, bp, XFS_DA_LOGRANGE(node, &node->hdr.info, sizeof(node->hdr.info))); } - xfs_da_buf_done(oldblk->bp); - xfs_da_buf_done(addblk->bp); addblk->bp = NULL; return(0); } @@ -265,69 +524,121 @@ * the EOF, extending the inode in process. */ STATIC int /* error */ -xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, - xfs_da_state_blk_t *blk2) -{ - xfs_da_intnode_t *node, *oldroot; - xfs_da_args_t *args; - xfs_dablk_t blkno; - xfs_dabuf_t *bp; - int error, size; - xfs_inode_t *dp; - xfs_trans_t *tp; - xfs_mount_t *mp; - xfs_dir2_leaf_t *leaf; +xfs_da3_root_split( + struct xfs_da_state *state, + struct xfs_da_state_blk *blk1, + struct xfs_da_state_blk *blk2) +{ + struct xfs_da_intnode *node; + struct xfs_da_intnode *oldroot; + struct xfs_da_node_entry *btree; + struct xfs_da3_icnode_hdr nodehdr; + struct xfs_da_args *args; + struct xfs_buf *bp; + struct xfs_inode *dp; + struct xfs_trans *tp; + struct xfs_mount *mp; + struct xfs_dir2_leaf *leaf; + xfs_dablk_t blkno; + int level; + int error; + int size; + + trace_xfs_da_root_split(state->args); /* * Copy the existing (incorrect) block from the root node position * to a free space somewhere. */ args = state->args; - ASSERT(args != NULL); error = xfs_da_grow_inode(args, &blkno); if (error) - return(error); + return error; + dp = args->dp; tp = args->trans; mp = state->mp; error = xfs_da_get_buf(tp, dp, blkno, -1, &bp, args->whichfork); if (error) - return(error); - ASSERT(bp != NULL); - node = bp->data; - oldroot = blk1->bp->data; - if (be16_to_cpu(oldroot->hdr.info.magic) == XFS_DA_NODE_MAGIC) { - size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] - - (char *)oldroot); + return error; + node = bp->b_addr; + oldroot = blk1->bp->b_addr; + if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC) || + oldroot->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC)) { + struct xfs_da3_icnode_hdr nodehdr; + + xfs_da3_node_hdr_from_disk(&nodehdr, oldroot); + btree = xfs_da3_node_tree_p(oldroot); + size = (int)((char *)&btree[nodehdr.count] - (char *)oldroot); + level = nodehdr.level; + + /* + * we are about to copy oldroot to bp, so set up the type + * of bp while we know exactly what it will be. + */ + xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DA_NODE_BUF); } else { - ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); + struct xfs_dir3_icleaf_hdr leafhdr; + struct xfs_dir2_leaf_entry *ents; + leaf = (xfs_dir2_leaf_t *)oldroot; - size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] - - (char *)leaf); + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + ents = xfs_dir3_leaf_ents_p(leaf); + + ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || + leafhdr.magic == XFS_DIR3_LEAFN_MAGIC); + size = (int)((char *)&ents[leafhdr.count] - (char *)leaf); + level = 0; + + /* + * we are about to copy oldroot to bp, so set up the type + * of bp while we know exactly what it will be. + */ + xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_LEAFN_BUF); } + + /* + * we can copy most of the information in the node from one block to + * another, but for CRC enabled headers we have to make sure that the + * block specific identifiers are kept intact. We update the buffer + * directly for this. + */ memcpy(node, oldroot, size); - xfs_da_log_buf(tp, bp, 0, size - 1); - xfs_da_buf_done(blk1->bp); + if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC) || + oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) { + struct xfs_da3_intnode *node3 = (struct xfs_da3_intnode *)node; + + node3->hdr.info.blkno = cpu_to_be64(bp->b_bn); + } + xfs_trans_log_buf(tp, bp, 0, size - 1); + + bp->b_ops = blk1->bp->b_ops; + xfs_trans_buf_copy_type(bp, blk1->bp); blk1->bp = bp; blk1->blkno = blkno; /* * Set up the new root node. */ - error = xfs_da_node_create(args, + error = xfs_da3_node_create(args, (args->whichfork == XFS_DATA_FORK) ? mp->m_dirleafblk : 0, - be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork); + level + 1, &bp, args->whichfork); if (error) - return(error); - node = bp->data; - node->btree[0].hashval = cpu_to_be32(blk1->hashval); - node->btree[0].before = cpu_to_be32(blk1->blkno); - node->btree[1].hashval = cpu_to_be32(blk2->hashval); - node->btree[1].before = cpu_to_be32(blk2->blkno); - node->hdr.count = cpu_to_be16(2); + return error; + + node = bp->b_addr; + xfs_da3_node_hdr_from_disk(&nodehdr, node); + btree = xfs_da3_node_tree_p(node); + btree[0].hashval = cpu_to_be32(blk1->hashval); + btree[0].before = cpu_to_be32(blk1->blkno); + btree[1].hashval = cpu_to_be32(blk2->hashval); + btree[1].before = cpu_to_be32(blk2->blkno); + nodehdr.count = 2; + xfs_da3_node_hdr_to_disk(node, &nodehdr); #ifdef DEBUG - if (be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC) { + if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || + oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) { ASSERT(blk1->blkno >= mp->m_dirleafblk && blk1->blkno < mp->m_dirfreeblk); ASSERT(blk2->blkno >= mp->m_dirleafblk && @@ -336,30 +647,35 @@ #endif /* Header is already logged by xfs_da_node_create */ - xfs_da_log_buf(tp, bp, - XFS_DA_LOGRANGE(node, node->btree, - sizeof(xfs_da_node_entry_t) * 2)); - xfs_da_buf_done(bp); + xfs_trans_log_buf(tp, bp, + XFS_DA_LOGRANGE(node, btree, sizeof(xfs_da_node_entry_t) * 2)); - return(0); + return 0; } /* * Split the node, rebalance, then add the new entry. */ STATIC int /* error */ -xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, - xfs_da_state_blk_t *newblk, - xfs_da_state_blk_t *addblk, - int treelevel, int *result) -{ - xfs_da_intnode_t *node; - xfs_dablk_t blkno; - int newcount, error; - int useextra; +xfs_da3_node_split( + struct xfs_da_state *state, + struct xfs_da_state_blk *oldblk, + struct xfs_da_state_blk *newblk, + struct xfs_da_state_blk *addblk, + int treelevel, + int *result) +{ + struct xfs_da_intnode *node; + struct xfs_da3_icnode_hdr nodehdr; + xfs_dablk_t blkno; + int newcount; + int error; + int useextra; - node = oldblk->bp->data; - ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); + trace_xfs_da_node_split(state->args); + + node = oldblk->bp->b_addr; + xfs_da3_node_hdr_from_disk(&nodehdr, node); /* * With V2 dirs the extra block is data or freespace. @@ -369,7 +685,7 @@ /* * Do we have to split the node? */ - if ((be16_to_cpu(node->hdr.count) + newcount) > state->node_ents) { + if (nodehdr.count + newcount > state->node_ents) { /* * Allocate a new node, add to the doubly linked chain of * nodes, then move some of our excess entries into it. @@ -378,14 +694,14 @@ if (error) return(error); /* GROT: dir is inconsistent */ - error = xfs_da_node_create(state->args, blkno, treelevel, + error = xfs_da3_node_create(state->args, blkno, treelevel, &newblk->bp, state->args->whichfork); if (error) return(error); /* GROT: dir is inconsistent */ newblk->blkno = blkno; newblk->magic = XFS_DA_NODE_MAGIC; - xfs_da_node_rebalance(state, oldblk, newblk); - error = xfs_da_blk_link(state, oldblk, newblk); + xfs_da3_node_rebalance(state, oldblk, newblk); + error = xfs_da3_blk_link(state, oldblk, newblk); if (error) return(error); *result = 1; @@ -397,7 +713,7 @@ * Insert the new entry(s) into the correct block * (updating last hashval in the process). * - * xfs_da_node_add() inserts BEFORE the given index, + * xfs_da3_node_add() inserts BEFORE the given index, * and as a result of using node_lookup_int() we always * point to a valid entry (not after one), but a split * operation always results in a new block whose hashvals @@ -405,23 +721,24 @@ * * If we had double-split op below us, then add the extra block too. */ - node = oldblk->bp->data; - if (oldblk->index <= be16_to_cpu(node->hdr.count)) { + node = oldblk->bp->b_addr; + xfs_da3_node_hdr_from_disk(&nodehdr, node); + if (oldblk->index <= nodehdr.count) { oldblk->index++; - xfs_da_node_add(state, oldblk, addblk); + xfs_da3_node_add(state, oldblk, addblk); if (useextra) { if (state->extraafter) oldblk->index++; - xfs_da_node_add(state, oldblk, &state->extrablk); + xfs_da3_node_add(state, oldblk, &state->extrablk); state->extravalid = 0; } } else { newblk->index++; - xfs_da_node_add(state, newblk, addblk); + xfs_da3_node_add(state, newblk, addblk); if (useextra) { if (state->extraafter) newblk->index++; - xfs_da_node_add(state, newblk, &state->extrablk); + xfs_da3_node_add(state, newblk, &state->extrablk); state->extravalid = 0; } } @@ -436,31 +753,53 @@ * NOTE: if blk2 is empty, then it will get the upper half of blk1. */ STATIC void -xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, - xfs_da_state_blk_t *blk2) -{ - xfs_da_intnode_t *node1, *node2, *tmpnode; - xfs_da_node_entry_t *btree_s, *btree_d; - int count, tmp; - xfs_trans_t *tp; +xfs_da3_node_rebalance( + struct xfs_da_state *state, + struct xfs_da_state_blk *blk1, + struct xfs_da_state_blk *blk2) +{ + struct xfs_da_intnode *node1; + struct xfs_da_intnode *node2; + struct xfs_da_intnode *tmpnode; + struct xfs_da_node_entry *btree1; + struct xfs_da_node_entry *btree2; + struct xfs_da_node_entry *btree_s; + struct xfs_da_node_entry *btree_d; + struct xfs_da3_icnode_hdr nodehdr1; + struct xfs_da3_icnode_hdr nodehdr2; + struct xfs_trans *tp; + int count; + int tmp; + int swap = 0; + + trace_xfs_da_node_rebalance(state->args); + + node1 = blk1->bp->b_addr; + node2 = blk2->bp->b_addr; + xfs_da3_node_hdr_from_disk(&nodehdr1, node1); + xfs_da3_node_hdr_from_disk(&nodehdr2, node2); + btree1 = xfs_da3_node_tree_p(node1); + btree2 = xfs_da3_node_tree_p(node2); - node1 = blk1->bp->data; - node2 = blk2->bp->data; /* * Figure out how many entries need to move, and in which direction. * Swap the nodes around if that makes it simpler. */ - if ((be16_to_cpu(node1->hdr.count) > 0) && (be16_to_cpu(node2->hdr.count) > 0) && - ((be32_to_cpu(node2->btree[0].hashval) < be32_to_cpu(node1->btree[0].hashval)) || - (be32_to_cpu(node2->btree[be16_to_cpu(node2->hdr.count)-1].hashval) < - be32_to_cpu(node1->btree[be16_to_cpu(node1->hdr.count)-1].hashval)))) { + if (nodehdr1.count > 0 && nodehdr2.count > 0 && + ((be32_to_cpu(btree2[0].hashval) < be32_to_cpu(btree1[0].hashval)) || + (be32_to_cpu(btree2[nodehdr2.count - 1].hashval) < + be32_to_cpu(btree1[nodehdr1.count - 1].hashval)))) { tmpnode = node1; node1 = node2; node2 = tmpnode; + xfs_da3_node_hdr_from_disk(&nodehdr1, node1); + xfs_da3_node_hdr_from_disk(&nodehdr2, node2); + btree1 = xfs_da3_node_tree_p(node1); + btree2 = xfs_da3_node_tree_p(node2); + swap = 1; } - ASSERT(be16_to_cpu(node1->hdr.info.magic) == XFS_DA_NODE_MAGIC); - ASSERT(be16_to_cpu(node2->hdr.info.magic) == XFS_DA_NODE_MAGIC); - count = (be16_to_cpu(node1->hdr.count) - be16_to_cpu(node2->hdr.count)) / 2; + + count = (nodehdr1.count - nodehdr2.count) / 2; if (count == 0) return; tp = state->args->trans; @@ -471,10 +810,11 @@ /* * Move elements in node2 up to make a hole. */ - if ((tmp = be16_to_cpu(node2->hdr.count)) > 0) { + tmp = nodehdr2.count; + if (tmp > 0) { tmp *= (uint)sizeof(xfs_da_node_entry_t); - btree_s = &node2->btree[0]; - btree_d = &node2->btree[count]; + btree_s = &btree2[0]; + btree_d = &btree2[count]; memmove(btree_d, btree_s, tmp); } @@ -482,12 +822,12 @@ * Move the req'd B-tree elements from high in node1 to * low in node2. */ - be16_add_cpu(&node2->hdr.count, count); + nodehdr2.count += count; tmp = count * (uint)sizeof(xfs_da_node_entry_t); - btree_s = &node1->btree[be16_to_cpu(node1->hdr.count) - count]; - btree_d = &node2->btree[0]; + btree_s = &btree1[nodehdr1.count - count]; + btree_d = &btree2[0]; memcpy(btree_d, btree_s, tmp); - be16_add_cpu(&node1->hdr.count, -count); + nodehdr1.count -= count; } else { /* * Move the req'd B-tree elements from low in node2 to @@ -495,49 +835,60 @@ */ count = -count; tmp = count * (uint)sizeof(xfs_da_node_entry_t); - btree_s = &node2->btree[0]; - btree_d = &node1->btree[be16_to_cpu(node1->hdr.count)]; + btree_s = &btree2[0]; + btree_d = &btree1[nodehdr1.count]; memcpy(btree_d, btree_s, tmp); - be16_add_cpu(&node1->hdr.count, count); - xfs_da_log_buf(tp, blk1->bp, + nodehdr1.count += count; + + xfs_trans_log_buf(tp, blk1->bp, XFS_DA_LOGRANGE(node1, btree_d, tmp)); /* * Move elements in node2 down to fill the hole. */ - tmp = be16_to_cpu(node2->hdr.count) - count; + tmp = nodehdr2.count - count; tmp *= (uint)sizeof(xfs_da_node_entry_t); - btree_s = &node2->btree[count]; - btree_d = &node2->btree[0]; + btree_s = &btree2[count]; + btree_d = &btree2[0]; memmove(btree_d, btree_s, tmp); - be16_add_cpu(&node2->hdr.count, -count); + nodehdr2.count -= count; } /* * Log header of node 1 and all current bits of node 2. */ - xfs_da_log_buf(tp, blk1->bp, - XFS_DA_LOGRANGE(node1, &node1->hdr, sizeof(node1->hdr))); - xfs_da_log_buf(tp, blk2->bp, + xfs_da3_node_hdr_to_disk(node1, &nodehdr1); + xfs_trans_log_buf(tp, blk1->bp, + XFS_DA_LOGRANGE(node1, &node1->hdr, + xfs_da3_node_hdr_size(node1))); + + xfs_da3_node_hdr_to_disk(node2, &nodehdr2); + xfs_trans_log_buf(tp, blk2->bp, XFS_DA_LOGRANGE(node2, &node2->hdr, - sizeof(node2->hdr) + - sizeof(node2->btree[0]) * be16_to_cpu(node2->hdr.count))); + xfs_da3_node_hdr_size(node2) + + (sizeof(btree2[0]) * nodehdr2.count))); /* * Record the last hashval from each block for upward propagation. * (note: don't use the swapped node pointers) */ - node1 = blk1->bp->data; - node2 = blk2->bp->data; - blk1->hashval = be32_to_cpu(node1->btree[be16_to_cpu(node1->hdr.count)-1].hashval); - blk2->hashval = be32_to_cpu(node2->btree[be16_to_cpu(node2->hdr.count)-1].hashval); + if (swap) { + node1 = blk1->bp->b_addr; + node2 = blk2->bp->b_addr; + xfs_da3_node_hdr_from_disk(&nodehdr1, node1); + xfs_da3_node_hdr_from_disk(&nodehdr2, node2); + btree1 = xfs_da3_node_tree_p(node1); + btree2 = xfs_da3_node_tree_p(node2); + } + blk1->hashval = be32_to_cpu(btree1[nodehdr1.count - 1].hashval); + blk2->hashval = be32_to_cpu(btree2[nodehdr2.count - 1].hashval); /* * Adjust the expected index for insertion. */ - if (blk1->index >= be16_to_cpu(node1->hdr.count)) { - blk2->index = blk1->index - be16_to_cpu(node1->hdr.count); - blk1->index = be16_to_cpu(node1->hdr.count) + 1; /* make it invalid */ + if (blk1->index >= nodehdr1.count) { + blk2->index = blk1->index - nodehdr1.count; + blk1->index = nodehdr1.count + 1; /* make it invalid */ } } @@ -545,16 +896,23 @@ * Add a new entry to an intermediate node. */ STATIC void -xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, - xfs_da_state_blk_t *newblk) -{ - xfs_da_intnode_t *node; - xfs_da_node_entry_t *btree; - int tmp; - - node = oldblk->bp->data; - ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); - ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count))); +xfs_da3_node_add( + struct xfs_da_state *state, + struct xfs_da_state_blk *oldblk, + struct xfs_da_state_blk *newblk) +{ + struct xfs_da_intnode *node; + struct xfs_da3_icnode_hdr nodehdr; + struct xfs_da_node_entry *btree; + int tmp; + + trace_xfs_da_node_add(state->args); + + node = oldblk->bp->b_addr; + xfs_da3_node_hdr_from_disk(&nodehdr, node); + btree = xfs_da3_node_tree_p(node); + + ASSERT(oldblk->index >= 0 && oldblk->index <= nodehdr.count); ASSERT(newblk->blkno != 0); if (state->args->whichfork == XFS_DATA_FORK) ASSERT(newblk->blkno >= state->mp->m_dirleafblk && @@ -564,23 +922,25 @@ * We may need to make some room before we insert the new node. */ tmp = 0; - btree = &node->btree[ oldblk->index ]; - if (oldblk->index < be16_to_cpu(node->hdr.count)) { - tmp = (be16_to_cpu(node->hdr.count) - oldblk->index) * (uint)sizeof(*btree); - memmove(btree + 1, btree, tmp); - } - btree->hashval = cpu_to_be32(newblk->hashval); - btree->before = cpu_to_be32(newblk->blkno); - xfs_da_log_buf(state->args->trans, oldblk->bp, - XFS_DA_LOGRANGE(node, btree, tmp + sizeof(*btree))); - be16_add_cpu(&node->hdr.count, 1); - xfs_da_log_buf(state->args->trans, oldblk->bp, - XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); + if (oldblk->index < nodehdr.count) { + tmp = (nodehdr.count - oldblk->index) * (uint)sizeof(*btree); + memmove(&btree[oldblk->index + 1], &btree[oldblk->index], tmp); + } + btree[oldblk->index].hashval = cpu_to_be32(newblk->hashval); + btree[oldblk->index].before = cpu_to_be32(newblk->blkno); + xfs_trans_log_buf(state->args->trans, oldblk->bp, + XFS_DA_LOGRANGE(node, &btree[oldblk->index], + tmp + sizeof(*btree))); + + nodehdr.count += 1; + xfs_da3_node_hdr_to_disk(node, &nodehdr); + xfs_trans_log_buf(state->args->trans, oldblk->bp, + XFS_DA_LOGRANGE(node, &node->hdr, xfs_da3_node_hdr_size(node))); /* * Copy the last hash value from the oldblk to propagate upwards. */ - oldblk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1 ].hashval); + oldblk->hashval = be32_to_cpu(btree[nodehdr.count - 1].hashval); } /*======================================================================== @@ -592,12 +952,16 @@ * possibly deallocating that block, etc... */ int -xfs_da_join(xfs_da_state_t *state) +xfs_da3_join( + struct xfs_da_state *state) { - xfs_da_state_blk_t *drop_blk, *save_blk; - int action, error; + struct xfs_da_state_blk *drop_blk; + struct xfs_da_state_blk *save_blk; + int action = 0; + int error; + + trace_xfs_da_join(state->args); - action = 0; drop_blk = &state->path.blk[ state->path.active-1 ]; save_blk = &state->altpath.blk[ state->path.active-1 ]; ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC); @@ -618,12 +982,12 @@ */ switch (drop_blk->magic) { case XFS_ATTR_LEAF_MAGIC: - error = xfs_attr_leaf_toosmall(state, &action); + error = xfs_attr3_leaf_toosmall(state, &action); if (error) return(error); if (action == 0) return(0); - xfs_attr_leaf_unbalance(state, drop_blk, save_blk); + xfs_attr3_leaf_unbalance(state, drop_blk, save_blk); break; case XFS_DIR2_LEAFN_MAGIC: error = xfs_dir2_leafn_toosmall(state, &action); @@ -638,18 +1002,18 @@ * Remove the offending node, fixup hashvals, * check for a toosmall neighbor. */ - xfs_da_node_remove(state, drop_blk); - xfs_da_fixhashpath(state, &state->path); - error = xfs_da_node_toosmall(state, &action); + xfs_da3_node_remove(state, drop_blk); + xfs_da3_fixhashpath(state, &state->path); + error = xfs_da3_node_toosmall(state, &action); if (error) return(error); if (action == 0) return 0; - xfs_da_node_unbalance(state, drop_blk, save_blk); + xfs_da3_node_unbalance(state, drop_blk, save_blk); break; } - xfs_da_fixhashpath(state, &state->altpath); - error = xfs_da_blk_unlink(state, drop_blk, save_blk); + xfs_da3_fixhashpath(state, &state->altpath); + error = xfs_da3_blk_unlink(state, drop_blk, save_blk); xfs_da_state_kill_altpath(state); if (error) return(error); @@ -664,63 +1028,95 @@ * we only have one entry in the root, make the child block * the new root. */ - xfs_da_node_remove(state, drop_blk); - xfs_da_fixhashpath(state, &state->path); - error = xfs_da_root_join(state, &state->path.blk[0]); + xfs_da3_node_remove(state, drop_blk); + xfs_da3_fixhashpath(state, &state->path); + error = xfs_da3_root_join(state, &state->path.blk[0]); return(error); } +#ifdef DEBUG +static void +xfs_da_blkinfo_onlychild_validate(struct xfs_da_blkinfo *blkinfo, __u16 level) +{ + __be16 magic = blkinfo->magic; + + if (level == 1) { + ASSERT(magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || + magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC) || + magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC) || + magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)); + } else { + ASSERT(magic == cpu_to_be16(XFS_DA_NODE_MAGIC) || + magic == cpu_to_be16(XFS_DA3_NODE_MAGIC)); + } + ASSERT(!blkinfo->forw); + ASSERT(!blkinfo->back); +} +#else /* !DEBUG */ +#define xfs_da_blkinfo_onlychild_validate(blkinfo, level) +#endif /* !DEBUG */ + /* * We have only one entry in the root. Copy the only remaining child of * the old root to block 0 as the new root node. */ STATIC int -xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk) -{ - xfs_da_intnode_t *oldroot; - /* REFERENCED */ - xfs_da_blkinfo_t *blkinfo; - xfs_da_args_t *args; - xfs_dablk_t child; - xfs_dabuf_t *bp; - int error; +xfs_da3_root_join( + struct xfs_da_state *state, + struct xfs_da_state_blk *root_blk) +{ + struct xfs_da_intnode *oldroot; + struct xfs_da_args *args; + xfs_dablk_t child; + struct xfs_buf *bp; + struct xfs_da3_icnode_hdr oldroothdr; + struct xfs_da_node_entry *btree; + int error; + + trace_xfs_da_root_join(state->args); - args = state->args; - ASSERT(args != NULL); ASSERT(root_blk->magic == XFS_DA_NODE_MAGIC); - oldroot = root_blk->bp->data; - ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DA_NODE_MAGIC); - ASSERT(!oldroot->hdr.info.forw); - ASSERT(!oldroot->hdr.info.back); + + args = state->args; + oldroot = root_blk->bp->b_addr; + xfs_da3_node_hdr_from_disk(&oldroothdr, oldroot); + ASSERT(oldroothdr.forw == 0); + ASSERT(oldroothdr.back == 0); /* * If the root has more than one child, then don't do anything. */ - if (be16_to_cpu(oldroot->hdr.count) > 1) - return(0); + if (oldroothdr.count > 1) + return 0; /* * Read in the (only) child block, then copy those bytes into * the root block's buffer and free the original child block. */ - child = be32_to_cpu(oldroot->btree[0].before); + btree = xfs_da3_node_tree_p(oldroot); + child = be32_to_cpu(btree[0].before); ASSERT(child != 0); - error = xfs_da_read_buf(args->trans, args->dp, child, -1, &bp, + error = xfs_da3_node_read(args->trans, args->dp, child, -1, &bp, args->whichfork); if (error) - return(error); - ASSERT(bp != NULL); - blkinfo = bp->data; - if (be16_to_cpu(oldroot->hdr.level) == 1) { - ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIR2_LEAFN_MAGIC || - be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC); - } else { - ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC); + return error; + xfs_da_blkinfo_onlychild_validate(bp->b_addr, oldroothdr.level); + + /* + * This could be copying a leaf back into the root block in the case of + * there only being a single leaf block left in the tree. Hence we have + * to update the b_ops pointer as well to match the buffer type change + * that could occur. For dir3 blocks we also need to update the block + * number in the buffer header. + */ + memcpy(root_blk->bp->b_addr, bp->b_addr, state->blocksize); + root_blk->bp->b_ops = bp->b_ops; + xfs_trans_buf_copy_type(root_blk->bp, bp); + if (oldroothdr.magic == XFS_DA3_NODE_MAGIC) { + struct xfs_da3_blkinfo *da3 = root_blk->bp->b_addr; + da3->blkno = cpu_to_be64(root_blk->bp->b_bn); } - ASSERT(!blkinfo->forw); - ASSERT(!blkinfo->back); - memcpy(root_blk->bp->data, bp->data, state->blocksize); - xfs_da_log_buf(args->trans, root_blk->bp, 0, state->blocksize - 1); + xfs_trans_log_buf(args->trans, root_blk->bp, 0, state->blocksize - 1); error = xfs_da_shrink_inode(args, child, bp); return(error); } @@ -735,14 +1131,23 @@ * If nothing can be done, return 0. */ STATIC int -xfs_da_node_toosmall(xfs_da_state_t *state, int *action) -{ - xfs_da_intnode_t *node; - xfs_da_state_blk_t *blk; - xfs_da_blkinfo_t *info; - int count, forward, error, retval, i; - xfs_dablk_t blkno; - xfs_dabuf_t *bp; +xfs_da3_node_toosmall( + struct xfs_da_state *state, + int *action) +{ + struct xfs_da_intnode *node; + struct xfs_da_state_blk *blk; + struct xfs_da_blkinfo *info; + xfs_dablk_t blkno; + struct xfs_buf *bp; + struct xfs_da3_icnode_hdr nodehdr; + int count; + int forward; + int error; + int retval; + int i; + + trace_xfs_da_node_toosmall(state->args); /* * Check for the degenerate case of the block being over 50% full. @@ -750,11 +1155,10 @@ * to coalesce with a sibling. */ blk = &state->path.blk[ state->path.active-1 ]; - info = blk->bp->data; - ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC); + info = blk->bp->b_addr; node = (xfs_da_intnode_t *)info; - count = be16_to_cpu(node->hdr.count); - if (count > (state->node_ents >> 1)) { + xfs_da3_node_hdr_from_disk(&nodehdr, node); + if (nodehdr.count > (state->node_ents >> 1)) { *action = 0; /* blk over 50%, don't try to join */ return(0); /* blk over 50%, don't try to join */ } @@ -765,14 +1169,14 @@ * coalesce it with a sibling block. We choose (arbitrarily) * to merge with the forward block unless it is NULL. */ - if (count == 0) { + if (nodehdr.count == 0) { /* * Make altpath point to the block we want to keep and * path point to the block we want to drop (this one). */ forward = (info->forw != 0); memcpy(&state->altpath, &state->path, sizeof(state->path)); - error = xfs_da_path_shift(state, &state->altpath, forward, + error = xfs_da3_path_shift(state, &state->altpath, forward, 0, &retval); if (error) return(error); @@ -791,35 +1195,35 @@ * We prefer coalescing with the lower numbered sibling so as * to shrink a directory over time. */ + count = state->node_ents; + count -= state->node_ents >> 2; + count -= nodehdr.count; + /* start with smaller blk num */ - forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back)); + forward = nodehdr.forw < nodehdr.back; for (i = 0; i < 2; forward = !forward, i++) { + struct xfs_da3_icnode_hdr thdr; if (forward) - blkno = be32_to_cpu(info->forw); + blkno = nodehdr.forw; else - blkno = be32_to_cpu(info->back); + blkno = nodehdr.back; if (blkno == 0) continue; - error = xfs_da_read_buf(state->args->trans, state->args->dp, + error = xfs_da3_node_read(state->args->trans, state->args->dp, blkno, -1, &bp, state->args->whichfork); if (error) return(error); - ASSERT(bp != NULL); - node = (xfs_da_intnode_t *)info; - count = state->node_ents; - count -= state->node_ents >> 2; - count -= be16_to_cpu(node->hdr.count); - node = bp->data; - ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); - count -= be16_to_cpu(node->hdr.count); - xfs_da_brelse(state->args->trans, bp); - if (count >= 0) + node = bp->b_addr; + xfs_da3_node_hdr_from_disk(&thdr, node); + xfs_trans_brelse(state->args->trans, bp); + + if (count - thdr.count >= 0) break; /* fits with at least 25% to spare */ } if (i >= 2) { *action = 0; - return(0); + return 0; } /* @@ -828,28 +1232,42 @@ */ memcpy(&state->altpath, &state->path, sizeof(state->path)); if (blkno < blk->blkno) { - error = xfs_da_path_shift(state, &state->altpath, forward, + error = xfs_da3_path_shift(state, &state->altpath, forward, 0, &retval); - if (error) { - return(error); - } - if (retval) { - *action = 0; - return(0); - } } else { - error = xfs_da_path_shift(state, &state->path, forward, + error = xfs_da3_path_shift(state, &state->path, forward, 0, &retval); - if (error) { - return(error); - } - if (retval) { - *action = 0; - return(0); - } + } + if (error) + return error; + if (retval) { + *action = 0; + return 0; } *action = 1; - return(0); + return 0; +} + +/* + * Pick up the last hashvalue from an intermediate node. + */ +STATIC uint +xfs_da3_node_lasthash( + struct xfs_buf *bp, + int *count) +{ + struct xfs_da_intnode *node; + struct xfs_da_node_entry *btree; + struct xfs_da3_icnode_hdr nodehdr; + + node = bp->b_addr; + xfs_da3_node_hdr_from_disk(&nodehdr, node); + if (count) + *count = nodehdr.count; + if (!nodehdr.count) + return 0; + btree = xfs_da3_node_tree_p(node); + return be32_to_cpu(btree[nodehdr.count - 1].hashval); } /* @@ -857,13 +1275,18 @@ * when we stop making changes, return. */ void -xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path) -{ - xfs_da_state_blk_t *blk; - xfs_da_intnode_t *node; - xfs_da_node_entry_t *btree; - xfs_dahash_t lasthash=0; - int level, count; +xfs_da3_fixhashpath( + struct xfs_da_state *state, + struct xfs_da_state_path *path) +{ + struct xfs_da_state_blk *blk; + struct xfs_da_intnode *node; + struct xfs_da_node_entry *btree; + xfs_dahash_t lasthash=0; + int level; + int count; + + trace_xfs_da_fixhashpath(state->args); level = path->active-1; blk = &path->blk[ level ]; @@ -879,23 +1302,26 @@ return; break; case XFS_DA_NODE_MAGIC: - lasthash = xfs_da_node_lasthash(blk->bp, &count); + lasthash = xfs_da3_node_lasthash(blk->bp, &count); if (count == 0) return; break; } for (blk--, level--; level >= 0; blk--, level--) { - node = blk->bp->data; - ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); - btree = &node->btree[ blk->index ]; - if (be32_to_cpu(btree->hashval) == lasthash) + struct xfs_da3_icnode_hdr nodehdr; + + node = blk->bp->b_addr; + xfs_da3_node_hdr_from_disk(&nodehdr, node); + btree = xfs_da3_node_tree_p(node); + if (be32_to_cpu(btree[blk->index].hashval) == lasthash) break; blk->hashval = lasthash; - btree->hashval = cpu_to_be32(lasthash); - xfs_da_log_buf(state->args->trans, blk->bp, - XFS_DA_LOGRANGE(node, btree, sizeof(*btree))); + btree[blk->index].hashval = cpu_to_be32(lasthash); + xfs_trans_log_buf(state->args->trans, blk->bp, + XFS_DA_LOGRANGE(node, &btree[blk->index], + sizeof(*btree))); - lasthash = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval); + lasthash = be32_to_cpu(btree[nodehdr.count - 1].hashval); } } @@ -903,100 +1329,120 @@ * Remove an entry from an intermediate node. */ STATIC void -xfs_da_node_remove(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk) -{ - xfs_da_intnode_t *node; - xfs_da_node_entry_t *btree; - int tmp; - - node = drop_blk->bp->data; - ASSERT(drop_blk->index < be16_to_cpu(node->hdr.count)); +xfs_da3_node_remove( + struct xfs_da_state *state, + struct xfs_da_state_blk *drop_blk) +{ + struct xfs_da_intnode *node; + struct xfs_da3_icnode_hdr nodehdr; + struct xfs_da_node_entry *btree; + int index; + int tmp; + + trace_xfs_da_node_remove(state->args); + + node = drop_blk->bp->b_addr; + xfs_da3_node_hdr_from_disk(&nodehdr, node); + ASSERT(drop_blk->index < nodehdr.count); ASSERT(drop_blk->index >= 0); /* * Copy over the offending entry, or just zero it out. */ - btree = &node->btree[drop_blk->index]; - if (drop_blk->index < (be16_to_cpu(node->hdr.count)-1)) { - tmp = be16_to_cpu(node->hdr.count) - drop_blk->index - 1; + index = drop_blk->index; + btree = xfs_da3_node_tree_p(node); + if (index < nodehdr.count - 1) { + tmp = nodehdr.count - index - 1; tmp *= (uint)sizeof(xfs_da_node_entry_t); - memmove(btree, btree + 1, tmp); - xfs_da_log_buf(state->args->trans, drop_blk->bp, - XFS_DA_LOGRANGE(node, btree, tmp)); - btree = &node->btree[be16_to_cpu(node->hdr.count)-1]; - } - memset((char *)btree, 0, sizeof(xfs_da_node_entry_t)); - xfs_da_log_buf(state->args->trans, drop_blk->bp, - XFS_DA_LOGRANGE(node, btree, sizeof(*btree))); - be16_add_cpu(&node->hdr.count, -1); - xfs_da_log_buf(state->args->trans, drop_blk->bp, - XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); + memmove(&btree[index], &btree[index + 1], tmp); + xfs_trans_log_buf(state->args->trans, drop_blk->bp, + XFS_DA_LOGRANGE(node, &btree[index], tmp)); + index = nodehdr.count - 1; + } + memset(&btree[index], 0, sizeof(xfs_da_node_entry_t)); + xfs_trans_log_buf(state->args->trans, drop_blk->bp, + XFS_DA_LOGRANGE(node, &btree[index], sizeof(btree[index]))); + nodehdr.count -= 1; + xfs_da3_node_hdr_to_disk(node, &nodehdr); + xfs_trans_log_buf(state->args->trans, drop_blk->bp, + XFS_DA_LOGRANGE(node, &node->hdr, xfs_da3_node_hdr_size(node))); /* * Copy the last hash value from the block to propagate upwards. */ - btree--; - drop_blk->hashval = be32_to_cpu(btree->hashval); + drop_blk->hashval = be32_to_cpu(btree[index - 1].hashval); } /* - * Unbalance the btree elements between two intermediate nodes, + * Unbalance the elements between two intermediate nodes, * move all Btree elements from one node into another. */ STATIC void -xfs_da_node_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, - xfs_da_state_blk_t *save_blk) -{ - xfs_da_intnode_t *drop_node, *save_node; - xfs_da_node_entry_t *btree; - int tmp; - xfs_trans_t *tp; - - drop_node = drop_blk->bp->data; - save_node = save_blk->bp->data; - ASSERT(be16_to_cpu(drop_node->hdr.info.magic) == XFS_DA_NODE_MAGIC); - ASSERT(be16_to_cpu(save_node->hdr.info.magic) == XFS_DA_NODE_MAGIC); +xfs_da3_node_unbalance( + struct xfs_da_state *state, + struct xfs_da_state_blk *drop_blk, + struct xfs_da_state_blk *save_blk) +{ + struct xfs_da_intnode *drop_node; + struct xfs_da_intnode *save_node; + struct xfs_da_node_entry *drop_btree; + struct xfs_da_node_entry *save_btree; + struct xfs_da3_icnode_hdr drop_hdr; + struct xfs_da3_icnode_hdr save_hdr; + struct xfs_trans *tp; + int sindex; + int tmp; + + trace_xfs_da_node_unbalance(state->args); + + drop_node = drop_blk->bp->b_addr; + save_node = save_blk->bp->b_addr; + xfs_da3_node_hdr_from_disk(&drop_hdr, drop_node); + xfs_da3_node_hdr_from_disk(&save_hdr, save_node); + drop_btree = xfs_da3_node_tree_p(drop_node); + save_btree = xfs_da3_node_tree_p(save_node); tp = state->args->trans; /* * If the dying block has lower hashvals, then move all the * elements in the remaining block up to make a hole. */ - if ((be32_to_cpu(drop_node->btree[0].hashval) < be32_to_cpu(save_node->btree[ 0 ].hashval)) || - (be32_to_cpu(drop_node->btree[be16_to_cpu(drop_node->hdr.count)-1].hashval) < - be32_to_cpu(save_node->btree[be16_to_cpu(save_node->hdr.count)-1].hashval))) - { - btree = &save_node->btree[be16_to_cpu(drop_node->hdr.count)]; - tmp = be16_to_cpu(save_node->hdr.count) * (uint)sizeof(xfs_da_node_entry_t); - memmove(btree, &save_node->btree[0], tmp); - btree = &save_node->btree[0]; - xfs_da_log_buf(tp, save_blk->bp, - XFS_DA_LOGRANGE(save_node, btree, - (be16_to_cpu(save_node->hdr.count) + be16_to_cpu(drop_node->hdr.count)) * - sizeof(xfs_da_node_entry_t))); + if ((be32_to_cpu(drop_btree[0].hashval) < + be32_to_cpu(save_btree[0].hashval)) || + (be32_to_cpu(drop_btree[drop_hdr.count - 1].hashval) < + be32_to_cpu(save_btree[save_hdr.count - 1].hashval))) { + /* XXX: check this - is memmove dst correct? */ + tmp = save_hdr.count * sizeof(xfs_da_node_entry_t); + memmove(&save_btree[drop_hdr.count], &save_btree[0], tmp); + + sindex = 0; + xfs_trans_log_buf(tp, save_blk->bp, + XFS_DA_LOGRANGE(save_node, &save_btree[0], + (save_hdr.count + drop_hdr.count) * + sizeof(xfs_da_node_entry_t))); } else { - btree = &save_node->btree[be16_to_cpu(save_node->hdr.count)]; - xfs_da_log_buf(tp, save_blk->bp, - XFS_DA_LOGRANGE(save_node, btree, - be16_to_cpu(drop_node->hdr.count) * - sizeof(xfs_da_node_entry_t))); + sindex = save_hdr.count; + xfs_trans_log_buf(tp, save_blk->bp, + XFS_DA_LOGRANGE(save_node, &save_btree[sindex], + drop_hdr.count * sizeof(xfs_da_node_entry_t))); } /* * Move all the B-tree elements from drop_blk to save_blk. */ - tmp = be16_to_cpu(drop_node->hdr.count) * (uint)sizeof(xfs_da_node_entry_t); - memcpy(btree, &drop_node->btree[0], tmp); - be16_add_cpu(&save_node->hdr.count, be16_to_cpu(drop_node->hdr.count)); + tmp = drop_hdr.count * (uint)sizeof(xfs_da_node_entry_t); + memcpy(&save_btree[sindex], &drop_btree[0], tmp); + save_hdr.count += drop_hdr.count; - xfs_da_log_buf(tp, save_blk->bp, + xfs_da3_node_hdr_to_disk(save_node, &save_hdr); + xfs_trans_log_buf(tp, save_blk->bp, XFS_DA_LOGRANGE(save_node, &save_node->hdr, - sizeof(save_node->hdr))); + xfs_da3_node_hdr_size(save_node))); /* * Save the last hashval in the remaining block for upward propagation. */ - save_blk->hashval = be32_to_cpu(save_node->btree[be16_to_cpu(save_node->hdr.count)-1].hashval); + save_blk->hashval = be32_to_cpu(save_btree[save_hdr.count - 1].hashval); } /*======================================================================== @@ -1015,16 +1461,24 @@ * pruned depth-first tree search. */ int /* error */ -xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) -{ - xfs_da_state_blk_t *blk; - xfs_da_blkinfo_t *curr; - xfs_da_intnode_t *node; - xfs_da_node_entry_t *btree; - xfs_dablk_t blkno; - int probe, span, max, error, retval; - xfs_dahash_t hashval, btreehashval; - xfs_da_args_t *args; +xfs_da3_node_lookup_int( + struct xfs_da_state *state, + int *result) +{ + struct xfs_da_state_blk *blk; + struct xfs_da_blkinfo *curr; + struct xfs_da_intnode *node; + struct xfs_da_node_entry *btree; + struct xfs_da3_icnode_hdr nodehdr; + struct xfs_da_args *args; + xfs_dablk_t blkno; + xfs_dahash_t hashval; + xfs_dahash_t btreehashval; + int probe; + int span; + int max; + int error; + int retval; args = state->args; @@ -1040,79 +1494,88 @@ * Read the next node down in the tree. */ blk->blkno = blkno; - error = xfs_da_read_buf(args->trans, args->dp, blkno, + error = xfs_da3_node_read(args->trans, args->dp, blkno, -1, &blk->bp, args->whichfork); if (error) { blk->blkno = 0; state->path.active--; return(error); } - curr = blk->bp->data; + curr = blk->bp->b_addr; blk->magic = be16_to_cpu(curr->magic); - ASSERT(blk->magic == XFS_DA_NODE_MAGIC || - blk->magic == XFS_DIR2_LEAFN_MAGIC || - blk->magic == XFS_ATTR_LEAF_MAGIC); + + if (blk->magic == XFS_ATTR_LEAF_MAGIC || + blk->magic == XFS_ATTR3_LEAF_MAGIC) { + blk->magic = XFS_ATTR_LEAF_MAGIC; + blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); + break; + } + + if (blk->magic == XFS_DIR2_LEAFN_MAGIC || + blk->magic == XFS_DIR3_LEAFN_MAGIC) { + blk->magic = XFS_DIR2_LEAFN_MAGIC; + blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); + break; + } + + blk->magic = XFS_DA_NODE_MAGIC; + /* * Search an intermediate node for a match. */ - if (blk->magic == XFS_DA_NODE_MAGIC) { - node = blk->bp->data; - max = be16_to_cpu(node->hdr.count); - blk->hashval = be32_to_cpu(node->btree[max-1].hashval); + node = blk->bp->b_addr; + xfs_da3_node_hdr_from_disk(&nodehdr, node); + btree = xfs_da3_node_tree_p(node); - /* - * Binary search. (note: small blocks will skip loop) - */ - probe = span = max / 2; - hashval = args->hashval; - for (btree = &node->btree[probe]; span > 4; - btree = &node->btree[probe]) { - span /= 2; - btreehashval = be32_to_cpu(btree->hashval); - if (btreehashval < hashval) - probe += span; - else if (btreehashval > hashval) - probe -= span; - else - break; - } - ASSERT((probe >= 0) && (probe < max)); - ASSERT((span <= 4) || (be32_to_cpu(btree->hashval) == hashval)); + max = nodehdr.count; + blk->hashval = be32_to_cpu(btree[max - 1].hashval); - /* - * Since we may have duplicate hashval's, find the first - * matching hashval in the node. - */ - while ((probe > 0) && (be32_to_cpu(btree->hashval) >= hashval)) { - btree--; - probe--; - } - while ((probe < max) && (be32_to_cpu(btree->hashval) < hashval)) { - btree++; - probe++; - } + /* + * Binary search. (note: small blocks will skip loop) + */ + probe = span = max / 2; + hashval = args->hashval; + while (span > 4) { + span /= 2; + btreehashval = be32_to_cpu(btree[probe].hashval); + if (btreehashval < hashval) + probe += span; + else if (btreehashval > hashval) + probe -= span; + else + break; + } + ASSERT((probe >= 0) && (probe < max)); + ASSERT((span <= 4) || + (be32_to_cpu(btree[probe].hashval) == hashval)); - /* - * Pick the right block to descend on. - */ - if (probe == max) { - blk->index = max-1; - blkno = be32_to_cpu(node->btree[max-1].before); - } else { - blk->index = probe; - blkno = be32_to_cpu(btree->before); - } - } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { - blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); - break; - } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { - blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); - break; + /* + * Since we may have duplicate hashval's, find the first + * matching hashval in the node. + */ + while (probe > 0 && + be32_to_cpu(btree[probe].hashval) >= hashval) { + probe--; + } + while (probe < max && + be32_to_cpu(btree[probe].hashval) < hashval) { + probe++; } - } - /* + /* + * Pick the right block to descend on. + */ + if (probe == max) { + blk->index = max - 1; + blkno = be32_to_cpu(btree[max - 1].before); + } else { + blk->index = probe; + blkno = be32_to_cpu(btree[probe].before); + } + } + + /* * A leaf block that ends in the hashval that we are interested in * (final hashval == search hashval) means that the next block may * contain more entries with the same hashval, shift upward to the @@ -1123,7 +1586,7 @@ retval = xfs_dir2_leafn_lookup_int(blk->bp, args, &blk->index, state); } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { - retval = xfs_attr_leaf_lookup_int(blk->bp, args); + retval = xfs_attr3_leaf_lookup_int(blk->bp, args); blk->index = args->index; args->blkno = blk->blkno; } else { @@ -1132,7 +1595,7 @@ } if (((retval == ENOENT) || (retval == ENOATTR)) && (blk->hashval == args->hashval)) { - error = xfs_da_path_shift(state, &state->path, 1, 1, + error = xfs_da3_path_shift(state, &state->path, 1, 1, &retval); if (error) return(error); @@ -1154,30 +1617,63 @@ *========================================================================*/ /* + * Compare two intermediate nodes for "order". + */ +STATIC int +xfs_da3_node_order( + struct xfs_buf *node1_bp, + struct xfs_buf *node2_bp) +{ + struct xfs_da_intnode *node1; + struct xfs_da_intnode *node2; + struct xfs_da_node_entry *btree1; + struct xfs_da_node_entry *btree2; + struct xfs_da3_icnode_hdr node1hdr; + struct xfs_da3_icnode_hdr node2hdr; + + node1 = node1_bp->b_addr; + node2 = node2_bp->b_addr; + xfs_da3_node_hdr_from_disk(&node1hdr, node1); + xfs_da3_node_hdr_from_disk(&node2hdr, node2); + btree1 = xfs_da3_node_tree_p(node1); + btree2 = xfs_da3_node_tree_p(node2); + + if (node1hdr.count > 0 && node2hdr.count > 0 && + ((be32_to_cpu(btree2[0].hashval) < be32_to_cpu(btree1[0].hashval)) || + (be32_to_cpu(btree2[node2hdr.count - 1].hashval) < + be32_to_cpu(btree1[node1hdr.count - 1].hashval)))) { + return 1; + } + return 0; +} + +/* * Link a new block into a doubly linked list of blocks (of whatever type). */ int /* error */ -xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, - xfs_da_state_blk_t *new_blk) -{ - xfs_da_blkinfo_t *old_info, *new_info, *tmp_info; - xfs_da_args_t *args; - int before=0, error; - xfs_dabuf_t *bp; +xfs_da3_blk_link( + struct xfs_da_state *state, + struct xfs_da_state_blk *old_blk, + struct xfs_da_state_blk *new_blk) +{ + struct xfs_da_blkinfo *old_info; + struct xfs_da_blkinfo *new_info; + struct xfs_da_blkinfo *tmp_info; + struct xfs_da_args *args; + struct xfs_buf *bp; + int before = 0; + int error; /* * Set up environment. */ args = state->args; ASSERT(args != NULL); - old_info = old_blk->bp->data; - new_info = new_blk->bp->data; + old_info = old_blk->bp->b_addr; + new_info = new_blk->bp->b_addr; ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC || old_blk->magic == XFS_DIR2_LEAFN_MAGIC || old_blk->magic == XFS_ATTR_LEAF_MAGIC); - ASSERT(old_blk->magic == be16_to_cpu(old_info->magic)); - ASSERT(new_blk->magic == be16_to_cpu(new_info->magic)); - ASSERT(old_blk->magic == new_blk->magic); switch (old_blk->magic) { case XFS_ATTR_LEAF_MAGIC: @@ -1187,7 +1683,7 @@ before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp); break; case XFS_DA_NODE_MAGIC: - before = xfs_da_node_order(old_blk->bp, new_blk->bp); + before = xfs_da3_node_order(old_blk->bp, new_blk->bp); break; } @@ -1198,114 +1694,77 @@ /* * Link new block in before existing block. */ + trace_xfs_da_link_before(args); new_info->forw = cpu_to_be32(old_blk->blkno); new_info->back = old_info->back; if (old_info->back) { - error = xfs_da_read_buf(args->trans, args->dp, + error = xfs_da3_node_read(args->trans, args->dp, be32_to_cpu(old_info->back), -1, &bp, args->whichfork); if (error) return(error); ASSERT(bp != NULL); - tmp_info = bp->data; - ASSERT(be16_to_cpu(tmp_info->magic) == be16_to_cpu(old_info->magic)); + tmp_info = bp->b_addr; + ASSERT(tmp_info->magic == old_info->magic); ASSERT(be32_to_cpu(tmp_info->forw) == old_blk->blkno); tmp_info->forw = cpu_to_be32(new_blk->blkno); - xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1); - xfs_da_buf_done(bp); + xfs_trans_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1); } old_info->back = cpu_to_be32(new_blk->blkno); } else { /* * Link new block in after existing block. */ + trace_xfs_da_link_after(args); new_info->forw = old_info->forw; new_info->back = cpu_to_be32(old_blk->blkno); if (old_info->forw) { - error = xfs_da_read_buf(args->trans, args->dp, + error = xfs_da3_node_read(args->trans, args->dp, be32_to_cpu(old_info->forw), -1, &bp, args->whichfork); if (error) return(error); ASSERT(bp != NULL); - tmp_info = bp->data; + tmp_info = bp->b_addr; ASSERT(tmp_info->magic == old_info->magic); ASSERT(be32_to_cpu(tmp_info->back) == old_blk->blkno); tmp_info->back = cpu_to_be32(new_blk->blkno); - xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1); - xfs_da_buf_done(bp); + xfs_trans_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1); } old_info->forw = cpu_to_be32(new_blk->blkno); } - xfs_da_log_buf(args->trans, old_blk->bp, 0, sizeof(*tmp_info) - 1); - xfs_da_log_buf(args->trans, new_blk->bp, 0, sizeof(*tmp_info) - 1); + xfs_trans_log_buf(args->trans, old_blk->bp, 0, sizeof(*tmp_info) - 1); + xfs_trans_log_buf(args->trans, new_blk->bp, 0, sizeof(*tmp_info) - 1); return(0); } /* - * Compare two intermediate nodes for "order". - */ -STATIC int -xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp) -{ - xfs_da_intnode_t *node1, *node2; - - node1 = node1_bp->data; - node2 = node2_bp->data; - ASSERT((be16_to_cpu(node1->hdr.info.magic) == XFS_DA_NODE_MAGIC) && - (be16_to_cpu(node2->hdr.info.magic) == XFS_DA_NODE_MAGIC)); - if ((be16_to_cpu(node1->hdr.count) > 0) && (be16_to_cpu(node2->hdr.count) > 0) && - ((be32_to_cpu(node2->btree[0].hashval) < - be32_to_cpu(node1->btree[0].hashval)) || - (be32_to_cpu(node2->btree[be16_to_cpu(node2->hdr.count)-1].hashval) < - be32_to_cpu(node1->btree[be16_to_cpu(node1->hdr.count)-1].hashval)))) { - return(1); - } - return(0); -} - -/* - * Pick up the last hashvalue from an intermediate node. - */ -STATIC uint -xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count) -{ - xfs_da_intnode_t *node; - - node = bp->data; - ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); - if (count) - *count = be16_to_cpu(node->hdr.count); - if (!node->hdr.count) - return(0); - return be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval); -} - -/* * Unlink a block from a doubly linked list of blocks. */ STATIC int /* error */ -xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, - xfs_da_state_blk_t *save_blk) -{ - xfs_da_blkinfo_t *drop_info, *save_info, *tmp_info; - xfs_da_args_t *args; - xfs_dabuf_t *bp; - int error; +xfs_da3_blk_unlink( + struct xfs_da_state *state, + struct xfs_da_state_blk *drop_blk, + struct xfs_da_state_blk *save_blk) +{ + struct xfs_da_blkinfo *drop_info; + struct xfs_da_blkinfo *save_info; + struct xfs_da_blkinfo *tmp_info; + struct xfs_da_args *args; + struct xfs_buf *bp; + int error; /* * Set up environment. */ args = state->args; ASSERT(args != NULL); - save_info = save_blk->bp->data; - drop_info = drop_blk->bp->data; + save_info = save_blk->bp->b_addr; + drop_info = drop_blk->bp->b_addr; ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC || save_blk->magic == XFS_DIR2_LEAFN_MAGIC || save_blk->magic == XFS_ATTR_LEAF_MAGIC); - ASSERT(save_blk->magic == be16_to_cpu(save_info->magic)); - ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic)); ASSERT(save_blk->magic == drop_blk->magic); ASSERT((be32_to_cpu(save_info->forw) == drop_blk->blkno) || (be32_to_cpu(save_info->back) == drop_blk->blkno)); @@ -1316,42 +1775,42 @@ * Unlink the leaf block from the doubly linked chain of leaves. */ if (be32_to_cpu(save_info->back) == drop_blk->blkno) { + trace_xfs_da_unlink_back(args); save_info->back = drop_info->back; if (drop_info->back) { - error = xfs_da_read_buf(args->trans, args->dp, + error = xfs_da3_node_read(args->trans, args->dp, be32_to_cpu(drop_info->back), -1, &bp, args->whichfork); if (error) return(error); ASSERT(bp != NULL); - tmp_info = bp->data; + tmp_info = bp->b_addr; ASSERT(tmp_info->magic == save_info->magic); ASSERT(be32_to_cpu(tmp_info->forw) == drop_blk->blkno); tmp_info->forw = cpu_to_be32(save_blk->blkno); - xfs_da_log_buf(args->trans, bp, 0, + xfs_trans_log_buf(args->trans, bp, 0, sizeof(*tmp_info) - 1); - xfs_da_buf_done(bp); } } else { + trace_xfs_da_unlink_forward(args); save_info->forw = drop_info->forw; if (drop_info->forw) { - error = xfs_da_read_buf(args->trans, args->dp, + error = xfs_da3_node_read(args->trans, args->dp, be32_to_cpu(drop_info->forw), -1, &bp, args->whichfork); if (error) return(error); ASSERT(bp != NULL); - tmp_info = bp->data; + tmp_info = bp->b_addr; ASSERT(tmp_info->magic == save_info->magic); ASSERT(be32_to_cpu(tmp_info->back) == drop_blk->blkno); tmp_info->back = cpu_to_be32(save_blk->blkno); - xfs_da_log_buf(args->trans, bp, 0, + xfs_trans_log_buf(args->trans, bp, 0, sizeof(*tmp_info) - 1); - xfs_da_buf_done(bp); } } - xfs_da_log_buf(args->trans, save_blk->bp, 0, sizeof(*save_info) - 1); + xfs_trans_log_buf(args->trans, save_blk->bp, 0, sizeof(*save_info) - 1); return(0); } @@ -1364,15 +1823,24 @@ * the new bottom and the root. */ int /* error */ -xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, - int forward, int release, int *result) -{ - xfs_da_state_blk_t *blk; - xfs_da_blkinfo_t *info; - xfs_da_intnode_t *node; - xfs_da_args_t *args; - xfs_dablk_t blkno=0; - int level, error; +xfs_da3_path_shift( + struct xfs_da_state *state, + struct xfs_da_state_path *path, + int forward, + int release, + int *result) +{ + struct xfs_da_state_blk *blk; + struct xfs_da_blkinfo *info; + struct xfs_da_intnode *node; + struct xfs_da_args *args; + struct xfs_da_node_entry *btree; + struct xfs_da3_icnode_hdr nodehdr; + xfs_dablk_t blkno = 0; + int level; + int error; + + trace_xfs_da_path_shift(state->args); /* * Roll up the Btree looking for the first block where our @@ -1385,16 +1853,17 @@ ASSERT((path->active > 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); level = (path->active-1) - 1; /* skip bottom layer in path */ for (blk = &path->blk[level]; level >= 0; blk--, level--) { - ASSERT(blk->bp != NULL); - node = blk->bp->data; - ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); - if (forward && (blk->index < be16_to_cpu(node->hdr.count)-1)) { + node = blk->bp->b_addr; + xfs_da3_node_hdr_from_disk(&nodehdr, node); + btree = xfs_da3_node_tree_p(node); + + if (forward && (blk->index < nodehdr.count - 1)) { blk->index++; - blkno = be32_to_cpu(node->btree[blk->index].before); + blkno = be32_to_cpu(btree[blk->index].before); break; } else if (!forward && (blk->index > 0)) { blk->index--; - blkno = be32_to_cpu(node->btree[blk->index].before); + blkno = be32_to_cpu(btree[blk->index].before); break; } } @@ -1414,51 +1883,66 @@ * (if it's dirty, trans won't actually let go) */ if (release) - xfs_da_brelse(args->trans, blk->bp); + xfs_trans_brelse(args->trans, blk->bp); /* * Read the next child block. */ blk->blkno = blkno; - error = xfs_da_read_buf(args->trans, args->dp, blkno, -1, - &blk->bp, args->whichfork); + error = xfs_da3_node_read(args->trans, args->dp, blkno, -1, + &blk->bp, args->whichfork); if (error) return(error); - ASSERT(blk->bp != NULL); - info = blk->bp->data; - ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC || - be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC || - be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC); - blk->magic = be16_to_cpu(info->magic); - if (blk->magic == XFS_DA_NODE_MAGIC) { + info = blk->bp->b_addr; + ASSERT(info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC) || + info->magic == cpu_to_be16(XFS_DA3_NODE_MAGIC) || + info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || + info->magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC) || + info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC) || + info->magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)); + + + /* + * Note: we flatten the magic number to a single type so we + * don't have to compare against crc/non-crc types elsewhere. + */ + switch (be16_to_cpu(info->magic)) { + case XFS_DA_NODE_MAGIC: + case XFS_DA3_NODE_MAGIC: + blk->magic = XFS_DA_NODE_MAGIC; node = (xfs_da_intnode_t *)info; - blk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval); + xfs_da3_node_hdr_from_disk(&nodehdr, node); + btree = xfs_da3_node_tree_p(node); + blk->hashval = be32_to_cpu(btree[nodehdr.count - 1].hashval); if (forward) blk->index = 0; else - blk->index = be16_to_cpu(node->hdr.count)-1; - blkno = be32_to_cpu(node->btree[blk->index].before); - } else { + blk->index = nodehdr.count - 1; + blkno = be32_to_cpu(btree[blk->index].before); + break; + case XFS_ATTR_LEAF_MAGIC: + case XFS_ATTR3_LEAF_MAGIC: + blk->magic = XFS_ATTR_LEAF_MAGIC; ASSERT(level == path->active-1); blk->index = 0; - switch(blk->magic) { - case XFS_ATTR_LEAF_MAGIC: - blk->hashval = xfs_attr_leaf_lasthash(blk->bp, - NULL); - break; - case XFS_DIR2_LEAFN_MAGIC: - blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, - NULL); - break; - default: - ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC || - blk->magic == XFS_DIR2_LEAFN_MAGIC); - break; - } + blk->hashval = xfs_attr_leaf_lasthash(blk->bp, + NULL); + break; + case XFS_DIR2_LEAFN_MAGIC: + case XFS_DIR3_LEAFN_MAGIC: + blk->magic = XFS_DIR2_LEAFN_MAGIC; + ASSERT(level == path->active-1); + blk->index = 0; + blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, + NULL); + break; + default: + ASSERT(0); + break; } } *result = 0; - return(0); + return 0; } @@ -1521,79 +2005,60 @@ .compname = xfs_da_compname }; -/* - * Add a block to the btree ahead of the file. - * Return the new block number to the caller. - */ int -xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) -{ - xfs_fileoff_t bno, b; - xfs_bmbt_irec_t map; - xfs_bmbt_irec_t *mapp; - xfs_inode_t *dp; - int nmap, error, w, count, c, got, i, mapi; - xfs_trans_t *tp; - xfs_mount_t *mp; - xfs_drfsbno_t nblks; +xfs_da_grow_inode_int( + struct xfs_da_args *args, + xfs_fileoff_t *bno, + int count) +{ + struct xfs_trans *tp = args->trans; + struct xfs_inode *dp = args->dp; + int w = args->whichfork; + xfs_drfsbno_t nblks = dp->i_d.di_nblocks; + struct xfs_bmbt_irec map, *mapp; + int nmap, error, got, i, mapi; - dp = args->dp; - mp = dp->i_mount; - w = args->whichfork; - tp = args->trans; - nblks = dp->i_d.di_nblocks; - - /* - * For new directories adjust the file offset and block count. - */ - if (w == XFS_DATA_FORK) { - bno = mp->m_dirleafblk; - count = mp->m_dirblkfsbs; - } else { - bno = 0; - count = 1; - } /* * Find a spot in the file space to put the new block. */ - if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) + error = xfs_bmap_first_unused(tp, dp, count, bno, w); + if (error) return error; - if (w == XFS_DATA_FORK) - ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk); + /* * Try mapping it in one filesystem block. */ nmap = 1; ASSERT(args->firstblock != NULL); - if ((error = xfs_bmapi(tp, dp, bno, count, - xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA| - XFS_BMAPI_CONTIG, + error = xfs_bmapi_write(tp, dp, *bno, count, + xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG, args->firstblock, args->total, &map, &nmap, - args->flist))) { + args->flist); + if (error) return error; - } + ASSERT(nmap <= 1); if (nmap == 1) { mapp = ↦ mapi = 1; - } - /* - * If we didn't get it and the block might work if fragmented, - * try without the CONTIG flag. Loop until we get it all. - */ - else if (nmap == 0 && count > 1) { + } else if (nmap == 0 && count > 1) { + xfs_fileoff_t b; + int c; + + /* + * If we didn't get it and the block might work if fragmented, + * try without the CONTIG flag. Loop until we get it all. + */ mapp = kmem_alloc(sizeof(*mapp) * count, KM_SLEEP); - for (b = bno, mapi = 0; b < bno + count; ) { + for (b = *bno, mapi = 0; b < *bno + count; ) { nmap = MIN(XFS_BMAP_MAX_NMAP, count); - c = (int)(bno + count - b); - if ((error = xfs_bmapi(tp, dp, b, c, - xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE| - XFS_BMAPI_METADATA, + c = (int)(*bno + count - b); + error = xfs_bmapi_write(tp, dp, b, c, + xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA, args->firstblock, args->total, - &mapp[mapi], &nmap, args->flist))) { - kmem_free(mapp); - return error; - } + &mapp[mapi], &nmap, args->flist); + if (error) + goto out_free_map; if (nmap < 1) break; mapi += nmap; @@ -1604,24 +2069,55 @@ mapi = 0; mapp = NULL; } + /* * Count the blocks we got, make sure it matches the total. */ for (i = 0, got = 0; i < mapi; i++) got += mapp[i].br_blockcount; - if (got != count || mapp[0].br_startoff != bno || + if (got != count || mapp[0].br_startoff != *bno || mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount != - bno + count) { - if (mapp != &map) - kmem_free(mapp); - return XFS_ERROR(ENOSPC); + *bno + count) { + error = XFS_ERROR(ENOSPC); + goto out_free_map; } - if (mapp != &map) - kmem_free(mapp); + /* account for newly allocated blocks in reserved blocks total */ args->total -= dp->i_d.di_nblocks - nblks; - *new_blkno = (xfs_dablk_t)bno; - return 0; + +out_free_map: + if (mapp != &map) + kmem_free(mapp); + return error; +} + +/* + * Add a block to the btree ahead of the file. + * Return the new block number to the caller. + */ +int +xfs_da_grow_inode( + struct xfs_da_args *args, + xfs_dablk_t *new_blkno) +{ + xfs_fileoff_t bno; + int count; + int error; + + trace_xfs_da_grow_inode(args); + + if (args->whichfork == XFS_DATA_FORK) { + bno = args->dp->i_mount->m_dirleafblk; + count = args->dp->i_mount->m_dirblkfsbs; + } else { + bno = 0; + count = 1; + } + + error = xfs_da_grow_inode_int(args, &bno, count); + if (!error) + *new_blkno = (xfs_dablk_t)bno; + return error; } /* @@ -1633,20 +2129,38 @@ * a bmap btree split to do that. */ STATIC int -xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, - xfs_dabuf_t **dead_bufp) -{ - xfs_dablk_t dead_blkno, last_blkno, sib_blkno, par_blkno; - xfs_dabuf_t *dead_buf, *last_buf, *sib_buf, *par_buf; - xfs_fileoff_t lastoff; - xfs_inode_t *ip; - xfs_trans_t *tp; - xfs_mount_t *mp; - int error, w, entno, level, dead_level; - xfs_da_blkinfo_t *dead_info, *sib_info; - xfs_da_intnode_t *par_node, *dead_node; - xfs_dir2_leaf_t *dead_leaf2; - xfs_dahash_t dead_hash; +xfs_da3_swap_lastblock( + struct xfs_da_args *args, + xfs_dablk_t *dead_blknop, + struct xfs_buf **dead_bufp) +{ + struct xfs_da_blkinfo *dead_info; + struct xfs_da_blkinfo *sib_info; + struct xfs_da_intnode *par_node; + struct xfs_da_intnode *dead_node; + struct xfs_dir2_leaf *dead_leaf2; + struct xfs_da_node_entry *btree; + struct xfs_da3_icnode_hdr par_hdr; + struct xfs_inode *ip; + struct xfs_trans *tp; + struct xfs_mount *mp; + struct xfs_buf *dead_buf; + struct xfs_buf *last_buf; + struct xfs_buf *sib_buf; + struct xfs_buf *par_buf; + xfs_dahash_t dead_hash; + xfs_fileoff_t lastoff; + xfs_dablk_t dead_blkno; + xfs_dablk_t last_blkno; + xfs_dablk_t sib_blkno; + xfs_dablk_t par_blkno; + int error; + int w; + int entno; + int level; + int dead_level; + + trace_xfs_da_swap_lastblock(args); dead_buf = *dead_bufp; dead_blkno = *dead_blknop; @@ -1668,35 +2182,46 @@ * Read the last block in the btree space. */ last_blkno = (xfs_dablk_t)lastoff - mp->m_dirblkfsbs; - if ((error = xfs_da_read_buf(tp, ip, last_blkno, -1, &last_buf, w))) + error = xfs_da3_node_read(tp, ip, last_blkno, -1, &last_buf, w); + if (error) return error; /* * Copy the last block into the dead buffer and log it. */ - memcpy(dead_buf->data, last_buf->data, mp->m_dirblksize); - xfs_da_log_buf(tp, dead_buf, 0, mp->m_dirblksize - 1); - dead_info = dead_buf->data; + memcpy(dead_buf->b_addr, last_buf->b_addr, mp->m_dirblksize); + xfs_trans_log_buf(tp, dead_buf, 0, mp->m_dirblksize - 1); + dead_info = dead_buf->b_addr; /* * Get values from the moved block. */ - if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) { + if (dead_info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || + dead_info->magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) { + struct xfs_dir3_icleaf_hdr leafhdr; + struct xfs_dir2_leaf_entry *ents; + dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; + xfs_dir3_leaf_hdr_from_disk(&leafhdr, dead_leaf2); + ents = xfs_dir3_leaf_ents_p(dead_leaf2); dead_level = 0; - dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval); + dead_hash = be32_to_cpu(ents[leafhdr.count - 1].hashval); } else { - ASSERT(be16_to_cpu(dead_info->magic) == XFS_DA_NODE_MAGIC); + struct xfs_da3_icnode_hdr deadhdr; + dead_node = (xfs_da_intnode_t *)dead_info; - dead_level = be16_to_cpu(dead_node->hdr.level); - dead_hash = be32_to_cpu(dead_node->btree[be16_to_cpu(dead_node->hdr.count) - 1].hashval); + xfs_da3_node_hdr_from_disk(&deadhdr, dead_node); + btree = xfs_da3_node_tree_p(dead_node); + dead_level = deadhdr.level; + dead_hash = be32_to_cpu(btree[deadhdr.count - 1].hashval); } sib_buf = par_buf = NULL; /* * If the moved block has a left sibling, fix up the pointers. */ if ((sib_blkno = be32_to_cpu(dead_info->back))) { - if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w))) + error = xfs_da3_node_read(tp, ip, sib_blkno, -1, &sib_buf, w); + if (error) goto done; - sib_info = sib_buf->data; + sib_info = sib_buf->b_addr; if (unlikely( be32_to_cpu(sib_info->forw) != last_blkno || sib_info->magic != dead_info->magic)) { @@ -1706,19 +2231,19 @@ goto done; } sib_info->forw = cpu_to_be32(dead_blkno); - xfs_da_log_buf(tp, sib_buf, + xfs_trans_log_buf(tp, sib_buf, XFS_DA_LOGRANGE(sib_info, &sib_info->forw, sizeof(sib_info->forw))); - xfs_da_buf_done(sib_buf); sib_buf = NULL; } /* * If the moved block has a right sibling, fix up the pointers. */ if ((sib_blkno = be32_to_cpu(dead_info->forw))) { - if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w))) + error = xfs_da3_node_read(tp, ip, sib_blkno, -1, &sib_buf, w); + if (error) goto done; - sib_info = sib_buf->data; + sib_info = sib_buf->b_addr; if (unlikely( be32_to_cpu(sib_info->back) != last_blkno || sib_info->magic != dead_info->magic)) { @@ -1728,10 +2253,9 @@ goto done; } sib_info->back = cpu_to_be32(dead_blkno); - xfs_da_log_buf(tp, sib_buf, + xfs_trans_log_buf(tp, sib_buf, XFS_DA_LOGRANGE(sib_info, &sib_info->back, sizeof(sib_info->back))); - xfs_da_buf_done(sib_buf); sib_buf = NULL; } par_blkno = mp->m_dirleafblk; @@ -1740,33 +2264,34 @@ * Walk down the tree looking for the parent of the moved block. */ for (;;) { - if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w))) + error = xfs_da3_node_read(tp, ip, par_blkno, -1, &par_buf, w); + if (error) goto done; - par_node = par_buf->data; - if (unlikely( - be16_to_cpu(par_node->hdr.info.magic) != XFS_DA_NODE_MAGIC || - (level >= 0 && level != be16_to_cpu(par_node->hdr.level) + 1))) { + par_node = par_buf->b_addr; + xfs_da3_node_hdr_from_disk(&par_hdr, par_node); + if (level >= 0 && level != par_hdr.level + 1) { XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)", XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } - level = be16_to_cpu(par_node->hdr.level); + level = par_hdr.level; + btree = xfs_da3_node_tree_p(par_node); for (entno = 0; - entno < be16_to_cpu(par_node->hdr.count) && - be32_to_cpu(par_node->btree[entno].hashval) < dead_hash; + entno < par_hdr.count && + be32_to_cpu(btree[entno].hashval) < dead_hash; entno++) continue; - if (unlikely(entno == be16_to_cpu(par_node->hdr.count))) { + if (entno == par_hdr.count) { XFS_ERROR_REPORT("xfs_da_swap_lastblock(5)", XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } - par_blkno = be32_to_cpu(par_node->btree[entno].before); + par_blkno = be32_to_cpu(btree[entno].before); if (level == dead_level + 1) break; - xfs_da_brelse(tp, par_buf); + xfs_trans_brelse(tp, par_buf); par_buf = NULL; } /* @@ -1775,14 +2300,14 @@ */ for (;;) { for (; - entno < be16_to_cpu(par_node->hdr.count) && - be32_to_cpu(par_node->btree[entno].before) != last_blkno; + entno < par_hdr.count && + be32_to_cpu(btree[entno].before) != last_blkno; entno++) continue; - if (entno < be16_to_cpu(par_node->hdr.count)) + if (entno < par_hdr.count) break; - par_blkno = be32_to_cpu(par_node->hdr.info.forw); - xfs_da_brelse(tp, par_buf); + par_blkno = par_hdr.forw; + xfs_trans_brelse(tp, par_buf); par_buf = NULL; if (unlikely(par_blkno == 0)) { XFS_ERROR_REPORT("xfs_da_swap_lastblock(6)", @@ -1790,37 +2315,36 @@ error = XFS_ERROR(EFSCORRUPTED); goto done; } - if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w))) + error = xfs_da3_node_read(tp, ip, par_blkno, -1, &par_buf, w); + if (error) goto done; - par_node = par_buf->data; - if (unlikely( - be16_to_cpu(par_node->hdr.level) != level || - be16_to_cpu(par_node->hdr.info.magic) != XFS_DA_NODE_MAGIC)) { + par_node = par_buf->b_addr; + xfs_da3_node_hdr_from_disk(&par_hdr, par_node); + if (par_hdr.level != level) { XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)", XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } + btree = xfs_da3_node_tree_p(par_node); entno = 0; } /* * Update the parent entry pointing to the moved block. */ - par_node->btree[entno].before = cpu_to_be32(dead_blkno); - xfs_da_log_buf(tp, par_buf, - XFS_DA_LOGRANGE(par_node, &par_node->btree[entno].before, - sizeof(par_node->btree[entno].before))); - xfs_da_buf_done(par_buf); - xfs_da_buf_done(dead_buf); + btree[entno].before = cpu_to_be32(dead_blkno); + xfs_trans_log_buf(tp, par_buf, + XFS_DA_LOGRANGE(par_node, &btree[entno].before, + sizeof(btree[entno].before))); *dead_blknop = last_blkno; *dead_bufp = last_buf; return 0; done: if (par_buf) - xfs_da_brelse(tp, par_buf); + xfs_trans_brelse(tp, par_buf); if (sib_buf) - xfs_da_brelse(tp, sib_buf); - xfs_da_brelse(tp, last_buf); + xfs_trans_brelse(tp, sib_buf); + xfs_trans_brelse(tp, last_buf); return error; } @@ -1828,14 +2352,18 @@ * Remove a btree block from a directory or attribute. */ int -xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, - xfs_dabuf_t *dead_buf) +xfs_da_shrink_inode( + xfs_da_args_t *args, + xfs_dablk_t dead_blkno, + struct xfs_buf *dead_buf) { xfs_inode_t *dp; int done, error, w, count; xfs_trans_t *tp; xfs_mount_t *mp; + trace_xfs_da_shrink_inode(args); + dp = args->dp; w = args->whichfork; tp = args->trans; @@ -1849,20 +2377,21 @@ * Remove extents. If we get ENOSPC for a dir we have to move * the last block to the place we want to kill. */ - if ((error = xfs_bunmapi(tp, dp, dead_blkno, count, - xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA, - 0, args->firstblock, args->flist, - &done)) == ENOSPC) { + error = xfs_bunmapi(tp, dp, dead_blkno, count, + xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA, + 0, args->firstblock, args->flist, &done); + if (error == ENOSPC) { if (w != XFS_DATA_FORK) break; - if ((error = xfs_da_swap_lastblock(args, &dead_blkno, - &dead_buf))) + error = xfs_da3_swap_lastblock(args, &dead_blkno, + &dead_buf); + if (error) break; } else { break; } } - xfs_da_binval(tp, dead_buf); + xfs_trans_binval(tp, dead_buf); return error; } @@ -1894,36 +2423,76 @@ } /* - * Make a dabuf. - * Used for get_buf, read_buf, read_bufr, and reada_buf. - */ -int -xfs_da_do_buf( - xfs_trans_t *trans, - xfs_inode_t *dp, - xfs_dablk_t bno, - xfs_daddr_t *mappedbnop, - xfs_dabuf_t **bpp, - int whichfork, - int caller, - inst_t *ra) -{ - xfs_buf_t *bp = NULL; - xfs_buf_t **bplist; - int error=0; - int i; - xfs_bmbt_irec_t map; - xfs_bmbt_irec_t *mapp; - xfs_daddr_t mappedbno; - xfs_mount_t *mp; - int nbplist=0; - int nfsb; - int nmap; - xfs_dabuf_t *rbp; + * Convert a struct xfs_bmbt_irec to a struct xfs_buf_map. + * + * For the single map case, it is assumed that the caller has provided a pointer + * to a valid xfs_buf_map. For the multiple map case, this function will + * allocate the xfs_buf_map to hold all the maps and replace the caller's single + * map pointer with the allocated map. + */ +static int +xfs_buf_map_from_irec( + struct xfs_mount *mp, + struct xfs_buf_map **mapp, + int *nmaps, + struct xfs_bmbt_irec *irecs, + int nirecs) +{ + struct xfs_buf_map *map; + int i; + + ASSERT(*nmaps == 1); + ASSERT(nirecs >= 1); + + if (nirecs > 1) { + map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), + KM_SLEEP | KM_NOFS); + if (!map) + return ENOMEM; + *mapp = map; + } + + *nmaps = nirecs; + map = *mapp; + for (i = 0; i < *nmaps; i++) { + ASSERT(irecs[i].br_startblock != DELAYSTARTBLOCK && + irecs[i].br_startblock != HOLESTARTBLOCK); + map[i].bm_bn = XFS_FSB_TO_DADDR(mp, irecs[i].br_startblock); + map[i].bm_len = XFS_FSB_TO_BB(mp, irecs[i].br_blockcount); + } + return 0; +} + +/* + * Map the block we are given ready for reading. There are three possible return + * values: + * -1 - will be returned if we land in a hole and mappedbno == -2 so the + * caller knows not to execute a subsequent read. + * 0 - if we mapped the block successfully + * >0 - positive error number if there was an error. + */ +static int +xfs_dabuf_map( + struct xfs_trans *trans, + struct xfs_inode *dp, + xfs_dablk_t bno, + xfs_daddr_t mappedbno, + int whichfork, + struct xfs_buf_map **map, + int *nmaps) +{ + struct xfs_mount *mp = dp->i_mount; + int nfsb; + int error = 0; + struct xfs_bmbt_irec irec; + struct xfs_bmbt_irec *irecs = &irec; + int nirecs; + + ASSERT(map && *map); + ASSERT(*nmaps == 1); - mp = dp->i_mount; nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1; - mappedbno = *mappedbnop; + /* * Caller doesn't have a mapping. -2 means don't complain * if we land in a hole. @@ -1932,178 +2501,50 @@ /* * Optimize the one-block case. */ - if (nfsb == 1) { - xfs_fsblock_t fsb; - - if ((error = - xfs_bmapi_single(trans, dp, whichfork, &fsb, - (xfs_fileoff_t)bno))) { - return error; - } - mapp = ↦ - if (fsb == NULLFSBLOCK) { - nmap = 0; - } else { - map.br_startblock = fsb; - map.br_startoff = (xfs_fileoff_t)bno; - map.br_blockcount = 1; - nmap = 1; - } - } else { - mapp = kmem_alloc(sizeof(*mapp) * nfsb, KM_SLEEP); - nmap = nfsb; - if ((error = xfs_bmapi(trans, dp, (xfs_fileoff_t)bno, - nfsb, - XFS_BMAPI_METADATA | - xfs_bmapi_aflag(whichfork), - NULL, 0, mapp, &nmap, NULL))) - goto exit0; - } + if (nfsb != 1) + irecs = kmem_zalloc(sizeof(irec) * nfsb, + KM_SLEEP | KM_NOFS); + + nirecs = nfsb; + error = xfs_bmapi_read(dp, (xfs_fileoff_t)bno, nfsb, irecs, + &nirecs, xfs_bmapi_aflag(whichfork)); + if (error) + goto out; } else { - map.br_startblock = XFS_DADDR_TO_FSB(mp, mappedbno); - map.br_startoff = (xfs_fileoff_t)bno; - map.br_blockcount = nfsb; - mapp = ↦ - nmap = 1; + irecs->br_startblock = XFS_DADDR_TO_FSB(mp, mappedbno); + irecs->br_startoff = (xfs_fileoff_t)bno; + irecs->br_blockcount = nfsb; + irecs->br_state = 0; + nirecs = 1; } - if (!xfs_da_map_covers_blocks(nmap, mapp, bno, nfsb)) { - error = mappedbno == -2 ? 0 : XFS_ERROR(EFSCORRUPTED); + + if (!xfs_da_map_covers_blocks(nirecs, irecs, bno, nfsb)) { + error = mappedbno == -2 ? -1 : XFS_ERROR(EFSCORRUPTED); if (unlikely(error == EFSCORRUPTED)) { if (xfs_error_level >= XFS_ERRLEVEL_LOW) { - cmn_err(CE_ALERT, "xfs_da_do_buf: bno %lld\n", - (long long)bno); - cmn_err(CE_ALERT, "dir: inode %lld\n", + int i; + xfs_alert(mp, "%s: bno %lld dir: inode %lld", + __func__, (long long)bno, (long long)dp->i_ino); - for (i = 0; i < nmap; i++) { - cmn_err(CE_ALERT, - "[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d\n", + for (i = 0; i < *nmaps; i++) { + xfs_alert(mp, +"[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d", i, - (long long)mapp[i].br_startoff, - (long long)mapp[i].br_startblock, - (long long)mapp[i].br_blockcount, - mapp[i].br_state); + (long long)irecs[i].br_startoff, + (long long)irecs[i].br_startblock, + (long long)irecs[i].br_blockcount, + irecs[i].br_state); } } XFS_ERROR_REPORT("xfs_da_do_buf(1)", XFS_ERRLEVEL_LOW, mp); } - goto exit0; + goto out; } - if (caller != 3 && nmap > 1) { - bplist = kmem_alloc(sizeof(*bplist) * nmap, KM_SLEEP); - nbplist = 0; - } else - bplist = NULL; - /* - * Turn the mapping(s) into buffer(s). - */ - for (i = 0; i < nmap; i++) { - int nmapped; - - mappedbno = XFS_FSB_TO_DADDR(mp, mapp[i].br_startblock); - if (i == 0) - *mappedbnop = mappedbno; - nmapped = (int)XFS_FSB_TO_BB(mp, mapp[i].br_blockcount); - switch (caller) { - case 0: - bp = xfs_trans_get_buf(trans, mp->m_ddev_targp, - mappedbno, nmapped, 0); - error = bp ? XFS_BUF_GETERROR(bp) : XFS_ERROR(EIO); - break; - case 1: - case 2: - bp = NULL; - error = xfs_trans_read_buf(mp, trans, mp->m_ddev_targp, - mappedbno, nmapped, 0, &bp); - break; - case 3: - xfs_buf_readahead(mp->m_ddev_targp, mappedbno, nmapped); - error = 0; - bp = NULL; - break; - } - if (error) { - if (bp) - xfs_trans_brelse(trans, bp); - goto exit1; - } - if (!bp) - continue; - if (caller == 1) { - if (whichfork == XFS_ATTR_FORK) { - XFS_BUF_SET_VTYPE_REF(bp, B_FS_ATTR_BTREE, - XFS_ATTR_BTREE_REF); - } else { - XFS_BUF_SET_VTYPE_REF(bp, B_FS_DIR_BTREE, - XFS_DIR_BTREE_REF); - } - } - if (bplist) { - bplist[nbplist++] = bp; - } - } - /* - * Build a dabuf structure. - */ - if (bplist) { - rbp = xfs_da_buf_make(nbplist, bplist, ra); - } else if (bp) - rbp = xfs_da_buf_make(1, &bp, ra); - else - rbp = NULL; - /* - * For read_buf, check the magic number. - */ - if (caller == 1) { - xfs_dir2_data_t *data; - xfs_dir2_free_t *free; - xfs_da_blkinfo_t *info; - uint magic, magic1; - - info = rbp->data; - data = rbp->data; - free = rbp->data; - magic = be16_to_cpu(info->magic); - magic1 = be32_to_cpu(data->hdr.magic); - if (unlikely( - XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && - (magic != XFS_ATTR_LEAF_MAGIC) && - (magic != XFS_DIR2_LEAF1_MAGIC) && - (magic != XFS_DIR2_LEAFN_MAGIC) && - (magic1 != XFS_DIR2_BLOCK_MAGIC) && - (magic1 != XFS_DIR2_DATA_MAGIC) && - (be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC), - mp, XFS_ERRTAG_DA_READ_BUF, - XFS_RANDOM_DA_READ_BUF))) { - trace_xfs_da_btree_corrupt(rbp->bps[0], _RET_IP_); - XFS_CORRUPTION_ERROR("xfs_da_do_buf(2)", - XFS_ERRLEVEL_LOW, mp, info); - error = XFS_ERROR(EFSCORRUPTED); - xfs_da_brelse(trans, rbp); - nbplist = 0; - goto exit1; - } - } - if (bplist) { - kmem_free(bplist); - } - if (mapp != &map) { - kmem_free(mapp); - } - if (bpp) - *bpp = rbp; - return 0; -exit1: - if (bplist) { - for (i = 0; i < nbplist; i++) - xfs_trans_brelse(trans, bplist[i]); - kmem_free(bplist); - } -exit0: - if (mapp != &map) - kmem_free(mapp); - if (bpp) - *bpp = NULL; + error = xfs_buf_map_from_irec(mp, map, nmaps, irecs, nirecs); +out: + if (irecs != &irec) + kmem_free(irecs); return error; } @@ -2112,328 +2553,175 @@ */ int xfs_da_get_buf( - xfs_trans_t *trans, - xfs_inode_t *dp, - xfs_dablk_t bno, + struct xfs_trans *trans, + struct xfs_inode *dp, + xfs_dablk_t bno, xfs_daddr_t mappedbno, - xfs_dabuf_t **bpp, - int whichfork) + struct xfs_buf **bpp, + int whichfork) { - return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 0, - (inst_t *)__return_address); -} + struct xfs_buf *bp; + struct xfs_buf_map map; + struct xfs_buf_map *mapp; + int nmap; + int error; -/* - * Get a buffer for the dir/attr block, fill in the contents. - */ -int -xfs_da_read_buf( - xfs_trans_t *trans, - xfs_inode_t *dp, - xfs_dablk_t bno, - xfs_daddr_t mappedbno, - xfs_dabuf_t **bpp, - int whichfork) -{ - return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 1, - (inst_t *)__return_address); -} - -/* - * Readahead the dir/attr block. - */ -xfs_daddr_t -xfs_da_reada_buf( - xfs_trans_t *trans, - xfs_inode_t *dp, - xfs_dablk_t bno, - int whichfork) -{ - xfs_daddr_t rval; - - rval = -1; - if (xfs_da_do_buf(trans, dp, bno, &rval, NULL, whichfork, 3, - (inst_t *)__return_address)) - return -1; - else - return rval; -} + *bpp = NULL; + mapp = ↦ + nmap = 1; + error = xfs_dabuf_map(trans, dp, bno, mappedbno, whichfork, + &mapp, &nmap); + if (error) { + /* mapping a hole is not an error, but we don't continue */ + if (error == -1) + error = 0; + goto out_free; + } -kmem_zone_t *xfs_da_state_zone; /* anchor for state struct zone */ -kmem_zone_t *xfs_dabuf_zone; /* dabuf zone */ + bp = xfs_trans_get_buf_map(trans, dp->i_mount->m_ddev_targp, + mapp, nmap, 0); + error = bp ? bp->b_error : XFS_ERROR(EIO); + if (error) { + if (bp) + xfs_trans_brelse(trans, bp); + goto out_free; + } -/* - * Allocate a dir-state structure. - * We don't put them on the stack since they're large. - */ -xfs_da_state_t * -xfs_da_state_alloc(void) -{ - return kmem_zone_zalloc(xfs_da_state_zone, KM_NOFS); -} + *bpp = bp; -/* - * Kill the altpath contents of a da-state structure. - */ -STATIC void -xfs_da_state_kill_altpath(xfs_da_state_t *state) -{ - int i; +out_free: + if (mapp != &map) + kmem_free(mapp); - for (i = 0; i < state->altpath.active; i++) { - if (state->altpath.blk[i].bp) { - if (state->altpath.blk[i].bp != state->path.blk[i].bp) - xfs_da_buf_done(state->altpath.blk[i].bp); - state->altpath.blk[i].bp = NULL; - } - } - state->altpath.active = 0; + return error; } /* - * Free a da-state structure. + * Get a buffer for the dir/attr block, fill in the contents. */ -void -xfs_da_state_free(xfs_da_state_t *state) -{ - int i; +int +xfs_da_read_buf( + struct xfs_trans *trans, + struct xfs_inode *dp, + xfs_dablk_t bno, + xfs_daddr_t mappedbno, + struct xfs_buf **bpp, + int whichfork, + const struct xfs_buf_ops *ops) +{ + struct xfs_buf *bp; + struct xfs_buf_map map; + struct xfs_buf_map *mapp; + int nmap; + int error; - xfs_da_state_kill_altpath(state); - for (i = 0; i < state->path.active; i++) { - if (state->path.blk[i].bp) - xfs_da_buf_done(state->path.blk[i].bp); + *bpp = NULL; + mapp = ↦ + nmap = 1; + error = xfs_dabuf_map(trans, dp, bno, mappedbno, whichfork, + &mapp, &nmap); + if (error) { + /* mapping a hole is not an error, but we don't continue */ + if (error == -1) + error = 0; + goto out_free; } - if (state->extravalid && state->extrablk.bp) - xfs_da_buf_done(state->extrablk.bp); -#ifdef DEBUG - memset((char *)state, 0, sizeof(*state)); -#endif /* DEBUG */ - kmem_zone_free(xfs_da_state_zone, state); -} -#ifdef XFS_DABUF_DEBUG -xfs_dabuf_t *xfs_dabuf_global_list; -static DEFINE_SPINLOCK(xfs_dabuf_global_lock); -#endif - -/* - * Create a dabuf. - */ -/* ARGSUSED */ -STATIC xfs_dabuf_t * -xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra) -{ - xfs_buf_t *bp; - xfs_dabuf_t *dabuf; - int i; - int off; + error = xfs_trans_read_buf_map(dp->i_mount, trans, + dp->i_mount->m_ddev_targp, + mapp, nmap, 0, &bp, ops); + if (error) + goto out_free; - if (nbuf == 1) - dabuf = kmem_zone_alloc(xfs_dabuf_zone, KM_NOFS); + if (whichfork == XFS_ATTR_FORK) + xfs_buf_set_ref(bp, XFS_ATTR_BTREE_REF); else - dabuf = kmem_alloc(XFS_DA_BUF_SIZE(nbuf), KM_NOFS); - dabuf->dirty = 0; -#ifdef XFS_DABUF_DEBUG - dabuf->ra = ra; - dabuf->target = XFS_BUF_TARGET(bps[0]); - dabuf->blkno = XFS_BUF_ADDR(bps[0]); -#endif - if (nbuf == 1) { - dabuf->nbuf = 1; - bp = bps[0]; - dabuf->bbcount = (short)BTOBB(XFS_BUF_COUNT(bp)); - dabuf->data = XFS_BUF_PTR(bp); - dabuf->bps[0] = bp; - } else { - dabuf->nbuf = nbuf; - for (i = 0, dabuf->bbcount = 0; i < nbuf; i++) { - dabuf->bps[i] = bp = bps[i]; - dabuf->bbcount += BTOBB(XFS_BUF_COUNT(bp)); - } - dabuf->data = kmem_alloc(BBTOB(dabuf->bbcount), KM_SLEEP); - for (i = off = 0; i < nbuf; i++, off += XFS_BUF_COUNT(bp)) { - bp = bps[i]; - memcpy((char *)dabuf->data + off, XFS_BUF_PTR(bp), - XFS_BUF_COUNT(bp)); - } - } -#ifdef XFS_DABUF_DEBUG - { - xfs_dabuf_t *p; + xfs_buf_set_ref(bp, XFS_DIR_BTREE_REF); - spin_lock(&xfs_dabuf_global_lock); - for (p = xfs_dabuf_global_list; p; p = p->next) { - ASSERT(p->blkno != dabuf->blkno || - p->target != dabuf->target); - } - dabuf->prev = NULL; - if (xfs_dabuf_global_list) - xfs_dabuf_global_list->prev = dabuf; - dabuf->next = xfs_dabuf_global_list; - xfs_dabuf_global_list = dabuf; - spin_unlock(&xfs_dabuf_global_lock); - } -#endif - return dabuf; -} - -/* - * Un-dirty a dabuf. - */ -STATIC void -xfs_da_buf_clean(xfs_dabuf_t *dabuf) -{ - xfs_buf_t *bp; - int i; - int off; + /* + * This verification code will be moved to a CRC verification callback + * function so just leave it here unchanged until then. + */ + { + xfs_dir2_data_hdr_t *hdr = bp->b_addr; + xfs_dir2_free_t *free = bp->b_addr; + xfs_da_blkinfo_t *info = bp->b_addr; + uint magic, magic1; + struct xfs_mount *mp = dp->i_mount; - if (dabuf->dirty) { - ASSERT(dabuf->nbuf > 1); - dabuf->dirty = 0; - for (i = off = 0; i < dabuf->nbuf; - i++, off += XFS_BUF_COUNT(bp)) { - bp = dabuf->bps[i]; - memcpy(XFS_BUF_PTR(bp), (char *)dabuf->data + off, - XFS_BUF_COUNT(bp)); + magic = be16_to_cpu(info->magic); + magic1 = be32_to_cpu(hdr->magic); + if (unlikely( + XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && + (magic != XFS_DA3_NODE_MAGIC) && + (magic != XFS_ATTR_LEAF_MAGIC) && + (magic != XFS_ATTR3_LEAF_MAGIC) && + (magic != XFS_DIR2_LEAF1_MAGIC) && + (magic != XFS_DIR3_LEAF1_MAGIC) && + (magic != XFS_DIR2_LEAFN_MAGIC) && + (magic != XFS_DIR3_LEAFN_MAGIC) && + (magic1 != XFS_DIR2_BLOCK_MAGIC) && + (magic1 != XFS_DIR3_BLOCK_MAGIC) && + (magic1 != XFS_DIR2_DATA_MAGIC) && + (magic1 != XFS_DIR3_DATA_MAGIC) && + (free->hdr.magic != + cpu_to_be32(XFS_DIR2_FREE_MAGIC)) && + (free->hdr.magic != + cpu_to_be32(XFS_DIR3_FREE_MAGIC)), + mp, XFS_ERRTAG_DA_READ_BUF, + XFS_RANDOM_DA_READ_BUF))) { + trace_xfs_da_btree_corrupt(bp, _RET_IP_); + XFS_CORRUPTION_ERROR("xfs_da_do_buf(2)", + XFS_ERRLEVEL_LOW, mp, info); + error = XFS_ERROR(EFSCORRUPTED); + xfs_trans_brelse(trans, bp); + goto out_free; } } -} - -/* - * Release a dabuf. - */ -void -xfs_da_buf_done(xfs_dabuf_t *dabuf) -{ - ASSERT(dabuf); - ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); - if (dabuf->dirty) - xfs_da_buf_clean(dabuf); - if (dabuf->nbuf > 1) - kmem_free(dabuf->data); -#ifdef XFS_DABUF_DEBUG - { - spin_lock(&xfs_dabuf_global_lock); - if (dabuf->prev) - dabuf->prev->next = dabuf->next; - else - xfs_dabuf_global_list = dabuf->next; - if (dabuf->next) - dabuf->next->prev = dabuf->prev; - spin_unlock(&xfs_dabuf_global_lock); - } - memset(dabuf, 0, XFS_DA_BUF_SIZE(dabuf->nbuf)); -#endif - if (dabuf->nbuf == 1) - kmem_zone_free(xfs_dabuf_zone, dabuf); - else - kmem_free(dabuf); -} - -/* - * Log transaction from a dabuf. - */ -void -xfs_da_log_buf(xfs_trans_t *tp, xfs_dabuf_t *dabuf, uint first, uint last) -{ - xfs_buf_t *bp; - uint f; - int i; - uint l; - int off; + *bpp = bp; +out_free: + if (mapp != &map) + kmem_free(mapp); - ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); - if (dabuf->nbuf == 1) { - ASSERT(dabuf->data == (void *)XFS_BUF_PTR(dabuf->bps[0])); - xfs_trans_log_buf(tp, dabuf->bps[0], first, last); - return; - } - dabuf->dirty = 1; - ASSERT(first <= last); - for (i = off = 0; i < dabuf->nbuf; i++, off += XFS_BUF_COUNT(bp)) { - bp = dabuf->bps[i]; - f = off; - l = f + XFS_BUF_COUNT(bp) - 1; - if (f < first) - f = first; - if (l > last) - l = last; - if (f <= l) - xfs_trans_log_buf(tp, bp, f - off, l - off); - /* - * B_DONE is set by xfs_trans_log buf. - * If we don't set it on a new buffer (get not read) - * then if we don't put anything in the buffer it won't - * be set, and at commit it it released into the cache, - * and then a read will fail. - */ - else if (!(XFS_BUF_ISDONE(bp))) - XFS_BUF_DONE(bp); - } - ASSERT(last < off); + return error; } /* - * Release dabuf from a transaction. - * Have to free up the dabuf before the buffers are released, - * since the synchronization on the dabuf is really the lock on the buffer. + * Readahead the dir/attr block. */ -void -xfs_da_brelse(xfs_trans_t *tp, xfs_dabuf_t *dabuf) +xfs_daddr_t +xfs_da_reada_buf( + struct xfs_trans *trans, + struct xfs_inode *dp, + xfs_dablk_t bno, + xfs_daddr_t mappedbno, + int whichfork, + const struct xfs_buf_ops *ops) { - xfs_buf_t *bp; - xfs_buf_t **bplist; - int i; - int nbuf; + struct xfs_buf_map map; + struct xfs_buf_map *mapp; + int nmap; + int error; - ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); - if ((nbuf = dabuf->nbuf) == 1) { - bplist = &bp; - bp = dabuf->bps[0]; - } else { - bplist = kmem_alloc(nbuf * sizeof(*bplist), KM_SLEEP); - memcpy(bplist, dabuf->bps, nbuf * sizeof(*bplist)); + mapp = ↦ + nmap = 1; + error = xfs_dabuf_map(trans, dp, bno, mappedbno, whichfork, + &mapp, &nmap); + if (error) { + /* mapping a hole is not an error, but we don't continue */ + if (error == -1) + error = 0; + goto out_free; } - xfs_da_buf_done(dabuf); - for (i = 0; i < nbuf; i++) - xfs_trans_brelse(tp, bplist[i]); - if (bplist != &bp) - kmem_free(bplist); -} -/* - * Invalidate dabuf from a transaction. - */ -void -xfs_da_binval(xfs_trans_t *tp, xfs_dabuf_t *dabuf) -{ - xfs_buf_t *bp; - xfs_buf_t **bplist; - int i; - int nbuf; + mappedbno = mapp[0].bm_bn; + xfs_buf_readahead_map(dp->i_mount->m_ddev_targp, mapp, nmap, ops); - ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); - if ((nbuf = dabuf->nbuf) == 1) { - bplist = &bp; - bp = dabuf->bps[0]; - } else { - bplist = kmem_alloc(nbuf * sizeof(*bplist), KM_SLEEP); - memcpy(bplist, dabuf->bps, nbuf * sizeof(*bplist)); - } - xfs_da_buf_done(dabuf); - for (i = 0; i < nbuf; i++) - xfs_trans_binval(tp, bplist[i]); - if (bplist != &bp) - kmem_free(bplist); -} +out_free: + if (mapp != &map) + kmem_free(mapp); -/* - * Get the first daddr from a dabuf. - */ -xfs_daddr_t -xfs_da_blkno(xfs_dabuf_t *dabuf) -{ - ASSERT(dabuf->nbuf); - ASSERT(dabuf->data); - return XFS_BUF_ADDR(dabuf->bps[0]); + if (error) + return -1; + return mappedbno; } diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2_block.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_dir2_block.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2_block.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_dir2_block.c 2014-05-02 00:09:16.000000000 +0000 @@ -1,5 +1,6 @@ /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. + * Copyright (c) 2013 Red Hat, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -21,10 +22,10 @@ /* * Local function prototypes. */ -static void xfs_dir2_block_log_leaf(xfs_trans_t *tp, xfs_dabuf_t *bp, int first, - int last); -static void xfs_dir2_block_log_tail(xfs_trans_t *tp, xfs_dabuf_t *bp); -static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **bpp, +static void xfs_dir2_block_log_leaf(xfs_trans_t *tp, struct xfs_buf *bp, + int first, int last); +static void xfs_dir2_block_log_tail(xfs_trans_t *tp, struct xfs_buf *bp); +static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, struct xfs_buf **bpp, int *entno); static int xfs_dir2_block_sort(const void *a, const void *b); @@ -40,6 +41,273 @@ xfs_dir_hash_dotdot = xfs_da_hashname((unsigned char *)"..", 2); } +static bool +xfs_dir3_block_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + if (hdr3->magic != cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) + return false; + if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_uuid)) + return false; + if (be64_to_cpu(hdr3->blkno) != bp->b_bn) + return false; + } else { + if (hdr3->magic != cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) + return false; + } + if (__xfs_dir3_data_check(NULL, bp)) + return false; + return true; +} + +static void +xfs_dir3_block_read_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + + if (xfs_sb_version_hascrc(&mp->m_sb) && + !xfs_buf_verify_cksum(bp, XFS_DIR3_DATA_CRC_OFF)) + xfs_buf_ioerror(bp, EFSBADCRC); + else if (!xfs_dir3_block_verify(bp)) + xfs_buf_ioerror(bp, EFSCORRUPTED); + + if (bp->b_error) + xfs_verifier_error(bp); +} + +static void +xfs_dir3_block_write_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; + + if (!xfs_dir3_block_verify(bp)) { + xfs_buf_ioerror(bp, EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return; + + if (bip) + hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn); + + xfs_buf_update_cksum(bp, XFS_DIR3_DATA_CRC_OFF); +} + +const struct xfs_buf_ops xfs_dir3_block_buf_ops = { + .verify_read = xfs_dir3_block_read_verify, + .verify_write = xfs_dir3_block_write_verify, +}; + +int +xfs_dir3_block_read( + struct xfs_trans *tp, + struct xfs_inode *dp, + struct xfs_buf **bpp) +{ + struct xfs_mount *mp = dp->i_mount; + int err; + + err = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, bpp, + XFS_DATA_FORK, &xfs_dir3_block_buf_ops); + if (!err && tp) + xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_BLOCK_BUF); + return err; +} + +static void +xfs_dir3_block_init( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_buf *bp, + struct xfs_inode *dp) +{ + struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; + + bp->b_ops = &xfs_dir3_block_buf_ops; + xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_BLOCK_BUF); + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + memset(hdr3, 0, sizeof(*hdr3)); + hdr3->magic = cpu_to_be32(XFS_DIR3_BLOCK_MAGIC); + hdr3->blkno = cpu_to_be64(bp->b_bn); + hdr3->owner = cpu_to_be64(dp->i_ino); + uuid_copy(&hdr3->uuid, &mp->m_sb.sb_uuid); + return; + + } + hdr3->magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); +} + +static void +xfs_dir2_block_need_space( + struct xfs_dir2_data_hdr *hdr, + struct xfs_dir2_block_tail *btp, + struct xfs_dir2_leaf_entry *blp, + __be16 **tagpp, + struct xfs_dir2_data_unused **dupp, + struct xfs_dir2_data_unused **enddupp, + int *compact, + int len) +{ + struct xfs_dir2_data_free *bf; + __be16 *tagp = NULL; + struct xfs_dir2_data_unused *dup = NULL; + struct xfs_dir2_data_unused *enddup = NULL; + + *compact = 0; + bf = xfs_dir3_data_bestfree_p(hdr); + + /* + * If there are stale entries we'll use one for the leaf. + */ + if (btp->stale) { + if (be16_to_cpu(bf[0].length) >= len) { + /* + * The biggest entry enough to avoid compaction. + */ + dup = (xfs_dir2_data_unused_t *) + ((char *)hdr + be16_to_cpu(bf[0].offset)); + goto out; + } + + /* + * Will need to compact to make this work. + * Tag just before the first leaf entry. + */ + *compact = 1; + tagp = (__be16 *)blp - 1; + + /* Data object just before the first leaf entry. */ + dup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp)); + + /* + * If it's not free then the data will go where the + * leaf data starts now, if it works at all. + */ + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { + if (be16_to_cpu(dup->length) + (be32_to_cpu(btp->stale) - 1) * + (uint)sizeof(*blp) < len) + dup = NULL; + } else if ((be32_to_cpu(btp->stale) - 1) * (uint)sizeof(*blp) < len) + dup = NULL; + else + dup = (xfs_dir2_data_unused_t *)blp; + goto out; + } + + /* + * no stale entries, so just use free space. + * Tag just before the first leaf entry. + */ + tagp = (__be16 *)blp - 1; + + /* Data object just before the first leaf entry. */ + enddup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp)); + + /* + * If it's not free then can't do this add without cleaning up: + * the space before the first leaf entry needs to be free so it + * can be expanded to hold the pointer to the new entry. + */ + if (be16_to_cpu(enddup->freetag) == XFS_DIR2_DATA_FREE_TAG) { + /* + * Check out the biggest freespace and see if it's the same one. + */ + dup = (xfs_dir2_data_unused_t *) + ((char *)hdr + be16_to_cpu(bf[0].offset)); + if (dup != enddup) { + /* + * Not the same free entry, just check its length. + */ + if (be16_to_cpu(dup->length) < len) + dup = NULL; + goto out; + } + + /* + * It is the biggest freespace, can it hold the leaf too? + */ + if (be16_to_cpu(dup->length) < len + (uint)sizeof(*blp)) { + /* + * Yes, use the second-largest entry instead if it works. + */ + if (be16_to_cpu(bf[1].length) >= len) + dup = (xfs_dir2_data_unused_t *) + ((char *)hdr + be16_to_cpu(bf[1].offset)); + else + dup = NULL; + } + } +out: + *tagpp = tagp; + *dupp = dup; + *enddupp = enddup; +} + +/* + * compact the leaf entries. + * Leave the highest-numbered stale entry stale. + * XXX should be the one closest to mid but mid is not yet computed. + */ +static void +xfs_dir2_block_compact( + struct xfs_trans *tp, + struct xfs_buf *bp, + struct xfs_dir2_data_hdr *hdr, + struct xfs_dir2_block_tail *btp, + struct xfs_dir2_leaf_entry *blp, + int *needlog, + int *lfloghigh, + int *lfloglow) +{ + int fromidx; /* source leaf index */ + int toidx; /* target leaf index */ + int needscan = 0; + int highstale; /* high stale index */ + + fromidx = toidx = be32_to_cpu(btp->count) - 1; + highstale = *lfloghigh = -1; + for (; fromidx >= 0; fromidx--) { + if (blp[fromidx].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) { + if (highstale == -1) + highstale = toidx; + else { + if (*lfloghigh == -1) + *lfloghigh = toidx; + continue; + } + } + if (fromidx < toidx) + blp[toidx] = blp[fromidx]; + toidx--; + } + *lfloglow = toidx + 1 - (be32_to_cpu(btp->stale) - 1); + *lfloghigh -= be32_to_cpu(btp->stale) - 1; + be32_add_cpu(&btp->count, -(be32_to_cpu(btp->stale) - 1)); + xfs_dir2_data_make_free(tp, bp, + (xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr), + (xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)), + needlog, &needscan); + blp += be32_to_cpu(btp->stale) - 1; + btp->stale = cpu_to_be32(1); + /* + * If we now need to rebuild the bestfree map, do so. + * This needs to happen before the next call to use_free. + */ + if (needscan) + xfs_dir2_data_freescan(tp->t_mountp, hdr, needlog); +} + /* * Add an entry to a block directory. */ @@ -47,10 +315,9 @@ xfs_dir2_block_addname( xfs_da_args_t *args) /* directory op arguments */ { - xfs_dir2_data_free_t *bf; /* bestfree table in block */ - xfs_dir2_block_t *block; /* directory block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ - xfs_dabuf_t *bp; /* buffer for block */ + struct xfs_buf *bp; /* buffer for block */ xfs_dir2_block_tail_t *btp; /* block tail */ int compact; /* need to compact leaf ents */ xfs_dir2_data_entry_t *dep; /* block data entry */ @@ -78,203 +345,74 @@ dp = args->dp; tp = args->trans; mp = dp->i_mount; - /* - * Read the (one and only) directory block into dabuf bp. - */ - if ((error = - xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) { + + /* Read the (one and only) directory block into bp. */ + error = xfs_dir3_block_read(tp, dp, &bp); + if (error) return error; - } - ASSERT(bp != NULL); - block = bp->data; - /* - * Check the magic number, corrupted if wrong. - */ - if (unlikely(be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC)) { - XFS_CORRUPTION_ERROR("xfs_dir2_block_addname", - XFS_ERRLEVEL_LOW, mp, block); - xfs_da_brelse(tp, bp); - return XFS_ERROR(EFSCORRUPTED); - } - len = xfs_dir2_data_entsize(args->namelen); + + len = xfs_dir3_data_entsize(mp, args->namelen); + /* * Set up pointers to parts of the block. */ - bf = block->hdr.bestfree; - btp = xfs_dir2_block_tail_p(mp, block); + hdr = bp->b_addr; + btp = xfs_dir2_block_tail_p(mp, hdr); blp = xfs_dir2_block_leaf_p(btp); + /* - * No stale entries? Need space for entry and new leaf. - */ - if (!btp->stale) { - /* - * Tag just before the first leaf entry. - */ - tagp = (__be16 *)blp - 1; - /* - * Data object just before the first leaf entry. - */ - enddup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); - /* - * If it's not free then can't do this add without cleaning up: - * the space before the first leaf entry needs to be free so it - * can be expanded to hold the pointer to the new entry. - */ - if (be16_to_cpu(enddup->freetag) != XFS_DIR2_DATA_FREE_TAG) - dup = enddup = NULL; - /* - * Check out the biggest freespace and see if it's the same one. - */ - else { - dup = (xfs_dir2_data_unused_t *) - ((char *)block + be16_to_cpu(bf[0].offset)); - if (dup == enddup) { - /* - * It is the biggest freespace, is it too small - * to hold the new leaf too? - */ - if (be16_to_cpu(dup->length) < len + (uint)sizeof(*blp)) { - /* - * Yes, we use the second-largest - * entry instead if it works. - */ - if (be16_to_cpu(bf[1].length) >= len) - dup = (xfs_dir2_data_unused_t *) - ((char *)block + - be16_to_cpu(bf[1].offset)); - else - dup = NULL; - } - } else { - /* - * Not the same free entry, - * just check its length. - */ - if (be16_to_cpu(dup->length) < len) { - dup = NULL; - } - } - } - compact = 0; - } - /* - * If there are stale entries we'll use one for the leaf. - * Is the biggest entry enough to avoid compaction? + * Find out if we can reuse stale entries or whether we need extra + * space for entry and new leaf. */ - else if (be16_to_cpu(bf[0].length) >= len) { - dup = (xfs_dir2_data_unused_t *) - ((char *)block + be16_to_cpu(bf[0].offset)); - compact = 0; - } + xfs_dir2_block_need_space(hdr, btp, blp, &tagp, &dup, + &enddup, &compact, len); + /* - * Will need to compact to make this work. + * Done everything we need for a space check now. */ - else { - /* - * Tag just before the first leaf entry. - */ - tagp = (__be16 *)blp - 1; - /* - * Data object just before the first leaf entry. - */ - dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); - /* - * If it's not free then the data will go where the - * leaf data starts now, if it works at all. - */ - if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { - if (be16_to_cpu(dup->length) + (be32_to_cpu(btp->stale) - 1) * - (uint)sizeof(*blp) < len) - dup = NULL; - } else if ((be32_to_cpu(btp->stale) - 1) * (uint)sizeof(*blp) < len) - dup = NULL; - else - dup = (xfs_dir2_data_unused_t *)blp; - compact = 1; + if (args->op_flags & XFS_DA_OP_JUSTCHECK) { + xfs_trans_brelse(tp, bp); + if (!dup) + return XFS_ERROR(ENOSPC); + return 0; } - /* - * If this isn't a real add, we're done with the buffer. - */ - if (args->op_flags & XFS_DA_OP_JUSTCHECK) - xfs_da_brelse(tp, bp); + /* * If we don't have space for the new entry & leaf ... */ if (!dup) { - /* - * Not trying to actually do anything, or don't have - * a space reservation: return no-space. - */ - if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || args->total == 0) + /* Don't have a space reservation: return no-space. */ + if (args->total == 0) return XFS_ERROR(ENOSPC); /* * Convert to the next larger format. * Then add the new entry in that format. */ error = xfs_dir2_block_to_leaf(args, bp); - xfs_da_buf_done(bp); if (error) return error; return xfs_dir2_leaf_addname(args); } - /* - * Just checking, and it would work, so say so. - */ - if (args->op_flags & XFS_DA_OP_JUSTCHECK) - return 0; + needlog = needscan = 0; + /* * If need to compact the leaf entries, do it now. - * Leave the highest-numbered stale entry stale. - * XXX should be the one closest to mid but mid is not yet computed. */ if (compact) { - int fromidx; /* source leaf index */ - int toidx; /* target leaf index */ - - for (fromidx = toidx = be32_to_cpu(btp->count) - 1, - highstale = lfloghigh = -1; - fromidx >= 0; - fromidx--) { - if (be32_to_cpu(blp[fromidx].address) == XFS_DIR2_NULL_DATAPTR) { - if (highstale == -1) - highstale = toidx; - else { - if (lfloghigh == -1) - lfloghigh = toidx; - continue; - } - } - if (fromidx < toidx) - blp[toidx] = blp[fromidx]; - toidx--; - } - lfloglow = toidx + 1 - (be32_to_cpu(btp->stale) - 1); - lfloghigh -= be32_to_cpu(btp->stale) - 1; - be32_add_cpu(&btp->count, -(be32_to_cpu(btp->stale) - 1)); - xfs_dir2_data_make_free(tp, bp, - (xfs_dir2_data_aoff_t)((char *)blp - (char *)block), - (xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)), - &needlog, &needscan); - blp += be32_to_cpu(btp->stale) - 1; - btp->stale = cpu_to_be32(1); + xfs_dir2_block_compact(tp, bp, hdr, btp, blp, &needlog, + &lfloghigh, &lfloglow); + /* recalculate blp post-compaction */ + blp = xfs_dir2_block_leaf_p(btp); + } else if (btp->stale) { /* - * If we now need to rebuild the bestfree map, do so. - * This needs to happen before the next call to use_free. + * Set leaf logging boundaries to impossible state. + * For the no-stale case they're set explicitly. */ - if (needscan) { - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); - needscan = 0; - } - } - /* - * Set leaf logging boundaries to impossible state. - * For the no-stale case they're set explicitly. - */ - else if (btp->stale) { lfloglow = be32_to_cpu(btp->count); lfloghigh = -1; } + /* * Find the slot that's first lower than our hash value, -1 if none. */ @@ -299,7 +437,7 @@ */ xfs_dir2_data_use_free(tp, bp, enddup, (xfs_dir2_data_aoff_t) - ((char *)enddup - (char *)block + be16_to_cpu(enddup->length) - + ((char *)enddup - (char *)hdr + be16_to_cpu(enddup->length) - sizeof(*blp)), (xfs_dir2_data_aoff_t)sizeof(*blp), &needlog, &needscan); @@ -312,8 +450,7 @@ * This needs to happen before the next call to use_free. */ if (needscan) { - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, - &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); needscan = 0; } /* @@ -334,12 +471,14 @@ else { for (lowstale = mid; lowstale >= 0 && - be32_to_cpu(blp[lowstale].address) != XFS_DIR2_NULL_DATAPTR; + blp[lowstale].address != + cpu_to_be32(XFS_DIR2_NULL_DATAPTR); lowstale--) continue; for (highstale = mid + 1; highstale < be32_to_cpu(btp->count) && - be32_to_cpu(blp[highstale].address) != XFS_DIR2_NULL_DATAPTR && + blp[highstale].address != + cpu_to_be32(XFS_DIR2_NULL_DATAPTR) && (lowstale < 0 || mid - lowstale > highstale - mid); highstale++) continue; @@ -378,13 +517,13 @@ */ blp[mid].hashval = cpu_to_be32(args->hashval); blp[mid].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, - (char *)dep - (char *)block)); + (char *)dep - (char *)hdr)); xfs_dir2_block_log_leaf(tp, bp, lfloglow, lfloghigh); /* * Mark space for the data entry used. */ xfs_dir2_data_use_free(tp, bp, dup, - (xfs_dir2_data_aoff_t)((char *)dup - (char *)block), + (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), (xfs_dir2_data_aoff_t)len, &needlog, &needscan); /* * Create the new data entry. @@ -392,19 +531,19 @@ dep->inumber = cpu_to_be64(args->inumber); dep->namelen = args->namelen; memcpy(dep->name, args->name, args->namelen); - tagp = xfs_dir2_data_entry_tag_p(dep); - *tagp = cpu_to_be16((char *)dep - (char *)block); + xfs_dir3_dirent_put_ftype(mp, dep, args->filetype); + tagp = xfs_dir3_data_entry_tag_p(mp, dep); + *tagp = cpu_to_be16((char *)dep - (char *)hdr); /* * Clean up the bestfree array and log the header, tail, and entry. */ if (needscan) - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); if (needlog) xfs_dir2_data_log_header(tp, bp); xfs_dir2_block_log_tail(tp, bp); xfs_dir2_data_log_entry(tp, bp, dep); - xfs_dir2_data_check(dp, bp); - xfs_da_buf_done(bp); + xfs_dir3_data_check(dp, bp); return 0; } @@ -414,21 +553,18 @@ static void xfs_dir2_block_log_leaf( xfs_trans_t *tp, /* transaction structure */ - xfs_dabuf_t *bp, /* block buffer */ + struct xfs_buf *bp, /* block buffer */ int first, /* index of first logged leaf */ int last) /* index of last logged leaf */ { - xfs_dir2_block_t *block; /* directory block structure */ - xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ - xfs_dir2_block_tail_t *btp; /* block tail */ - xfs_mount_t *mp; /* filesystem mount point */ + xfs_dir2_data_hdr_t *hdr = bp->b_addr; + xfs_dir2_leaf_entry_t *blp; + xfs_dir2_block_tail_t *btp; - mp = tp->t_mountp; - block = bp->data; - btp = xfs_dir2_block_tail_p(mp, block); + btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr); blp = xfs_dir2_block_leaf_p(btp); - xfs_da_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)block), - (uint)((char *)&blp[last + 1] - (char *)block - 1)); + xfs_trans_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)hdr), + (uint)((char *)&blp[last + 1] - (char *)hdr - 1)); } /* @@ -437,17 +573,14 @@ static void xfs_dir2_block_log_tail( xfs_trans_t *tp, /* transaction structure */ - xfs_dabuf_t *bp) /* block buffer */ + struct xfs_buf *bp) /* block buffer */ { - xfs_dir2_block_t *block; /* directory block structure */ - xfs_dir2_block_tail_t *btp; /* block tail */ - xfs_mount_t *mp; /* filesystem mount point */ + xfs_dir2_data_hdr_t *hdr = bp->b_addr; + xfs_dir2_block_tail_t *btp; - mp = tp->t_mountp; - block = bp->data; - btp = xfs_dir2_block_tail_p(mp, block); - xfs_da_log_buf(tp, bp, (uint)((char *)btp - (char *)block), - (uint)((char *)(btp + 1) - (char *)block - 1)); + btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr); + xfs_trans_log_buf(tp, bp, (uint)((char *)btp - (char *)hdr), + (uint)((char *)(btp + 1) - (char *)hdr - 1)); } /* @@ -458,9 +591,9 @@ xfs_dir2_block_lookup( xfs_da_args_t *args) /* dir lookup arguments */ { - xfs_dir2_block_t *block; /* block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ - xfs_dabuf_t *bp; /* block buffer */ + struct xfs_buf *bp; /* block buffer */ xfs_dir2_block_tail_t *btp; /* block tail */ xfs_dir2_data_entry_t *dep; /* block data entry */ xfs_inode_t *dp; /* incore inode */ @@ -478,21 +611,22 @@ return error; dp = args->dp; mp = dp->i_mount; - block = bp->data; - xfs_dir2_data_check(dp, bp); - btp = xfs_dir2_block_tail_p(mp, block); + hdr = bp->b_addr; + xfs_dir3_data_check(dp, bp); + btp = xfs_dir2_block_tail_p(mp, hdr); blp = xfs_dir2_block_leaf_p(btp); /* * Get the offset from the leaf entry, to point to the data. */ - dep = (xfs_dir2_data_entry_t *)((char *)block + + dep = (xfs_dir2_data_entry_t *)((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); /* * Fill in inode number, CI name if appropriate, release the block. */ args->inumber = be64_to_cpu(dep->inumber); + args->filetype = xfs_dir3_dirent_get_ftype(mp, dep); error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); - xfs_da_brelse(args->trans, bp); + xfs_trans_brelse(args->trans, bp); return XFS_ERROR(error); } @@ -502,13 +636,13 @@ static int /* error */ xfs_dir2_block_lookup_int( xfs_da_args_t *args, /* dir lookup arguments */ - xfs_dabuf_t **bpp, /* returned block buffer */ + struct xfs_buf **bpp, /* returned block buffer */ int *entno) /* returned entry number */ { xfs_dir2_dataptr_t addr; /* data entry address */ - xfs_dir2_block_t *block; /* block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ - xfs_dabuf_t *bp; /* block buffer */ + struct xfs_buf *bp; /* block buffer */ xfs_dir2_block_tail_t *btp; /* block tail */ xfs_dir2_data_entry_t *dep; /* block data entry */ xfs_inode_t *dp; /* incore inode */ @@ -524,17 +658,14 @@ dp = args->dp; tp = args->trans; mp = dp->i_mount; - /* - * Read the buffer, return error if we can't get it. - */ - if ((error = - xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) { + + error = xfs_dir3_block_read(tp, dp, &bp); + if (error) return error; - } - ASSERT(bp != NULL); - block = bp->data; - xfs_dir2_data_check(dp, bp); - btp = xfs_dir2_block_tail_p(mp, block); + + hdr = bp->b_addr; + xfs_dir3_data_check(dp, bp); + btp = xfs_dir2_block_tail_p(mp, hdr); blp = xfs_dir2_block_leaf_p(btp); /* * Loop doing a binary search for our hash value. @@ -551,7 +682,7 @@ high = mid - 1; if (low > high) { ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); - xfs_da_brelse(tp, bp); + xfs_trans_brelse(tp, bp); return XFS_ERROR(ENOENT); } } @@ -572,7 +703,7 @@ * Get pointer to the entry from the leaf. */ dep = (xfs_dir2_data_entry_t *) - ((char *)block + xfs_dir2_dataptr_to_off(mp, addr)); + ((char *)hdr + xfs_dir2_dataptr_to_off(mp, addr)); /* * Compare name and if it's an exact match, return the index * and buffer. If it's the first case-insensitive match, store @@ -599,7 +730,7 @@ /* * No match, release the buffer and return ENOENT. */ - xfs_da_brelse(tp, bp); + xfs_trans_brelse(tp, bp); return XFS_ERROR(ENOENT); } @@ -611,9 +742,9 @@ xfs_dir2_block_removename( xfs_da_args_t *args) /* directory operation args */ { - xfs_dir2_block_t *block; /* block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_leaf_entry_t *blp; /* block leaf pointer */ - xfs_dabuf_t *bp; /* block buffer */ + struct xfs_buf *bp; /* block buffer */ xfs_dir2_block_tail_t *btp; /* block tail */ xfs_dir2_data_entry_t *dep; /* block data entry */ xfs_inode_t *dp; /* incore inode */ @@ -638,21 +769,21 @@ dp = args->dp; tp = args->trans; mp = dp->i_mount; - block = bp->data; - btp = xfs_dir2_block_tail_p(mp, block); + hdr = bp->b_addr; + btp = xfs_dir2_block_tail_p(mp, hdr); blp = xfs_dir2_block_leaf_p(btp); /* * Point to the data entry using the leaf entry. */ dep = (xfs_dir2_data_entry_t *) - ((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); + ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); /* * Mark the data entry's space free. */ needlog = needscan = 0; xfs_dir2_data_make_free(tp, bp, - (xfs_dir2_data_aoff_t)((char *)dep - (char *)block), - xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); + (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr), + xfs_dir3_data_entsize(mp, dep->namelen), &needlog, &needscan); /* * Fix up the block tail. */ @@ -667,18 +798,17 @@ * Fix up bestfree, log the header if necessary. */ if (needscan) - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); if (needlog) xfs_dir2_data_log_header(tp, bp); - xfs_dir2_data_check(dp, bp); + xfs_dir3_data_check(dp, bp); /* * See if the size as a shortform is good enough. */ - if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) > - XFS_IFORK_DSIZE(dp)) { - xfs_da_buf_done(bp); + size = xfs_dir2_block_sfsize(dp, hdr, &sfh); + if (size > XFS_IFORK_DSIZE(dp)) return 0; - } + /* * If it works, do the conversion. */ @@ -693,9 +823,9 @@ xfs_dir2_block_replace( xfs_da_args_t *args) /* directory operation args */ { - xfs_dir2_block_t *block; /* block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ - xfs_dabuf_t *bp; /* block buffer */ + struct xfs_buf *bp; /* block buffer */ xfs_dir2_block_tail_t *btp; /* block tail */ xfs_dir2_data_entry_t *dep; /* block data entry */ xfs_inode_t *dp; /* incore inode */ @@ -714,22 +844,22 @@ } dp = args->dp; mp = dp->i_mount; - block = bp->data; - btp = xfs_dir2_block_tail_p(mp, block); + hdr = bp->b_addr; + btp = xfs_dir2_block_tail_p(mp, hdr); blp = xfs_dir2_block_leaf_p(btp); /* * Point to the data entry we need to change. */ dep = (xfs_dir2_data_entry_t *) - ((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); + ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); ASSERT(be64_to_cpu(dep->inumber) != args->inumber); /* * Change the inode number to the new value. */ dep->inumber = cpu_to_be64(args->inumber); + xfs_dir3_dirent_put_ftype(mp, dep, args->filetype); xfs_dir2_data_log_entry(args->trans, bp, dep); - xfs_dir2_data_check(dp, bp); - xfs_da_buf_done(bp); + xfs_dir3_data_check(dp, bp); return 0; } @@ -756,11 +886,11 @@ int /* error */ xfs_dir2_leaf_to_block( xfs_da_args_t *args, /* operation arguments */ - xfs_dabuf_t *lbp, /* leaf buffer */ - xfs_dabuf_t *dbp) /* data buffer */ + struct xfs_buf *lbp, /* leaf buffer */ + struct xfs_buf *dbp) /* data buffer */ { __be16 *bestsp; /* leaf bests table */ - xfs_dir2_block_t *block; /* block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_block_tail_t *btp; /* block tail */ xfs_inode_t *dp; /* incore directory inode */ xfs_dir2_data_unused_t *dup; /* unused data entry */ @@ -777,15 +907,21 @@ __be16 *tagp; /* end of entry (tag) */ int to; /* block/leaf to index */ xfs_trans_t *tp; /* transaction pointer */ + struct xfs_dir2_leaf_entry *ents; + struct xfs_dir3_icleaf_hdr leafhdr; trace_xfs_dir2_leaf_to_block(args); dp = args->dp; tp = args->trans; mp = dp->i_mount; - leaf = lbp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); + leaf = lbp->b_addr; + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + ents = xfs_dir3_leaf_ents_p(leaf); ltp = xfs_dir2_leaf_tail_p(mp, leaf); + + ASSERT(leafhdr.magic == XFS_DIR2_LEAF1_MAGIC || + leafhdr.magic == XFS_DIR3_LEAF1_MAGIC); /* * If there are data blocks other than the first one, take this * opportunity to remove trailing empty data blocks that may have @@ -793,50 +929,53 @@ * These will show up in the leaf bests table. */ while (dp->i_d.di_size > mp->m_dirblksize) { + int hdrsz; + + hdrsz = xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&mp->m_sb)); bestsp = xfs_dir2_leaf_bests_p(ltp); if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) == - mp->m_dirblksize - (uint)sizeof(block->hdr)) { + mp->m_dirblksize - hdrsz) { if ((error = xfs_dir2_leaf_trim_data(args, lbp, (xfs_dir2_db_t)(be32_to_cpu(ltp->bestcount) - 1)))) - goto out; - } else { - error = 0; - goto out; - } + return error; + } else + return 0; } /* * Read the data block if we don't already have it, give up if it fails. */ - if (dbp == NULL && - (error = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &dbp, - XFS_DATA_FORK))) { - goto out; + if (!dbp) { + error = xfs_dir3_data_read(tp, dp, mp->m_dirdatablk, -1, &dbp); + if (error) + return error; } - block = dbp->data; - ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_DATA_MAGIC); + hdr = dbp->b_addr; + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)); + /* * Size of the "leaf" area in the block. */ - size = (uint)sizeof(block->tail) + - (uint)sizeof(*lep) * (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); + size = (uint)sizeof(xfs_dir2_block_tail_t) + + (uint)sizeof(*lep) * (leafhdr.count - leafhdr.stale); /* * Look at the last data entry. */ - tagp = (__be16 *)((char *)block + mp->m_dirblksize) - 1; - dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); + tagp = (__be16 *)((char *)hdr + mp->m_dirblksize) - 1; + dup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp)); /* * If it's not free or is too short we can't do it. */ if (be16_to_cpu(dup->freetag) != XFS_DIR2_DATA_FREE_TAG || - be16_to_cpu(dup->length) < size) { - error = 0; - goto out; - } + be16_to_cpu(dup->length) < size) + return 0; + /* * Start converting it to block form. */ - block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); + xfs_dir3_block_init(mp, tp, dbp, dp); + needlog = 1; needscan = 0; /* @@ -847,18 +986,18 @@ /* * Initialize the block tail. */ - btp = xfs_dir2_block_tail_p(mp, block); - btp->count = cpu_to_be32(be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); + btp = xfs_dir2_block_tail_p(mp, hdr); + btp->count = cpu_to_be32(leafhdr.count - leafhdr.stale); btp->stale = 0; xfs_dir2_block_log_tail(tp, dbp); /* * Initialize the block leaf area. We compact out stale entries. */ lep = xfs_dir2_block_leaf_p(btp); - for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) { - if (be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) + for (from = to = 0; from < leafhdr.count; from++) { + if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) continue; - lep[to++] = leaf->ents[from]; + lep[to++] = ents[from]; } ASSERT(to == be32_to_cpu(btp->count)); xfs_dir2_block_log_leaf(tp, dbp, 0, be32_to_cpu(btp->count) - 1); @@ -866,32 +1005,24 @@ * Scan the bestfree if we need it and log the data block header. */ if (needscan) - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); if (needlog) xfs_dir2_data_log_header(tp, dbp); /* * Pitch the old leaf block. */ error = xfs_da_shrink_inode(args, mp->m_dirleafblk, lbp); - lbp = NULL; - if (error) { - goto out; - } + if (error) + return error; + /* * Now see if the resulting block can be shrunken to shortform. */ - if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) > - XFS_IFORK_DSIZE(dp)) { - error = 0; - goto out; - } + size = xfs_dir2_block_sfsize(dp, hdr, &sfh); + if (size > XFS_IFORK_DSIZE(dp)) + return 0; + return xfs_dir2_block_to_sf(args, dbp, size, &sfh); -out: - if (lbp) - xfs_da_buf_done(lbp); - if (dbp) - xfs_da_buf_done(dbp); - return error; } /* @@ -902,12 +1033,10 @@ xfs_da_args_t *args) /* operation arguments */ { xfs_dir2_db_t blkno; /* dir-relative block # (0) */ - xfs_dir2_block_t *block; /* block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ - xfs_dabuf_t *bp; /* block buffer */ + struct xfs_buf *bp; /* block buffer */ xfs_dir2_block_tail_t *btp; /* block tail pointer */ - char *buf; /* sf buffer */ - int buf_len; xfs_dir2_data_entry_t *dep; /* data entry pointer */ xfs_inode_t *dp; /* incore directory inode */ int dummy; /* trash */ @@ -921,17 +1050,20 @@ int newoffset; /* offset from current entry */ int offset; /* target block offset */ xfs_dir2_sf_entry_t *sfep; /* sf entry pointer */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *oldsfp; /* old shortform header */ + xfs_dir2_sf_hdr_t *sfp; /* shortform header */ __be16 *tagp; /* end of data entry */ xfs_trans_t *tp; /* transaction pointer */ struct xfs_name name; + struct xfs_ifork *ifp; trace_xfs_dir2_sf_to_block(args); dp = args->dp; tp = args->trans; mp = dp->i_mount; - ASSERT(dp->i_df.if_flags & XFS_IFINLINE); + ifp = XFS_IFORK_PTR(dp, XFS_DATA_FORK); + ASSERT(ifp->if_flags & XFS_IFINLINE); /* * Bomb out if the shortform directory is way too short. */ @@ -939,54 +1071,54 @@ ASSERT(XFS_FORCED_SHUTDOWN(mp)); return XFS_ERROR(EIO); } - ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); - ASSERT(dp->i_df.if_u1.if_data != NULL); - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); + + oldsfp = (xfs_dir2_sf_hdr_t *)ifp->if_u1.if_data; + + ASSERT(ifp->if_bytes == dp->i_d.di_size); + ASSERT(ifp->if_u1.if_data != NULL); + ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(oldsfp->i8count)); + ASSERT(dp->i_d.di_nextents == 0); + /* - * Copy the directory into the stack buffer. + * Copy the directory into a temporary buffer. * Then pitch the incore inode data so we can make extents. */ + sfp = kmem_alloc(ifp->if_bytes, KM_SLEEP); + memcpy(sfp, oldsfp, ifp->if_bytes); - buf_len = dp->i_df.if_bytes; - buf = kmem_alloc(buf_len, KM_SLEEP); - - memcpy(buf, sfp, buf_len); - xfs_idata_realloc(dp, -buf_len, XFS_DATA_FORK); + xfs_idata_realloc(dp, -ifp->if_bytes, XFS_DATA_FORK); + xfs_bmap_local_to_extents_empty(dp, XFS_DATA_FORK); dp->i_d.di_size = 0; - xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); - /* - * Reset pointer - old sfp is gone. - */ - sfp = (xfs_dir2_sf_t *)buf; + /* * Add block 0 to the inode. */ error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, &blkno); if (error) { - kmem_free(buf); + kmem_free(sfp); return error; } /* - * Initialize the data block. + * Initialize the data block, then convert it to block format. */ - error = xfs_dir2_data_init(args, blkno, &bp); + error = xfs_dir3_data_init(args, blkno, &bp); if (error) { - kmem_free(buf); + kmem_free(sfp); return error; } - block = bp->data; - block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); + xfs_dir3_block_init(mp, tp, bp, dp); + hdr = bp->b_addr; + /* * Compute size of block "tail" area. */ i = (uint)sizeof(*btp) + - (sfp->hdr.count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t); + (sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t); /* * The whole thing is initialized to free by the init routine. * Say we're using the leaf and tail area. */ - dup = (xfs_dir2_data_unused_t *)block->u; + dup = xfs_dir3_data_unused_p(hdr); needlog = needscan = 0; xfs_dir2_data_use_free(tp, bp, dup, mp->m_dirblksize - i, i, &needlog, &needscan); @@ -994,50 +1126,51 @@ /* * Fill in the tail. */ - btp = xfs_dir2_block_tail_p(mp, block); - btp->count = cpu_to_be32(sfp->hdr.count + 2); /* ., .. */ + btp = xfs_dir2_block_tail_p(mp, hdr); + btp->count = cpu_to_be32(sfp->count + 2); /* ., .. */ btp->stale = 0; blp = xfs_dir2_block_leaf_p(btp); - endoffset = (uint)((char *)blp - (char *)block); + endoffset = (uint)((char *)blp - (char *)hdr); /* * Remove the freespace, we'll manage it. */ xfs_dir2_data_use_free(tp, bp, dup, - (xfs_dir2_data_aoff_t)((char *)dup - (char *)block), + (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), be16_to_cpu(dup->length), &needlog, &needscan); /* * Create entry for . */ - dep = (xfs_dir2_data_entry_t *) - ((char *)block + XFS_DIR2_DATA_DOT_OFFSET); + dep = xfs_dir3_data_dot_entry_p(mp, hdr); dep->inumber = cpu_to_be64(dp->i_ino); dep->namelen = 1; dep->name[0] = '.'; - tagp = xfs_dir2_data_entry_tag_p(dep); - *tagp = cpu_to_be16((char *)dep - (char *)block); + xfs_dir3_dirent_put_ftype(mp, dep, XFS_DIR3_FT_DIR); + tagp = xfs_dir3_data_entry_tag_p(mp, dep); + *tagp = cpu_to_be16((char *)dep - (char *)hdr); xfs_dir2_data_log_entry(tp, bp, dep); blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot); blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, - (char *)dep - (char *)block)); + (char *)dep - (char *)hdr)); /* * Create entry for .. */ - dep = (xfs_dir2_data_entry_t *) - ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET); - dep->inumber = cpu_to_be64(xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent)); + dep = xfs_dir3_data_dotdot_entry_p(mp, hdr); + dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp)); dep->namelen = 2; dep->name[0] = dep->name[1] = '.'; - tagp = xfs_dir2_data_entry_tag_p(dep); - *tagp = cpu_to_be16((char *)dep - (char *)block); + xfs_dir3_dirent_put_ftype(mp, dep, XFS_DIR3_FT_DIR); + tagp = xfs_dir3_data_entry_tag_p(mp, dep); + *tagp = cpu_to_be16((char *)dep - (char *)hdr); xfs_dir2_data_log_entry(tp, bp, dep); blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, - (char *)dep - (char *)block)); - offset = XFS_DIR2_DATA_FIRST_OFFSET; + (char *)dep - (char *)hdr)); + offset = xfs_dir3_data_first_offset(mp); /* * Loop over existing entries, stuff them in. */ - if ((i = 0) == sfp->hdr.count) + i = 0; + if (!sfp->count) sfep = NULL; else sfep = xfs_dir2_sf_firstentry(sfp); @@ -1057,43 +1190,42 @@ * There should be a hole here, make one. */ if (offset < newoffset) { - dup = (xfs_dir2_data_unused_t *) - ((char *)block + offset); + dup = (xfs_dir2_data_unused_t *)((char *)hdr + offset); dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); dup->length = cpu_to_be16(newoffset - offset); *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16( - ((char *)dup - (char *)block)); + ((char *)dup - (char *)hdr)); xfs_dir2_data_log_unused(tp, bp, dup); - (void)xfs_dir2_data_freeinsert((xfs_dir2_data_t *)block, - dup, &dummy); + xfs_dir2_data_freeinsert(hdr, dup, &dummy); offset += be16_to_cpu(dup->length); continue; } /* * Copy a real entry. */ - dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset); - dep->inumber = cpu_to_be64(xfs_dir2_sf_get_inumber(sfp, - xfs_dir2_sf_inumberp(sfep))); + dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset); + dep->inumber = cpu_to_be64(xfs_dir3_sfe_get_ino(mp, sfp, sfep)); dep->namelen = sfep->namelen; + xfs_dir3_dirent_put_ftype(mp, dep, + xfs_dir3_sfe_get_ftype(mp, sfp, sfep)); memcpy(dep->name, sfep->name, dep->namelen); - tagp = xfs_dir2_data_entry_tag_p(dep); - *tagp = cpu_to_be16((char *)dep - (char *)block); + tagp = xfs_dir3_data_entry_tag_p(mp, dep); + *tagp = cpu_to_be16((char *)dep - (char *)hdr); xfs_dir2_data_log_entry(tp, bp, dep); name.name = sfep->name; name.len = sfep->namelen; blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops-> hashname(&name)); blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, - (char *)dep - (char *)block)); - offset = (int)((char *)(tagp + 1) - (char *)block); - if (++i == sfp->hdr.count) + (char *)dep - (char *)hdr)); + offset = (int)((char *)(tagp + 1) - (char *)hdr); + if (++i == sfp->count) sfep = NULL; else - sfep = xfs_dir2_sf_nextentry(sfp, sfep); + sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep); } /* Done with the temporary buffer */ - kmem_free(buf); + kmem_free(sfp); /* * Sort the leaf entries by hash value. */ @@ -1105,7 +1237,6 @@ ASSERT(needscan == 0); xfs_dir2_block_log_leaf(tp, bp, 0, be32_to_cpu(btp->count) - 1); xfs_dir2_block_log_tail(tp, bp); - xfs_dir2_data_check(dp, bp); - xfs_da_buf_done(bp); + xfs_dir3_data_check(dp, bp); return 0; } diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_dir2.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_dir2.c 2014-05-02 00:09:16.000000000 +0000 @@ -18,7 +18,24 @@ #include -struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2}; +struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2, XFS_DIR3_FT_DIR }; + +/* + * @mode, if set, indicates that the type field needs to be set up. + * This uses the transformation from file mode to DT_* as defined in linux/fs.h + * for file type specification. This will be propagated into the directory + * structure if appropriate for the given operation and filesystem config. + */ +const unsigned char xfs_mode_to_ftype[S_IFMT >> S_SHIFT] = { + [0] = XFS_DIR3_FT_UNKNOWN, + [S_IFREG >> S_SHIFT] = XFS_DIR3_FT_REG_FILE, + [S_IFDIR >> S_SHIFT] = XFS_DIR3_FT_DIR, + [S_IFCHR >> S_SHIFT] = XFS_DIR3_FT_CHRDEV, + [S_IFBLK >> S_SHIFT] = XFS_DIR3_FT_BLKDEV, + [S_IFIFO >> S_SHIFT] = XFS_DIR3_FT_FIFO, + [S_IFSOCK >> S_SHIFT] = XFS_DIR3_FT_SOCK, + [S_IFLNK >> S_SHIFT] = XFS_DIR3_FT_SYMLINK, +}; /* * ASCII case-insensitive (ie. A-Z) support for directories that was @@ -70,6 +87,9 @@ xfs_dir_mount( xfs_mount_t *mp) { + int nodehdr_size; + + ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb)); ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <= XFS_MAX_BLOCKSIZE); @@ -78,12 +98,13 @@ mp->m_dirdatablk = xfs_dir2_db_to_da(mp, XFS_DIR2_DATA_FIRSTDB(mp)); mp->m_dirleafblk = xfs_dir2_db_to_da(mp, XFS_DIR2_LEAF_FIRSTDB(mp)); mp->m_dirfreeblk = xfs_dir2_db_to_da(mp, XFS_DIR2_FREE_FIRSTDB(mp)); - mp->m_attr_node_ents = - (mp->m_sb.sb_blocksize - (uint)sizeof(xfs_da_node_hdr_t)) / - (uint)sizeof(xfs_da_node_entry_t); - mp->m_dir_node_ents = - (mp->m_dirblksize - (uint)sizeof(xfs_da_node_hdr_t)) / - (uint)sizeof(xfs_da_node_entry_t); + + nodehdr_size = __xfs_da3_node_hdr_size(xfs_sb_version_hascrc(&mp->m_sb)); + mp->m_attr_node_ents = (mp->m_sb.sb_blocksize - nodehdr_size) / + (uint)sizeof(xfs_da_node_entry_t); + mp->m_dir_node_ents = (mp->m_dirblksize - nodehdr_size) / + (uint)sizeof(xfs_da_node_entry_t); + mp->m_dir_magicpct = (mp->m_dirblksize * 37) / 100; if (xfs_sb_version_hasasciici(&mp->m_sb)) mp->m_dirnameops = &xfs_ascii_ci_nameops; @@ -98,15 +119,15 @@ xfs_dir_isempty( xfs_inode_t *dp) { - xfs_dir2_sf_t *sfp; + xfs_dir2_sf_hdr_t *sfp; - ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); + ASSERT(S_ISDIR(dp->i_d.di_mode)); if (dp->i_d.di_size == 0) /* might happen during shutdown. */ return 1; if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) return 0; - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - return !sfp->hdr.count; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + return !sfp->count; } /* @@ -135,7 +156,7 @@ XFS_AGINO_TO_INO(mp, agno, agino) == ino; if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE, XFS_RANDOM_DIR_INO_VALIDATE))) { - xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx", + xfs_warn(mp, "Invalid inode number 0x%Lx", (unsigned long long) ino); XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp); return XFS_ERROR(EFSCORRUPTED); @@ -158,7 +179,7 @@ memset((char *)&args, 0, sizeof(args)); args.dp = dp; args.trans = tp; - ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); + ASSERT(S_ISDIR(dp->i_d.di_mode)); if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino))) return error; return xfs_dir2_sf_create(&args, pdp->i_ino); @@ -181,7 +202,7 @@ int rval; int v; /* type-checking value */ - ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); + ASSERT(S_ISDIR(dp->i_d.di_mode)); if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) return rval; XFS_STATS_INC(xs_dir_create); @@ -189,6 +210,7 @@ memset(&args, 0, sizeof(xfs_da_args_t)); args.name = name->name; args.namelen = name->len; + args.filetype = name->type; args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = inum; args.dp = dp; @@ -257,12 +279,13 @@ int rval; int v; /* type-checking value */ - ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); + ASSERT(S_ISDIR(dp->i_d.di_mode)); XFS_STATS_INC(xs_dir_lookup); memset(&args, 0, sizeof(xfs_da_args_t)); args.name = name->name; args.namelen = name->len; + args.filetype = name->type; args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.dp = dp; args.whichfork = XFS_DATA_FORK; @@ -312,12 +335,13 @@ int rval; int v; /* type-checking value */ - ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); + ASSERT(S_ISDIR(dp->i_d.di_mode)); XFS_STATS_INC(xs_dir_remove); memset(&args, 0, sizeof(xfs_da_args_t)); args.name = name->name; args.namelen = name->len; + args.filetype = name->type; args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = ino; args.dp = dp; @@ -359,7 +383,7 @@ int rval; int v; /* type-checking value */ - ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); + ASSERT(S_ISDIR(dp->i_d.di_mode)); if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) return rval; @@ -367,6 +391,7 @@ memset(&args, 0, sizeof(xfs_da_args_t)); args.name = name->name; args.namelen = name->len; + args.filetype = name->type; args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = inum; args.dp = dp; @@ -392,134 +417,85 @@ } /* + * See if this entry can be added to the directory without allocating space. + * First checks that the caller couldn't reserve enough space (resblks = 0). + */ +int +xfs_dir_canenter( + xfs_trans_t *tp, + xfs_inode_t *dp, + struct xfs_name *name, /* name of entry to add */ + uint resblks) +{ + xfs_da_args_t args; + int rval; + int v; /* type-checking value */ + + if (resblks) + return 0; + + ASSERT(S_ISDIR(dp->i_d.di_mode)); + + memset(&args, 0, sizeof(xfs_da_args_t)); + args.name = name->name; + args.namelen = name->len; + args.filetype = name->type; + args.hashval = dp->i_mount->m_dirnameops->hashname(name); + args.dp = dp; + args.whichfork = XFS_DATA_FORK; + args.trans = tp; + args.op_flags = XFS_DA_OP_JUSTCHECK | XFS_DA_OP_ADDNAME | + XFS_DA_OP_OKNOENT; + + if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) + rval = xfs_dir2_sf_addname(&args); + else if ((rval = xfs_dir2_isblock(tp, dp, &v))) + return rval; + else if (v) + rval = xfs_dir2_block_addname(&args); + else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) + return rval; + else if (v) + rval = xfs_dir2_leaf_addname(&args); + else + rval = xfs_dir2_node_addname(&args); + return rval; +} + +/* * Utility routines. */ /* * Add a block to the directory. - * This routine is for data and free blocks, not leaf/node blocks - * which are handled by xfs_da_grow_inode. + * + * This routine is for data and free blocks, not leaf/node blocks which are + * handled by xfs_da_grow_inode. */ int xfs_dir2_grow_inode( - xfs_da_args_t *args, - int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */ - xfs_dir2_db_t *dbp) /* out: block number added */ -{ - xfs_fileoff_t bno; /* directory offset of new block */ - int count; /* count of filesystem blocks */ - xfs_inode_t *dp; /* incore directory inode */ - int error; - int got; /* blocks actually mapped */ - int i; - xfs_bmbt_irec_t map; /* single structure for bmap */ - int mapi; /* mapping index */ - xfs_bmbt_irec_t *mapp; /* bmap mapping structure(s) */ - xfs_mount_t *mp; - int nmap; /* number of bmap entries */ - xfs_trans_t *tp; - xfs_drfsbno_t nblks; + struct xfs_da_args *args, + int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */ + xfs_dir2_db_t *dbp) /* out: block number added */ +{ + struct xfs_inode *dp = args->dp; + struct xfs_mount *mp = dp->i_mount; + xfs_fileoff_t bno; /* directory offset of new block */ + int count; /* count of filesystem blocks */ + int error; trace_xfs_dir2_grow_inode(args, space); - dp = args->dp; - tp = args->trans; - mp = dp->i_mount; - nblks = dp->i_d.di_nblocks; /* * Set lowest possible block in the space requested. */ bno = XFS_B_TO_FSBT(mp, space * XFS_DIR2_SPACE_SIZE); count = mp->m_dirblkfsbs; - /* - * Find the first hole for our block. - */ - if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK))) - return error; - nmap = 1; - ASSERT(args->firstblock != NULL); - /* - * Try mapping the new block contiguously (one extent). - */ - if ((error = xfs_bmapi(tp, dp, bno, count, - XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG, - args->firstblock, args->total, &map, &nmap, - args->flist))) - return error; - ASSERT(nmap <= 1); - if (nmap == 1) { - mapp = ↦ - mapi = 1; - } - /* - * Didn't work and this is a multiple-fsb directory block. - * Try again with contiguous flag turned on. - */ - else if (nmap == 0 && count > 1) { - xfs_fileoff_t b; /* current file offset */ - - /* - * Space for maximum number of mappings. - */ - mapp = kmem_alloc(sizeof(*mapp) * count, KM_SLEEP); - /* - * Iterate until we get to the end of our block. - */ - for (b = bno, mapi = 0; b < bno + count; ) { - int c; /* current fsb count */ - /* - * Can't map more than MAX_NMAP at once. - */ - nmap = MIN(XFS_BMAP_MAX_NMAP, count); - c = (int)(bno + count - b); - if ((error = xfs_bmapi(tp, dp, b, c, - XFS_BMAPI_WRITE|XFS_BMAPI_METADATA, - args->firstblock, args->total, - &mapp[mapi], &nmap, args->flist))) { - kmem_free(mapp); - return error; - } - if (nmap < 1) - break; - /* - * Add this bunch into our table, go to the next offset. - */ - mapi += nmap; - b = mapp[mapi - 1].br_startoff + - mapp[mapi - 1].br_blockcount; - } - } - /* - * Didn't work. - */ - else { - mapi = 0; - mapp = NULL; - } - /* - * See how many fsb's we got. - */ - for (i = 0, got = 0; i < mapi; i++) - got += mapp[i].br_blockcount; - /* - * Didn't get enough fsb's, or the first/last block's are wrong. - */ - if (got != count || mapp[0].br_startoff != bno || - mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount != - bno + count) { - if (mapp != &map) - kmem_free(mapp); - return XFS_ERROR(ENOSPC); - } - /* - * Done with the temporary mapping table. - */ - if (mapp != &map) - kmem_free(mapp); + error = xfs_da_grow_inode_int(args, &bno, count); + if (error) + return error; - /* account for newly allocated blocks in reserved blocks total */ - args->total -= dp->i_d.di_nblocks - nblks; *dbp = xfs_dir2_da_to_db(mp, (xfs_dablk_t)bno); /* @@ -531,7 +507,7 @@ size = XFS_FSB_TO_B(mp, bno + count); if (size > dp->i_d.di_size) { dp->i_d.di_size = size; - xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); + xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE); } } return 0; @@ -588,7 +564,7 @@ xfs_dir2_shrink_inode( xfs_da_args_t *args, xfs_dir2_db_t db, - xfs_dabuf_t *bp) + struct xfs_buf *bp) { xfs_fileoff_t bno; /* directory file offset */ xfs_dablk_t da; /* directory file offset */ @@ -630,7 +606,7 @@ /* * Invalidate the buffer from the transaction. */ - xfs_da_binval(tp, bp); + xfs_trans_binval(tp, bp); /* * If it's not a data block, we're done. */ diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2_data.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_dir2_data.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2_data.c 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_dir2_data.c 2014-05-02 00:09:16.000000000 +0000 @@ -1,5 +1,6 @@ /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. + * Copyright (c) 2013 Red Hat, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -18,23 +19,21 @@ #include - -#ifdef DEBUG /* * Check the consistency of the data block. * The input can also be a block-format directory. - * Pop an assert if we find anything bad. + * Return 0 is the buffer is good, otherwise an error. */ -void -xfs_dir2_data_check( - xfs_inode_t *dp, /* incore inode pointer */ - xfs_dabuf_t *bp) /* data block's buffer */ +int +__xfs_dir3_data_check( + struct xfs_inode *dp, /* incore inode pointer */ + struct xfs_buf *bp) /* data block's buffer */ { xfs_dir2_dataptr_t addr; /* addr for leaf lookup */ xfs_dir2_data_free_t *bf; /* bestfree table */ xfs_dir2_block_tail_t *btp=NULL; /* block tail */ int count; /* count of entries found */ - xfs_dir2_data_t *d; /* data block pointer */ + xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_data_entry_t *dep; /* data entry */ xfs_dir2_data_free_t *dfp; /* bestfree entry */ xfs_dir2_data_unused_t *dup; /* unused entry */ @@ -49,36 +48,48 @@ int stale; /* count of stale leaves */ struct xfs_name name; - mp = dp->i_mount; - d = bp->data; - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); - bf = d->hdr.bestfree; - p = (char *)d->u; - if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { - btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); + mp = bp->b_target->bt_mount; + hdr = bp->b_addr; + bf = xfs_dir3_data_bestfree_p(hdr); + p = (char *)xfs_dir3_data_entry_p(hdr); + + switch (hdr->magic) { + case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC): + case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC): + btp = xfs_dir2_block_tail_p(mp, hdr); lep = xfs_dir2_block_leaf_p(btp); endp = (char *)lep; - } else - endp = (char *)d + mp->m_dirblksize; + break; + case cpu_to_be32(XFS_DIR3_DATA_MAGIC): + case cpu_to_be32(XFS_DIR2_DATA_MAGIC): + endp = (char *)hdr + mp->m_dirblksize; + break; + default: + XFS_ERROR_REPORT("Bad Magic", XFS_ERRLEVEL_LOW, mp); + return EFSCORRUPTED; + } + count = lastfree = freeseen = 0; /* * Account for zero bestfree entries. */ if (!bf[0].length) { - ASSERT(!bf[0].offset); + XFS_WANT_CORRUPTED_RETURN(!bf[0].offset); freeseen |= 1 << 0; } if (!bf[1].length) { - ASSERT(!bf[1].offset); + XFS_WANT_CORRUPTED_RETURN(!bf[1].offset); freeseen |= 1 << 1; } if (!bf[2].length) { - ASSERT(!bf[2].offset); + XFS_WANT_CORRUPTED_RETURN(!bf[2].offset); freeseen |= 1 << 2; } - ASSERT(be16_to_cpu(bf[0].length) >= be16_to_cpu(bf[1].length)); - ASSERT(be16_to_cpu(bf[1].length) >= be16_to_cpu(bf[2].length)); + + XFS_WANT_CORRUPTED_RETURN(be16_to_cpu(bf[0].length) >= + be16_to_cpu(bf[1].length)); + XFS_WANT_CORRUPTED_RETURN(be16_to_cpu(bf[1].length) >= + be16_to_cpu(bf[2].length)); /* * Loop over the data/unused entries. */ @@ -90,17 +101,20 @@ * doesn't need to be there. */ if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { - ASSERT(lastfree == 0); - ASSERT(be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) == - (char *)dup - (char *)d); - dfp = xfs_dir2_data_freefind(d, dup); + XFS_WANT_CORRUPTED_RETURN(lastfree == 0); + XFS_WANT_CORRUPTED_RETURN( + be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) == + (char *)dup - (char *)hdr); + dfp = xfs_dir2_data_freefind(hdr, dup); if (dfp) { i = (int)(dfp - bf); - ASSERT((freeseen & (1 << i)) == 0); + XFS_WANT_CORRUPTED_RETURN( + (freeseen & (1 << i)) == 0); freeseen |= 1 << i; } else { - ASSERT(be16_to_cpu(dup->length) <= - be16_to_cpu(bf[2].length)); + XFS_WANT_CORRUPTED_RETURN( + be16_to_cpu(dup->length) <= + be16_to_cpu(bf[2].length)); } p += be16_to_cpu(dup->length); lastfree = 1; @@ -113,16 +127,21 @@ * The linear search is crude but this is DEBUG code. */ dep = (xfs_dir2_data_entry_t *)p; - ASSERT(dep->namelen != 0); - ASSERT(xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)) == 0); - ASSERT(be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) == - (char *)dep - (char *)d); + XFS_WANT_CORRUPTED_RETURN(dep->namelen != 0); + XFS_WANT_CORRUPTED_RETURN( + !xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber))); + XFS_WANT_CORRUPTED_RETURN( + be16_to_cpu(*xfs_dir3_data_entry_tag_p(mp, dep)) == + (char *)dep - (char *)hdr); + XFS_WANT_CORRUPTED_RETURN( + xfs_dir3_dirent_get_ftype(mp, dep) < XFS_DIR3_FT_MAX); count++; lastfree = 0; - if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { + if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { addr = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, (xfs_dir2_data_aoff_t) - ((char *)dep - (char *)d)); + ((char *)dep - (char *)hdr)); name.name = dep->name; name.len = dep->namelen; hash = mp->m_dirnameops->hashname(&name); @@ -131,26 +150,160 @@ be32_to_cpu(lep[i].hashval) == hash) break; } - ASSERT(i < be32_to_cpu(btp->count)); + XFS_WANT_CORRUPTED_RETURN(i < be32_to_cpu(btp->count)); } - p += xfs_dir2_data_entsize(dep->namelen); + p += xfs_dir3_data_entsize(mp, dep->namelen); } /* * Need to have seen all the entries and all the bestfree slots. */ - ASSERT(freeseen == 7); - if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { + XFS_WANT_CORRUPTED_RETURN(freeseen == 7); + if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { for (i = stale = 0; i < be32_to_cpu(btp->count); i++) { - if (be32_to_cpu(lep[i].address) == XFS_DIR2_NULL_DATAPTR) + if (lep[i].address == + cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) stale++; if (i > 0) - ASSERT(be32_to_cpu(lep[i].hashval) >= be32_to_cpu(lep[i - 1].hashval)); - } - ASSERT(count == be32_to_cpu(btp->count) - be32_to_cpu(btp->stale)); - ASSERT(stale == be32_to_cpu(btp->stale)); + XFS_WANT_CORRUPTED_RETURN( + be32_to_cpu(lep[i].hashval) >= + be32_to_cpu(lep[i - 1].hashval)); + } + XFS_WANT_CORRUPTED_RETURN(count == + be32_to_cpu(btp->count) - be32_to_cpu(btp->stale)); + XFS_WANT_CORRUPTED_RETURN(stale == be32_to_cpu(btp->stale)); } + return 0; +} + +static bool +xfs_dir3_data_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + if (hdr3->magic != cpu_to_be32(XFS_DIR3_DATA_MAGIC)) + return false; + if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_uuid)) + return false; + if (be64_to_cpu(hdr3->blkno) != bp->b_bn) + return false; + } else { + if (hdr3->magic != cpu_to_be32(XFS_DIR2_DATA_MAGIC)) + return false; + } + if (__xfs_dir3_data_check(NULL, bp)) + return false; + return true; +} + +/* + * Readahead of the first block of the directory when it is opened is completely + * oblivious to the format of the directory. Hence we can either get a block + * format buffer or a data format buffer on readahead. + */ +static void +xfs_dir3_data_reada_verify( + struct xfs_buf *bp) +{ + struct xfs_dir2_data_hdr *hdr = bp->b_addr; + + switch (hdr->magic) { + case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC): + case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC): + bp->b_ops = &xfs_dir3_block_buf_ops; + bp->b_ops->verify_read(bp); + return; + case cpu_to_be32(XFS_DIR2_DATA_MAGIC): + case cpu_to_be32(XFS_DIR3_DATA_MAGIC): + xfs_dir3_data_verify(bp); + return; + default: + xfs_buf_ioerror(bp, EFSCORRUPTED); + xfs_verifier_error(bp); + break; + } +} + +static void +xfs_dir3_data_read_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + + if (xfs_sb_version_hascrc(&mp->m_sb) && + !xfs_buf_verify_cksum(bp, XFS_DIR3_DATA_CRC_OFF)) + xfs_buf_ioerror(bp, EFSBADCRC); + else if (!xfs_dir3_data_verify(bp)) + xfs_buf_ioerror(bp, EFSCORRUPTED); + + if (bp->b_error) + xfs_verifier_error(bp); +} + +static void +xfs_dir3_data_write_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; + + if (!xfs_dir3_data_verify(bp)) { + xfs_buf_ioerror(bp, EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return; + + if (bip) + hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn); + + xfs_buf_update_cksum(bp, XFS_DIR3_DATA_CRC_OFF); +} + +const struct xfs_buf_ops xfs_dir3_data_buf_ops = { + .verify_read = xfs_dir3_data_read_verify, + .verify_write = xfs_dir3_data_write_verify, +}; + +static const struct xfs_buf_ops xfs_dir3_data_reada_buf_ops = { + .verify_read = xfs_dir3_data_reada_verify, + .verify_write = xfs_dir3_data_write_verify, +}; + + +int +xfs_dir3_data_read( + struct xfs_trans *tp, + struct xfs_inode *dp, + xfs_dablk_t bno, + xfs_daddr_t mapped_bno, + struct xfs_buf **bpp) +{ + int err; + + err = xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp, + XFS_DATA_FORK, &xfs_dir3_data_buf_ops); + if (!err && tp) + xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_DATA_BUF); + return err; +} + +int +xfs_dir3_data_readahead( + struct xfs_trans *tp, + struct xfs_inode *dp, + xfs_dablk_t bno, + xfs_daddr_t mapped_bno) +{ + return xfs_da_reada_buf(tp, dp, bno, mapped_bno, + XFS_DATA_FORK, &xfs_dir3_data_reada_buf_ops); } -#endif /* * Given a data block and an unused entry from that block, @@ -158,27 +311,32 @@ */ xfs_dir2_data_free_t * xfs_dir2_data_freefind( - xfs_dir2_data_t *d, /* data block */ + xfs_dir2_data_hdr_t *hdr, /* data block */ xfs_dir2_data_unused_t *dup) /* data unused entry */ { xfs_dir2_data_free_t *dfp; /* bestfree entry */ xfs_dir2_data_aoff_t off; /* offset value needed */ -#if defined(DEBUG) && defined(__KERNEL__) + struct xfs_dir2_data_free *bf; +#ifdef DEBUG int matched; /* matched the value */ int seenzero; /* saw a 0 bestfree entry */ #endif - off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)d); -#if defined(DEBUG) && defined(__KERNEL__) + off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr); + bf = xfs_dir3_data_bestfree_p(hdr); + +#ifdef DEBUG /* * Validate some consistency in the bestfree table. * Check order, non-overlapping entries, and if we find the * one we're looking for it has to be exact. */ - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); - for (dfp = &d->hdr.bestfree[0], seenzero = matched = 0; - dfp < &d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT]; + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); + for (dfp = &bf[0], seenzero = matched = 0; + dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) { if (!dfp->offset) { ASSERT(!dfp->length); @@ -194,7 +352,7 @@ else ASSERT(be16_to_cpu(dfp->offset) + be16_to_cpu(dfp->length) <= off); ASSERT(matched || be16_to_cpu(dfp->length) >= be16_to_cpu(dup->length)); - if (dfp > &d->hdr.bestfree[0]) + if (dfp > &bf[0]) ASSERT(be16_to_cpu(dfp[-1].length) >= be16_to_cpu(dfp[0].length)); } #endif @@ -203,14 +361,12 @@ * it can't be there since they're sorted. */ if (be16_to_cpu(dup->length) < - be16_to_cpu(d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length)) + be16_to_cpu(bf[XFS_DIR2_DATA_FD_COUNT - 1].length)) return NULL; /* * Look at the three bestfree entries for our guy. */ - for (dfp = &d->hdr.bestfree[0]; - dfp < &d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT]; - dfp++) { + for (dfp = &bf[0]; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) { if (!dfp->offset) return NULL; if (be16_to_cpu(dfp->offset) == off) @@ -227,20 +383,22 @@ */ xfs_dir2_data_free_t * /* entry inserted */ xfs_dir2_data_freeinsert( - xfs_dir2_data_t *d, /* data block pointer */ + xfs_dir2_data_hdr_t *hdr, /* data block pointer */ xfs_dir2_data_unused_t *dup, /* unused space */ int *loghead) /* log the data header (out) */ { xfs_dir2_data_free_t *dfp; /* bestfree table pointer */ xfs_dir2_data_free_t new; /* new bestfree entry */ -#ifdef __KERNEL__ - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); -#endif - dfp = d->hdr.bestfree; + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); + + dfp = xfs_dir3_data_bestfree_p(hdr); new.length = dup->length; - new.offset = cpu_to_be16((char *)dup - (char *)d); + new.offset = cpu_to_be16((char *)dup - (char *)hdr); + /* * Insert at position 0, 1, or 2; or not at all. */ @@ -270,36 +428,40 @@ */ STATIC void xfs_dir2_data_freeremove( - xfs_dir2_data_t *d, /* data block pointer */ + xfs_dir2_data_hdr_t *hdr, /* data block header */ xfs_dir2_data_free_t *dfp, /* bestfree entry pointer */ int *loghead) /* out: log data header */ { -#ifdef __KERNEL__ - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); -#endif + struct xfs_dir2_data_free *bf; + + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); + /* * It's the first entry, slide the next 2 up. */ - if (dfp == &d->hdr.bestfree[0]) { - d->hdr.bestfree[0] = d->hdr.bestfree[1]; - d->hdr.bestfree[1] = d->hdr.bestfree[2]; + bf = xfs_dir3_data_bestfree_p(hdr); + if (dfp == &bf[0]) { + bf[0] = bf[1]; + bf[1] = bf[2]; } /* * It's the second entry, slide the 3rd entry up. */ - else if (dfp == &d->hdr.bestfree[1]) - d->hdr.bestfree[1] = d->hdr.bestfree[2]; + else if (dfp == &bf[1]) + bf[1] = bf[2]; /* * Must be the last entry. */ else - ASSERT(dfp == &d->hdr.bestfree[2]); + ASSERT(dfp == &bf[2]); /* * Clear the 3rd entry, must be zero now. */ - d->hdr.bestfree[2].length = 0; - d->hdr.bestfree[2].offset = 0; + bf[2].length = 0; + bf[2].offset = 0; *loghead = 1; } @@ -309,33 +471,37 @@ void xfs_dir2_data_freescan( xfs_mount_t *mp, /* filesystem mount point */ - xfs_dir2_data_t *d, /* data block pointer */ + xfs_dir2_data_hdr_t *hdr, /* data block header */ int *loghead) /* out: log data header */ { xfs_dir2_block_tail_t *btp; /* block tail */ xfs_dir2_data_entry_t *dep; /* active data entry */ xfs_dir2_data_unused_t *dup; /* unused data entry */ + struct xfs_dir2_data_free *bf; char *endp; /* end of block's data */ char *p; /* current entry pointer */ -#ifdef __KERNEL__ - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); -#endif + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); + /* * Start by clearing the table. */ - memset(d->hdr.bestfree, 0, sizeof(d->hdr.bestfree)); + bf = xfs_dir3_data_bestfree_p(hdr); + memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT); *loghead = 1; /* * Set up pointers. */ - p = (char *)d->u; - if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { - btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); + p = (char *)xfs_dir3_data_entry_p(hdr); + if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { + btp = xfs_dir2_block_tail_p(mp, hdr); endp = (char *)xfs_dir2_block_leaf_p(btp); } else - endp = (char *)d + mp->m_dirblksize; + endp = (char *)hdr + mp->m_dirblksize; /* * Loop over the block's entries. */ @@ -345,9 +511,9 @@ * If it's a free entry, insert it. */ if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { - ASSERT((char *)dup - (char *)d == + ASSERT((char *)dup - (char *)hdr == be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup))); - xfs_dir2_data_freeinsert(d, dup, loghead); + xfs_dir2_data_freeinsert(hdr, dup, loghead); p += be16_to_cpu(dup->length); } /* @@ -355,9 +521,9 @@ */ else { dep = (xfs_dir2_data_entry_t *)p; - ASSERT((char *)dep - (char *)d == - be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep))); - p += xfs_dir2_data_entsize(dep->namelen); + ASSERT((char *)dep - (char *)hdr == + be16_to_cpu(*xfs_dir3_data_entry_tag_p(mp, dep))); + p += xfs_dir3_data_entsize(mp, dep->namelen); } } } @@ -367,15 +533,16 @@ * Give back the buffer for the created block. */ int /* error */ -xfs_dir2_data_init( +xfs_dir3_data_init( xfs_da_args_t *args, /* directory operation args */ xfs_dir2_db_t blkno, /* logical dir block number */ - xfs_dabuf_t **bpp) /* output block buffer */ + struct xfs_buf **bpp) /* output block buffer */ { - xfs_dabuf_t *bp; /* block buffer */ - xfs_dir2_data_t *d; /* pointer to block */ + struct xfs_buf *bp; /* block buffer */ + xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_inode_t *dp; /* incore directory inode */ xfs_dir2_data_unused_t *dup; /* unused entry pointer */ + struct xfs_dir2_data_free *bf; int error; /* error return value */ int i; /* bestfree index */ xfs_mount_t *mp; /* filesystem mount point */ @@ -390,30 +557,44 @@ */ error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, blkno), -1, &bp, XFS_DATA_FORK); - if (error) { + if (error) return error; - } - ASSERT(bp != NULL); + bp->b_ops = &xfs_dir3_data_buf_ops; + xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_DATA_BUF); + /* * Initialize the header. */ - d = bp->data; - d->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); - d->hdr.bestfree[0].offset = cpu_to_be16(sizeof(d->hdr)); + hdr = bp->b_addr; + if (xfs_sb_version_hascrc(&mp->m_sb)) { + struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; + + memset(hdr3, 0, sizeof(*hdr3)); + hdr3->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC); + hdr3->blkno = cpu_to_be64(bp->b_bn); + hdr3->owner = cpu_to_be64(dp->i_ino); + uuid_copy(&hdr3->uuid, &mp->m_sb.sb_uuid); + + } else + hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); + + bf = xfs_dir3_data_bestfree_p(hdr); + bf[0].offset = cpu_to_be16(xfs_dir3_data_entry_offset(hdr)); for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) { - d->hdr.bestfree[i].length = 0; - d->hdr.bestfree[i].offset = 0; + bf[i].length = 0; + bf[i].offset = 0; } + /* * Set up an unused entry for the block's body. */ - dup = &d->u[0].unused; + dup = xfs_dir3_data_unused_p(hdr); dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); - t=mp->m_dirblksize - (uint)sizeof(d->hdr); - d->hdr.bestfree[0].length = cpu_to_be16(t); + t = mp->m_dirblksize - (uint)xfs_dir3_data_entry_offset(hdr); + bf[0].length = cpu_to_be16(t); dup->length = cpu_to_be16(t); - *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)d); + *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr); /* * Log it and return it. */ @@ -428,18 +609,21 @@ */ void xfs_dir2_data_log_entry( - xfs_trans_t *tp, /* transaction pointer */ - xfs_dabuf_t *bp, /* block buffer */ + struct xfs_trans *tp, + struct xfs_buf *bp, xfs_dir2_data_entry_t *dep) /* data entry pointer */ { - xfs_dir2_data_t *d; /* data block pointer */ + struct xfs_dir2_data_hdr *hdr = bp->b_addr; + struct xfs_mount *mp = tp->t_mountp; - d = bp->data; - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); - xfs_da_log_buf(tp, bp, (uint)((char *)dep - (char *)d), - (uint)((char *)(xfs_dir2_data_entry_tag_p(dep) + 1) - - (char *)d - 1)); + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); + + xfs_trans_log_buf(tp, bp, (uint)((char *)dep - (char *)hdr), + (uint)((char *)(xfs_dir3_data_entry_tag_p(mp, dep) + 1) - + (char *)hdr - 1)); } /* @@ -447,16 +631,17 @@ */ void xfs_dir2_data_log_header( - xfs_trans_t *tp, /* transaction pointer */ - xfs_dabuf_t *bp) /* block buffer */ + struct xfs_trans *tp, + struct xfs_buf *bp) { - xfs_dir2_data_t *d; /* data block pointer */ + xfs_dir2_data_hdr_t *hdr = bp->b_addr; - d = bp->data; - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); - xfs_da_log_buf(tp, bp, (uint)((char *)&d->hdr - (char *)d), - (uint)(sizeof(d->hdr) - 1)); + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); + + xfs_trans_log_buf(tp, bp, 0, xfs_dir3_data_entry_offset(hdr) - 1); } /* @@ -464,27 +649,29 @@ */ void xfs_dir2_data_log_unused( - xfs_trans_t *tp, /* transaction pointer */ - xfs_dabuf_t *bp, /* block buffer */ + struct xfs_trans *tp, + struct xfs_buf *bp, xfs_dir2_data_unused_t *dup) /* data unused pointer */ { - xfs_dir2_data_t *d; /* data block pointer */ + xfs_dir2_data_hdr_t *hdr = bp->b_addr; + + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); - d = bp->data; - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); /* * Log the first part of the unused entry. */ - xfs_da_log_buf(tp, bp, (uint)((char *)dup - (char *)d), + xfs_trans_log_buf(tp, bp, (uint)((char *)dup - (char *)hdr), (uint)((char *)&dup->length + sizeof(dup->length) - - 1 - (char *)d)); + 1 - (char *)hdr)); /* * Log the end (tag) of the unused entry. */ - xfs_da_log_buf(tp, bp, - (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)d), - (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)d + + xfs_trans_log_buf(tp, bp, + (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr), + (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr + sizeof(xfs_dir2_data_off_t) - 1)); } @@ -494,14 +681,14 @@ */ void xfs_dir2_data_make_free( - xfs_trans_t *tp, /* transaction pointer */ - xfs_dabuf_t *bp, /* block buffer */ + struct xfs_trans *tp, + struct xfs_buf *bp, xfs_dir2_data_aoff_t offset, /* starting byte offset */ xfs_dir2_data_aoff_t len, /* length in bytes */ int *needlogp, /* out: log header */ int *needscanp) /* out: regen bestfree */ { - xfs_dir2_data_t *d; /* data block pointer */ + xfs_dir2_data_hdr_t *hdr; /* data block pointer */ xfs_dir2_data_free_t *dfp; /* bestfree pointer */ char *endptr; /* end of data area */ xfs_mount_t *mp; /* filesystem mount point */ @@ -509,30 +696,34 @@ xfs_dir2_data_unused_t *newdup; /* new unused entry */ xfs_dir2_data_unused_t *postdup; /* unused entry after us */ xfs_dir2_data_unused_t *prevdup; /* unused entry before us */ + struct xfs_dir2_data_free *bf; mp = tp->t_mountp; - d = bp->data; + hdr = bp->b_addr; + /* * Figure out where the end of the data area is. */ - if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC) - endptr = (char *)d + mp->m_dirblksize; + if (hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)) + endptr = (char *)hdr + mp->m_dirblksize; else { xfs_dir2_block_tail_t *btp; /* block tail */ - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); - btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); + btp = xfs_dir2_block_tail_p(mp, hdr); endptr = (char *)xfs_dir2_block_leaf_p(btp); } /* * If this isn't the start of the block, then back up to * the previous entry and see if it's free. */ - if (offset > sizeof(d->hdr)) { + if (offset > xfs_dir3_data_entry_offset(hdr)) { __be16 *tagp; /* tag just before us */ - tagp = (__be16 *)((char *)d + offset) - 1; - prevdup = (xfs_dir2_data_unused_t *)((char *)d + be16_to_cpu(*tagp)); + tagp = (__be16 *)((char *)hdr + offset) - 1; + prevdup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp)); if (be16_to_cpu(prevdup->freetag) != XFS_DIR2_DATA_FREE_TAG) prevdup = NULL; } else @@ -541,9 +732,9 @@ * If this isn't the end of the block, see if the entry after * us is free. */ - if ((char *)d + offset + len < endptr) { + if ((char *)hdr + offset + len < endptr) { postdup = - (xfs_dir2_data_unused_t *)((char *)d + offset + len); + (xfs_dir2_data_unused_t *)((char *)hdr + offset + len); if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG) postdup = NULL; } else @@ -554,27 +745,28 @@ * Previous and following entries are both free, * merge everything into a single free entry. */ + bf = xfs_dir3_data_bestfree_p(hdr); if (prevdup && postdup) { xfs_dir2_data_free_t *dfp2; /* another bestfree pointer */ /* * See if prevdup and/or postdup are in bestfree table. */ - dfp = xfs_dir2_data_freefind(d, prevdup); - dfp2 = xfs_dir2_data_freefind(d, postdup); + dfp = xfs_dir2_data_freefind(hdr, prevdup); + dfp2 = xfs_dir2_data_freefind(hdr, postdup); /* * We need a rescan unless there are exactly 2 free entries * namely our two. Then we know what's happening, otherwise * since the third bestfree is there, there might be more * entries. */ - needscan = (d->hdr.bestfree[2].length != 0); + needscan = (bf[2].length != 0); /* * Fix up the new big freespace. */ be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length)); *xfs_dir2_data_unused_tag_p(prevdup) = - cpu_to_be16((char *)prevdup - (char *)d); + cpu_to_be16((char *)prevdup - (char *)hdr); xfs_dir2_data_log_unused(tp, bp, prevdup); if (!needscan) { /* @@ -584,18 +776,18 @@ * Remove entry 1 first then entry 0. */ ASSERT(dfp && dfp2); - if (dfp == &d->hdr.bestfree[1]) { - dfp = &d->hdr.bestfree[0]; + if (dfp == &bf[1]) { + dfp = &bf[0]; ASSERT(dfp2 == dfp); - dfp2 = &d->hdr.bestfree[1]; + dfp2 = &bf[1]; } - xfs_dir2_data_freeremove(d, dfp2, needlogp); - xfs_dir2_data_freeremove(d, dfp, needlogp); + xfs_dir2_data_freeremove(hdr, dfp2, needlogp); + xfs_dir2_data_freeremove(hdr, dfp, needlogp); /* * Now insert the new entry. */ - dfp = xfs_dir2_data_freeinsert(d, prevdup, needlogp); - ASSERT(dfp == &d->hdr.bestfree[0]); + dfp = xfs_dir2_data_freeinsert(hdr, prevdup, needlogp); + ASSERT(dfp == &bf[0]); ASSERT(dfp->length == prevdup->length); ASSERT(!dfp[1].length); ASSERT(!dfp[2].length); @@ -605,10 +797,10 @@ * The entry before us is free, merge with it. */ else if (prevdup) { - dfp = xfs_dir2_data_freefind(d, prevdup); + dfp = xfs_dir2_data_freefind(hdr, prevdup); be16_add_cpu(&prevdup->length, len); *xfs_dir2_data_unused_tag_p(prevdup) = - cpu_to_be16((char *)prevdup - (char *)d); + cpu_to_be16((char *)prevdup - (char *)hdr); xfs_dir2_data_log_unused(tp, bp, prevdup); /* * If the previous entry was in the table, the new entry @@ -616,27 +808,27 @@ * the old one and add the new one. */ if (dfp) { - xfs_dir2_data_freeremove(d, dfp, needlogp); - (void)xfs_dir2_data_freeinsert(d, prevdup, needlogp); + xfs_dir2_data_freeremove(hdr, dfp, needlogp); + xfs_dir2_data_freeinsert(hdr, prevdup, needlogp); } /* * Otherwise we need a scan if the new entry is big enough. */ else { needscan = be16_to_cpu(prevdup->length) > - be16_to_cpu(d->hdr.bestfree[2].length); + be16_to_cpu(bf[2].length); } } /* * The following entry is free, merge with it. */ else if (postdup) { - dfp = xfs_dir2_data_freefind(d, postdup); - newdup = (xfs_dir2_data_unused_t *)((char *)d + offset); + dfp = xfs_dir2_data_freefind(hdr, postdup); + newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset); newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length)); *xfs_dir2_data_unused_tag_p(newdup) = - cpu_to_be16((char *)newdup - (char *)d); + cpu_to_be16((char *)newdup - (char *)hdr); xfs_dir2_data_log_unused(tp, bp, newdup); /* * If the following entry was in the table, the new entry @@ -644,28 +836,28 @@ * the old one and add the new one. */ if (dfp) { - xfs_dir2_data_freeremove(d, dfp, needlogp); - (void)xfs_dir2_data_freeinsert(d, newdup, needlogp); + xfs_dir2_data_freeremove(hdr, dfp, needlogp); + xfs_dir2_data_freeinsert(hdr, newdup, needlogp); } /* * Otherwise we need a scan if the new entry is big enough. */ else { needscan = be16_to_cpu(newdup->length) > - be16_to_cpu(d->hdr.bestfree[2].length); + be16_to_cpu(bf[2].length); } } /* * Neither neighbor is free. Make a new entry. */ else { - newdup = (xfs_dir2_data_unused_t *)((char *)d + offset); + newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset); newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); newdup->length = cpu_to_be16(len); *xfs_dir2_data_unused_tag_p(newdup) = - cpu_to_be16((char *)newdup - (char *)d); + cpu_to_be16((char *)newdup - (char *)hdr); xfs_dir2_data_log_unused(tp, bp, newdup); - (void)xfs_dir2_data_freeinsert(d, newdup, needlogp); + xfs_dir2_data_freeinsert(hdr, newdup, needlogp); } *needscanp = needscan; } @@ -675,15 +867,15 @@ */ void xfs_dir2_data_use_free( - xfs_trans_t *tp, /* transaction pointer */ - xfs_dabuf_t *bp, /* data block buffer */ + struct xfs_trans *tp, + struct xfs_buf *bp, xfs_dir2_data_unused_t *dup, /* unused entry */ xfs_dir2_data_aoff_t offset, /* starting offset to use */ xfs_dir2_data_aoff_t len, /* length to use */ int *needlogp, /* out: need to log header */ int *needscanp) /* out: need regen bestfree */ { - xfs_dir2_data_t *d; /* data block */ + xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_data_free_t *dfp; /* bestfree pointer */ int matchback; /* matches end of freespace */ int matchfront; /* matches start of freespace */ @@ -691,25 +883,29 @@ xfs_dir2_data_unused_t *newdup; /* new unused entry */ xfs_dir2_data_unused_t *newdup2; /* another new unused entry */ int oldlen; /* old unused entry's length */ + struct xfs_dir2_data_free *bf; - d = bp->data; - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); + hdr = bp->b_addr; + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG); - ASSERT(offset >= (char *)dup - (char *)d); - ASSERT(offset + len <= (char *)dup + be16_to_cpu(dup->length) - (char *)d); - ASSERT((char *)dup - (char *)d == be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup))); + ASSERT(offset >= (char *)dup - (char *)hdr); + ASSERT(offset + len <= (char *)dup + be16_to_cpu(dup->length) - (char *)hdr); + ASSERT((char *)dup - (char *)hdr == be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup))); /* * Look up the entry in the bestfree table. */ - dfp = xfs_dir2_data_freefind(d, dup); + dfp = xfs_dir2_data_freefind(hdr, dup); oldlen = be16_to_cpu(dup->length); - ASSERT(dfp || oldlen <= be16_to_cpu(d->hdr.bestfree[2].length)); + bf = xfs_dir3_data_bestfree_p(hdr); + ASSERT(dfp || oldlen <= be16_to_cpu(bf[2].length)); /* * Check for alignment with front and back of the entry. */ - matchfront = (char *)dup - (char *)d == offset; - matchback = (char *)dup + oldlen - (char *)d == offset + len; + matchfront = (char *)dup - (char *)hdr == offset; + matchback = (char *)dup + oldlen - (char *)hdr == offset + len; ASSERT(*needscanp == 0); needscan = 0; /* @@ -718,9 +914,9 @@ */ if (matchfront && matchback) { if (dfp) { - needscan = (d->hdr.bestfree[2].offset != 0); + needscan = (bf[2].offset != 0); if (!needscan) - xfs_dir2_data_freeremove(d, dfp, needlogp); + xfs_dir2_data_freeremove(hdr, dfp, needlogp); } } /* @@ -728,27 +924,27 @@ * Make a new entry with the remaining freespace. */ else if (matchfront) { - newdup = (xfs_dir2_data_unused_t *)((char *)d + offset + len); + newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len); newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); newdup->length = cpu_to_be16(oldlen - len); *xfs_dir2_data_unused_tag_p(newdup) = - cpu_to_be16((char *)newdup - (char *)d); + cpu_to_be16((char *)newdup - (char *)hdr); xfs_dir2_data_log_unused(tp, bp, newdup); /* * If it was in the table, remove it and add the new one. */ if (dfp) { - xfs_dir2_data_freeremove(d, dfp, needlogp); - dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp); + xfs_dir2_data_freeremove(hdr, dfp, needlogp); + dfp = xfs_dir2_data_freeinsert(hdr, newdup, needlogp); ASSERT(dfp != NULL); ASSERT(dfp->length == newdup->length); - ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d); + ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)hdr); /* * If we got inserted at the last slot, * that means we don't know if there was a better * choice for the last slot, or not. Rescan. */ - needscan = dfp == &d->hdr.bestfree[2]; + needscan = dfp == &bf[2]; } } /* @@ -757,25 +953,25 @@ */ else if (matchback) { newdup = dup; - newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup); + newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup); *xfs_dir2_data_unused_tag_p(newdup) = - cpu_to_be16((char *)newdup - (char *)d); + cpu_to_be16((char *)newdup - (char *)hdr); xfs_dir2_data_log_unused(tp, bp, newdup); /* * If it was in the table, remove it and add the new one. */ if (dfp) { - xfs_dir2_data_freeremove(d, dfp, needlogp); - dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp); + xfs_dir2_data_freeremove(hdr, dfp, needlogp); + dfp = xfs_dir2_data_freeinsert(hdr, newdup, needlogp); ASSERT(dfp != NULL); ASSERT(dfp->length == newdup->length); - ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d); + ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)hdr); /* * If we got inserted at the last slot, * that means we don't know if there was a better * choice for the last slot, or not. Rescan. */ - needscan = dfp == &d->hdr.bestfree[2]; + needscan = dfp == &bf[2]; } } /* @@ -784,15 +980,15 @@ */ else { newdup = dup; - newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup); + newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup); *xfs_dir2_data_unused_tag_p(newdup) = - cpu_to_be16((char *)newdup - (char *)d); + cpu_to_be16((char *)newdup - (char *)hdr); xfs_dir2_data_log_unused(tp, bp, newdup); - newdup2 = (xfs_dir2_data_unused_t *)((char *)d + offset + len); + newdup2 = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len); newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length)); *xfs_dir2_data_unused_tag_p(newdup2) = - cpu_to_be16((char *)newdup2 - (char *)d); + cpu_to_be16((char *)newdup2 - (char *)hdr); xfs_dir2_data_log_unused(tp, bp, newdup2); /* * If the old entry was in the table, we need to scan @@ -803,13 +999,12 @@ * the 2 new will work. */ if (dfp) { - needscan = (d->hdr.bestfree[2].length != 0); + needscan = (bf[2].length != 0); if (!needscan) { - xfs_dir2_data_freeremove(d, dfp, needlogp); - (void)xfs_dir2_data_freeinsert(d, newdup, - needlogp); - (void)xfs_dir2_data_freeinsert(d, newdup2, - needlogp); + xfs_dir2_data_freeremove(hdr, dfp, needlogp); + xfs_dir2_data_freeinsert(hdr, newdup, needlogp); + xfs_dir2_data_freeinsert(hdr, newdup2, + needlogp); } } } diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2_leaf.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_dir2_leaf.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2_leaf.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_dir2_leaf.c 2014-05-02 00:09:16.000000000 +0000 @@ -1,5 +1,6 @@ /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. + * Copyright (c) 2013 Red Hat, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -21,17 +22,373 @@ /* * Local function declarations. */ +static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, struct xfs_buf **lbpp, + int *indexp, struct xfs_buf **dbpp); +static void xfs_dir3_leaf_log_bests(struct xfs_trans *tp, struct xfs_buf *bp, + int first, int last); +static void xfs_dir3_leaf_log_tail(struct xfs_trans *tp, struct xfs_buf *bp); + +/* + * Check the internal consistency of a leaf1 block. + * Pop an assert if something is wrong. + */ #ifdef DEBUG -static void xfs_dir2_leaf_check(xfs_inode_t *dp, xfs_dabuf_t *bp); +#define xfs_dir3_leaf_check(mp, bp) \ +do { \ + if (!xfs_dir3_leaf1_check((mp), (bp))) \ + ASSERT(0); \ +} while (0); + +STATIC bool +xfs_dir3_leaf1_check( + struct xfs_mount *mp, + struct xfs_buf *bp) +{ + struct xfs_dir2_leaf *leaf = bp->b_addr; + struct xfs_dir3_icleaf_hdr leafhdr; + + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + + if (leafhdr.magic == XFS_DIR3_LEAF1_MAGIC) { + struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr; + if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn) + return false; + } else if (leafhdr.magic != XFS_DIR2_LEAF1_MAGIC) + return false; + + return xfs_dir3_leaf_check_int(mp, &leafhdr, leaf); +} #else -#define xfs_dir2_leaf_check(dp, bp) +#define xfs_dir3_leaf_check(mp, bp) #endif -static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **lbpp, - int *indexp, xfs_dabuf_t **dbpp); -static void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp, - int first, int last); -static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp); +void +xfs_dir3_leaf_hdr_from_disk( + struct xfs_dir3_icleaf_hdr *to, + struct xfs_dir2_leaf *from) +{ + if (from->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || + from->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)) { + to->forw = be32_to_cpu(from->hdr.info.forw); + to->back = be32_to_cpu(from->hdr.info.back); + to->magic = be16_to_cpu(from->hdr.info.magic); + to->count = be16_to_cpu(from->hdr.count); + to->stale = be16_to_cpu(from->hdr.stale); + } else { + struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)from; + + to->forw = be32_to_cpu(hdr3->info.hdr.forw); + to->back = be32_to_cpu(hdr3->info.hdr.back); + to->magic = be16_to_cpu(hdr3->info.hdr.magic); + to->count = be16_to_cpu(hdr3->count); + to->stale = be16_to_cpu(hdr3->stale); + } + + ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC || + to->magic == XFS_DIR3_LEAF1_MAGIC || + to->magic == XFS_DIR2_LEAFN_MAGIC || + to->magic == XFS_DIR3_LEAFN_MAGIC); +} + +void +xfs_dir3_leaf_hdr_to_disk( + struct xfs_dir2_leaf *to, + struct xfs_dir3_icleaf_hdr *from) +{ + ASSERT(from->magic == XFS_DIR2_LEAF1_MAGIC || + from->magic == XFS_DIR3_LEAF1_MAGIC || + from->magic == XFS_DIR2_LEAFN_MAGIC || + from->magic == XFS_DIR3_LEAFN_MAGIC); + + if (from->magic == XFS_DIR2_LEAF1_MAGIC || + from->magic == XFS_DIR2_LEAFN_MAGIC) { + to->hdr.info.forw = cpu_to_be32(from->forw); + to->hdr.info.back = cpu_to_be32(from->back); + to->hdr.info.magic = cpu_to_be16(from->magic); + to->hdr.count = cpu_to_be16(from->count); + to->hdr.stale = cpu_to_be16(from->stale); + } else { + struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)to; + + hdr3->info.hdr.forw = cpu_to_be32(from->forw); + hdr3->info.hdr.back = cpu_to_be32(from->back); + hdr3->info.hdr.magic = cpu_to_be16(from->magic); + hdr3->count = cpu_to_be16(from->count); + hdr3->stale = cpu_to_be16(from->stale); + } +} + +bool +xfs_dir3_leaf_check_int( + struct xfs_mount *mp, + struct xfs_dir3_icleaf_hdr *hdr, + struct xfs_dir2_leaf *leaf) +{ + struct xfs_dir2_leaf_entry *ents; + xfs_dir2_leaf_tail_t *ltp; + int stale; + int i; + + ents = xfs_dir3_leaf_ents_p(leaf); + ltp = xfs_dir2_leaf_tail_p(mp, leaf); + + /* + * XXX (dgc): This value is not restrictive enough. + * Should factor in the size of the bests table as well. + * We can deduce a value for that from di_size. + */ + if (hdr->count > xfs_dir3_max_leaf_ents(mp, leaf)) + return false; + + /* Leaves and bests don't overlap in leaf format. */ + if ((hdr->magic == XFS_DIR2_LEAF1_MAGIC || + hdr->magic == XFS_DIR3_LEAF1_MAGIC) && + (char *)&ents[hdr->count] > (char *)xfs_dir2_leaf_bests_p(ltp)) + return false; + + /* Check hash value order, count stale entries. */ + for (i = stale = 0; i < hdr->count; i++) { + if (i + 1 < hdr->count) { + if (be32_to_cpu(ents[i].hashval) > + be32_to_cpu(ents[i + 1].hashval)) + return false; + } + if (ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) + stale++; + } + if (hdr->stale != stale) + return false; + return true; +} + +/* + * We verify the magic numbers before decoding the leaf header so that on debug + * kernels we don't get assertion failures in xfs_dir3_leaf_hdr_from_disk() due + * to incorrect magic numbers. + */ +static bool +xfs_dir3_leaf_verify( + struct xfs_buf *bp, + __uint16_t magic) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_dir2_leaf *leaf = bp->b_addr; + struct xfs_dir3_icleaf_hdr leafhdr; + + ASSERT(magic == XFS_DIR2_LEAF1_MAGIC || magic == XFS_DIR2_LEAFN_MAGIC); + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr; + __uint16_t magic3; + + magic3 = (magic == XFS_DIR2_LEAF1_MAGIC) ? XFS_DIR3_LEAF1_MAGIC + : XFS_DIR3_LEAFN_MAGIC; + + if (leaf3->info.hdr.magic != cpu_to_be16(magic3)) + return false; + if (!uuid_equal(&leaf3->info.uuid, &mp->m_sb.sb_uuid)) + return false; + if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn) + return false; + } else { + if (leaf->hdr.info.magic != cpu_to_be16(magic)) + return false; + } + + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + return xfs_dir3_leaf_check_int(mp, &leafhdr, leaf); +} + +static void +__read_verify( + struct xfs_buf *bp, + __uint16_t magic) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + + if (xfs_sb_version_hascrc(&mp->m_sb) && + !xfs_buf_verify_cksum(bp, XFS_DIR3_LEAF_CRC_OFF)) + xfs_buf_ioerror(bp, EFSBADCRC); + else if (!xfs_dir3_leaf_verify(bp, magic)) + xfs_buf_ioerror(bp, EFSCORRUPTED); + + if (bp->b_error) + xfs_verifier_error(bp); +} + +static void +__write_verify( + struct xfs_buf *bp, + __uint16_t magic) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_dir3_leaf_hdr *hdr3 = bp->b_addr; + + if (!xfs_dir3_leaf_verify(bp, magic)) { + xfs_buf_ioerror(bp, EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return; + + if (bip) + hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn); + + xfs_buf_update_cksum(bp, XFS_DIR3_LEAF_CRC_OFF); +} + +static void +xfs_dir3_leaf1_read_verify( + struct xfs_buf *bp) +{ + __read_verify(bp, XFS_DIR2_LEAF1_MAGIC); +} + +static void +xfs_dir3_leaf1_write_verify( + struct xfs_buf *bp) +{ + __write_verify(bp, XFS_DIR2_LEAF1_MAGIC); +} + +static void +xfs_dir3_leafn_read_verify( + struct xfs_buf *bp) +{ + __read_verify(bp, XFS_DIR2_LEAFN_MAGIC); +} + +static void +xfs_dir3_leafn_write_verify( + struct xfs_buf *bp) +{ + __write_verify(bp, XFS_DIR2_LEAFN_MAGIC); +} + +const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops = { + .verify_read = xfs_dir3_leaf1_read_verify, + .verify_write = xfs_dir3_leaf1_write_verify, +}; + +const struct xfs_buf_ops xfs_dir3_leafn_buf_ops = { + .verify_read = xfs_dir3_leafn_read_verify, + .verify_write = xfs_dir3_leafn_write_verify, +}; + +static int +xfs_dir3_leaf_read( + struct xfs_trans *tp, + struct xfs_inode *dp, + xfs_dablk_t fbno, + xfs_daddr_t mappedbno, + struct xfs_buf **bpp) +{ + int err; + + err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, + XFS_DATA_FORK, &xfs_dir3_leaf1_buf_ops); + if (!err && tp) + xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_LEAF1_BUF); + return err; +} + +int +xfs_dir3_leafn_read( + struct xfs_trans *tp, + struct xfs_inode *dp, + xfs_dablk_t fbno, + xfs_daddr_t mappedbno, + struct xfs_buf **bpp) +{ + int err; + + err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, + XFS_DATA_FORK, &xfs_dir3_leafn_buf_ops); + if (!err && tp) + xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_LEAFN_BUF); + return err; +} + +/* + * Initialize a new leaf block, leaf1 or leafn magic accepted. + */ +static void +xfs_dir3_leaf_init( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_buf *bp, + xfs_ino_t owner, + __uint16_t type) +{ + struct xfs_dir2_leaf *leaf = bp->b_addr; + + ASSERT(type == XFS_DIR2_LEAF1_MAGIC || type == XFS_DIR2_LEAFN_MAGIC); + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr; + + memset(leaf3, 0, sizeof(*leaf3)); + + leaf3->info.hdr.magic = (type == XFS_DIR2_LEAF1_MAGIC) + ? cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) + : cpu_to_be16(XFS_DIR3_LEAFN_MAGIC); + leaf3->info.blkno = cpu_to_be64(bp->b_bn); + leaf3->info.owner = cpu_to_be64(owner); + uuid_copy(&leaf3->info.uuid, &mp->m_sb.sb_uuid); + } else { + memset(leaf, 0, sizeof(*leaf)); + leaf->hdr.info.magic = cpu_to_be16(type); + } + + /* + * If it's a leaf-format directory initialize the tail. + * Caller is responsible for initialising the bests table. + */ + if (type == XFS_DIR2_LEAF1_MAGIC) { + struct xfs_dir2_leaf_tail *ltp; + + ltp = xfs_dir2_leaf_tail_p(mp, leaf); + ltp->bestcount = 0; + bp->b_ops = &xfs_dir3_leaf1_buf_ops; + xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_LEAF1_BUF); + } else { + bp->b_ops = &xfs_dir3_leafn_buf_ops; + xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_LEAFN_BUF); + } +} + +int +xfs_dir3_leaf_get_buf( + xfs_da_args_t *args, + xfs_dir2_db_t bno, + struct xfs_buf **bpp, + __uint16_t magic) +{ + struct xfs_inode *dp = args->dp; + struct xfs_trans *tp = args->trans; + struct xfs_mount *mp = dp->i_mount; + struct xfs_buf *bp; + int error; + + ASSERT(magic == XFS_DIR2_LEAF1_MAGIC || magic == XFS_DIR2_LEAFN_MAGIC); + ASSERT(bno >= XFS_DIR2_LEAF_FIRSTDB(mp) && + bno < XFS_DIR2_FREE_FIRSTDB(mp)); + + error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, bno), -1, &bp, + XFS_DATA_FORK); + if (error) + return error; + + xfs_dir3_leaf_init(mp, tp, bp, dp->i_ino, magic); + xfs_dir3_leaf_log_header(tp, bp); + if (magic == XFS_DIR2_LEAF1_MAGIC) + xfs_dir3_leaf_log_tail(tp, bp); + *bpp = bp; + return 0; +} /* * Convert a block form directory to a leaf form directory. @@ -39,16 +396,16 @@ int /* error */ xfs_dir2_block_to_leaf( xfs_da_args_t *args, /* operation arguments */ - xfs_dabuf_t *dbp) /* input block's buffer */ + struct xfs_buf *dbp) /* input block's buffer */ { __be16 *bestsp; /* leaf's bestsp entries */ xfs_dablk_t blkno; /* leaf block's bno */ - xfs_dir2_block_t *block; /* block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_leaf_entry_t *blp; /* block's leaf entries */ xfs_dir2_block_tail_t *btp; /* block's tail */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return code */ - xfs_dabuf_t *lbp; /* leaf block's buffer */ + struct xfs_buf *lbp; /* leaf block's buffer */ xfs_dir2_db_t ldb; /* leaf block's bno */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_tail_t *ltp; /* leaf's tail */ @@ -56,6 +413,9 @@ int needlog; /* need to log block header */ int needscan; /* need to rescan bestfree */ xfs_trans_t *tp; /* transaction pointer */ + struct xfs_dir2_data_free *bf; + struct xfs_dir2_leaf_entry *ents; + struct xfs_dir3_icleaf_hdr leafhdr; trace_xfs_dir2_block_to_leaf(args); @@ -75,26 +435,33 @@ /* * Initialize the leaf block, get a buffer for it. */ - if ((error = xfs_dir2_leaf_init(args, ldb, &lbp, XFS_DIR2_LEAF1_MAGIC))) { + error = xfs_dir3_leaf_get_buf(args, ldb, &lbp, XFS_DIR2_LEAF1_MAGIC); + if (error) return error; - } - ASSERT(lbp != NULL); - leaf = lbp->data; - block = dbp->data; - xfs_dir2_data_check(dp, dbp); - btp = xfs_dir2_block_tail_p(mp, block); + + leaf = lbp->b_addr; + hdr = dbp->b_addr; + xfs_dir3_data_check(dp, dbp); + btp = xfs_dir2_block_tail_p(mp, hdr); blp = xfs_dir2_block_leaf_p(btp); + bf = xfs_dir3_data_bestfree_p(hdr); + ents = xfs_dir3_leaf_ents_p(leaf); + /* * Set the counts in the leaf header. */ - leaf->hdr.count = cpu_to_be16(be32_to_cpu(btp->count)); - leaf->hdr.stale = cpu_to_be16(be32_to_cpu(btp->stale)); + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + leafhdr.count = be32_to_cpu(btp->count); + leafhdr.stale = be32_to_cpu(btp->stale); + xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr); + xfs_dir3_leaf_log_header(tp, lbp); + /* * Could compact these but I think we always do the conversion * after squeezing out stale entries. */ - memcpy(leaf->ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t)); - xfs_dir2_leaf_log_ents(tp, lbp, 0, be16_to_cpu(leaf->hdr.count) - 1); + memcpy(ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t)); + xfs_dir3_leaf_log_ents(tp, lbp, 0, leafhdr.count - 1); needscan = 0; needlog = 1; /* @@ -102,35 +469,161 @@ * tail be free. */ xfs_dir2_data_make_free(tp, dbp, - (xfs_dir2_data_aoff_t)((char *)blp - (char *)block), - (xfs_dir2_data_aoff_t)((char *)block + mp->m_dirblksize - + (xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr), + (xfs_dir2_data_aoff_t)((char *)hdr + mp->m_dirblksize - (char *)blp), &needlog, &needscan); /* * Fix up the block header, make it a data block. */ - block->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); + dbp->b_ops = &xfs_dir3_data_buf_ops; + xfs_trans_buf_set_type(tp, dbp, XFS_BLFT_DIR_DATA_BUF); + if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) + hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); + else + hdr->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC); + if (needscan) - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); /* * Set up leaf tail and bests table. */ ltp = xfs_dir2_leaf_tail_p(mp, leaf); ltp->bestcount = cpu_to_be32(1); bestsp = xfs_dir2_leaf_bests_p(ltp); - bestsp[0] = block->hdr.bestfree[0].length; + bestsp[0] = bf[0].length; /* * Log the data header and leaf bests table. */ if (needlog) xfs_dir2_data_log_header(tp, dbp); - xfs_dir2_leaf_check(dp, lbp); - xfs_dir2_data_check(dp, dbp); - xfs_dir2_leaf_log_bests(tp, lbp, 0, 0); - xfs_da_buf_done(lbp); + xfs_dir3_leaf_check(mp, lbp); + xfs_dir3_data_check(dp, dbp); + xfs_dir3_leaf_log_bests(tp, lbp, 0, 0); return 0; } +STATIC void +xfs_dir3_leaf_find_stale( + struct xfs_dir3_icleaf_hdr *leafhdr, + struct xfs_dir2_leaf_entry *ents, + int index, + int *lowstale, + int *highstale) +{ + /* + * Find the first stale entry before our index, if any. + */ + for (*lowstale = index - 1; *lowstale >= 0; --*lowstale) { + if (ents[*lowstale].address == + cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) + break; + } + + /* + * Find the first stale entry at or after our index, if any. + * Stop if the result would require moving more entries than using + * lowstale. + */ + for (*highstale = index; *highstale < leafhdr->count; ++*highstale) { + if (ents[*highstale].address == + cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) + break; + if (*lowstale >= 0 && index - *lowstale <= *highstale - index) + break; + } +} + +struct xfs_dir2_leaf_entry * +xfs_dir3_leaf_find_entry( + struct xfs_dir3_icleaf_hdr *leafhdr, + struct xfs_dir2_leaf_entry *ents, + int index, /* leaf table position */ + int compact, /* need to compact leaves */ + int lowstale, /* index of prev stale leaf */ + int highstale, /* index of next stale leaf */ + int *lfloglow, /* low leaf logging index */ + int *lfloghigh) /* high leaf logging index */ +{ + if (!leafhdr->stale) { + xfs_dir2_leaf_entry_t *lep; /* leaf entry table pointer */ + + /* + * Now we need to make room to insert the leaf entry. + * + * If there are no stale entries, just insert a hole at index. + */ + lep = &ents[index]; + if (index < leafhdr->count) + memmove(lep + 1, lep, + (leafhdr->count - index) * sizeof(*lep)); + + /* + * Record low and high logging indices for the leaf. + */ + *lfloglow = index; + *lfloghigh = leafhdr->count++; + return lep; + } + + /* + * There are stale entries. + * + * We will use one of them for the new entry. It's probably not at + * the right location, so we'll have to shift some up or down first. + * + * If we didn't compact before, we need to find the nearest stale + * entries before and after our insertion point. + */ + if (compact == 0) + xfs_dir3_leaf_find_stale(leafhdr, ents, index, + &lowstale, &highstale); + + /* + * If the low one is better, use it. + */ + if (lowstale >= 0 && + (highstale == leafhdr->count || + index - lowstale - 1 < highstale - index)) { + ASSERT(index - lowstale - 1 >= 0); + ASSERT(ents[lowstale].address == + cpu_to_be32(XFS_DIR2_NULL_DATAPTR)); + + /* + * Copy entries up to cover the stale entry and make room + * for the new entry. + */ + if (index - lowstale - 1 > 0) { + memmove(&ents[lowstale], &ents[lowstale + 1], + (index - lowstale - 1) * + sizeof(xfs_dir2_leaf_entry_t)); + } + *lfloglow = MIN(lowstale, *lfloglow); + *lfloghigh = MAX(index - 1, *lfloghigh); + leafhdr->stale--; + return &ents[index - 1]; + } + + /* + * The high one is better, so use that one. + */ + ASSERT(highstale - index >= 0); + ASSERT(ents[highstale].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)); + + /* + * Copy entries down to cover the stale entry and make room for the + * new entry. + */ + if (highstale - index > 0) { + memmove(&ents[index + 1], &ents[index], + (highstale - index) * sizeof(xfs_dir2_leaf_entry_t)); + } + *lfloglow = MIN(index, *lfloglow); + *lfloghigh = MAX(highstale, *lfloghigh); + leafhdr->stale--; + return &ents[index]; +} + /* * Add an entry to a leaf form directory. */ @@ -140,8 +633,8 @@ { __be16 *bestsp; /* freespace table in leaf */ int compact; /* need to compact leaves */ - xfs_dir2_data_t *data; /* data block structure */ - xfs_dabuf_t *dbp; /* data block buffer */ + xfs_dir2_data_hdr_t *hdr; /* data block header */ + struct xfs_buf *dbp; /* data block buffer */ xfs_dir2_data_entry_t *dep; /* data block entry */ xfs_inode_t *dp; /* incore directory inode */ xfs_dir2_data_unused_t *dup; /* data unused entry */ @@ -150,7 +643,7 @@ int highstale; /* index of next stale leaf */ int i; /* temporary, index */ int index; /* leaf table position */ - xfs_dabuf_t *lbp; /* leaf's buffer */ + struct xfs_buf *lbp; /* leaf's buffer */ xfs_dir2_leaf_t *leaf; /* leaf structure */ int length; /* length of new entry */ xfs_dir2_leaf_entry_t *lep; /* leaf entry table pointer */ @@ -165,21 +658,20 @@ __be16 *tagp; /* end of data entry */ xfs_trans_t *tp; /* transaction pointer */ xfs_dir2_db_t use_block; /* data block number */ + struct xfs_dir2_data_free *bf; /* bestfree table */ + struct xfs_dir2_leaf_entry *ents; + struct xfs_dir3_icleaf_hdr leafhdr; trace_xfs_dir2_leaf_addname(args); dp = args->dp; tp = args->trans; mp = dp->i_mount; - /* - * Read the leaf block. - */ - error = xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp, - XFS_DATA_FORK); - if (error) { + + error = xfs_dir3_leaf_read(tp, dp, mp->m_dirleafblk, -1, &lbp); + if (error) return error; - } - ASSERT(lbp != NULL); + /* * Look up the entry by hash value and name. * We know it's not there, our caller has already done a lookup. @@ -187,24 +679,27 @@ * But if there are dup hash values the index is of the first of those. */ index = xfs_dir2_leaf_search_hash(args, lbp); - leaf = lbp->data; + leaf = lbp->b_addr; ltp = xfs_dir2_leaf_tail_p(mp, leaf); + ents = xfs_dir3_leaf_ents_p(leaf); + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); bestsp = xfs_dir2_leaf_bests_p(ltp); - length = xfs_dir2_data_entsize(args->namelen); + length = xfs_dir3_data_entsize(mp, args->namelen); + /* * See if there are any entries with the same hash value * and space in their block for the new entry. * This is good because it puts multiple same-hash value entries * in a data block, improving the lookup of those entries. */ - for (use_block = -1, lep = &leaf->ents[index]; - index < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(lep->hashval) == args->hashval; + for (use_block = -1, lep = &ents[index]; + index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval; index++, lep++) { if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) continue; i = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); ASSERT(i < be32_to_cpu(ltp->bestcount)); - ASSERT(be16_to_cpu(bestsp[i]) != NULLDATAOFF); + ASSERT(bestsp[i] != cpu_to_be16(NULLDATAOFF)); if (be16_to_cpu(bestsp[i]) >= length) { use_block = i; break; @@ -218,7 +713,8 @@ /* * Remember a block we see that's missing. */ - if (be16_to_cpu(bestsp[i]) == NULLDATAOFF && use_block == -1) + if (bestsp[i] == cpu_to_be16(NULLDATAOFF) && + use_block == -1) use_block = i; else if (be16_to_cpu(bestsp[i]) >= length) { use_block = i; @@ -229,42 +725,43 @@ /* * How many bytes do we need in the leaf block? */ - needbytes = - (leaf->hdr.stale ? 0 : (uint)sizeof(leaf->ents[0])) + - (use_block != -1 ? 0 : (uint)sizeof(leaf->bests[0])); + needbytes = 0; + if (!leafhdr.stale) + needbytes += sizeof(xfs_dir2_leaf_entry_t); + if (use_block == -1) + needbytes += sizeof(xfs_dir2_data_off_t); + /* * Now kill use_block if it refers to a missing block, so we * can use it as an indication of allocation needed. */ - if (use_block != -1 && be16_to_cpu(bestsp[use_block]) == NULLDATAOFF) + if (use_block != -1 && bestsp[use_block] == cpu_to_be16(NULLDATAOFF)) use_block = -1; /* * If we don't have enough free bytes but we can make enough * by compacting out stale entries, we'll do that. */ - if ((char *)bestsp - (char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] < - needbytes && be16_to_cpu(leaf->hdr.stale) > 1) { + if ((char *)bestsp - (char *)&ents[leafhdr.count] < needbytes && + leafhdr.stale > 1) compact = 1; - } + /* * Otherwise if we don't have enough free bytes we need to * convert to node form. */ - else if ((char *)bestsp - (char *)&leaf->ents[be16_to_cpu( - leaf->hdr.count)] < needbytes) { + else if ((char *)bestsp - (char *)&ents[leafhdr.count] < needbytes) { /* * Just checking or no space reservation, give up. */ if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || args->total == 0) { - xfs_da_brelse(tp, lbp); + xfs_trans_brelse(tp, lbp); return XFS_ERROR(ENOSPC); } /* * Convert to node form. */ error = xfs_dir2_leaf_to_node(args, lbp); - xfs_da_buf_done(lbp); if (error) return error; /* @@ -282,7 +779,7 @@ * a new data block. */ if (args->op_flags & XFS_DA_OP_JUSTCHECK) { - xfs_da_brelse(tp, lbp); + xfs_trans_brelse(tp, lbp); return use_block == -1 ? XFS_ERROR(ENOSPC) : 0; } /* @@ -290,7 +787,7 @@ * changed anything. */ if (args->total == 0 && use_block == -1) { - xfs_da_brelse(tp, lbp); + xfs_trans_brelse(tp, lbp); return XFS_ERROR(ENOSPC); } /* @@ -300,15 +797,15 @@ * point later. */ if (compact) { - xfs_dir2_leaf_compact_x1(lbp, &index, &lowstale, &highstale, - &lfloglow, &lfloghigh); + xfs_dir3_leaf_compact_x1(&leafhdr, ents, &index, &lowstale, + &highstale, &lfloglow, &lfloghigh); } /* * There are stale entries, so we'll need log-low and log-high * impossibly bad values later. */ - else if (be16_to_cpu(leaf->hdr.stale)) { - lfloglow = be16_to_cpu(leaf->hdr.count); + else if (leafhdr.stale) { + lfloglow = leafhdr.count; lfloghigh = -1; } /* @@ -321,14 +818,14 @@ */ if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, &use_block))) { - xfs_da_brelse(tp, lbp); + xfs_trans_brelse(tp, lbp); return error; } /* * Initialize the block. */ - if ((error = xfs_dir2_data_init(args, use_block, &dbp))) { - xfs_da_brelse(tp, lbp); + if ((error = xfs_dir3_data_init(args, use_block, &dbp))) { + xfs_trans_brelse(tp, lbp); return error; } /* @@ -340,45 +837,46 @@ memmove(&bestsp[0], &bestsp[1], be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0])); be32_add_cpu(<p->bestcount, 1); - xfs_dir2_leaf_log_tail(tp, lbp); - xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); + xfs_dir3_leaf_log_tail(tp, lbp); + xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); } /* * If we're filling in a previously empty block just log it. */ else - xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); - data = dbp->data; - bestsp[use_block] = data->hdr.bestfree[0].length; + xfs_dir3_leaf_log_bests(tp, lbp, use_block, use_block); + hdr = dbp->b_addr; + bf = xfs_dir3_data_bestfree_p(hdr); + bestsp[use_block] = bf[0].length; grown = 1; - } - /* - * Already had space in some data block. - * Just read that one in. - */ - else { - if ((error = - xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, use_block), - -1, &dbp, XFS_DATA_FORK))) { - xfs_da_brelse(tp, lbp); + } else { + /* + * Already had space in some data block. + * Just read that one in. + */ + error = xfs_dir3_data_read(tp, dp, + xfs_dir2_db_to_da(mp, use_block), + -1, &dbp); + if (error) { + xfs_trans_brelse(tp, lbp); return error; } - data = dbp->data; + hdr = dbp->b_addr; + bf = xfs_dir3_data_bestfree_p(hdr); grown = 0; } - xfs_dir2_data_check(dp, dbp); /* * Point to the biggest freespace in our data block. */ dup = (xfs_dir2_data_unused_t *) - ((char *)data + be16_to_cpu(data->hdr.bestfree[0].offset)); + ((char *)hdr + be16_to_cpu(bf[0].offset)); ASSERT(be16_to_cpu(dup->length) >= length); needscan = needlog = 0; /* * Mark the initial part of our freespace in use for the new entry. */ xfs_dir2_data_use_free(tp, dbp, dup, - (xfs_dir2_data_aoff_t)((char *)dup - (char *)data), length, + (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length, &needlog, &needscan); /* * Initialize our new entry (at last). @@ -387,13 +885,14 @@ dep->inumber = cpu_to_be64(args->inumber); dep->namelen = args->namelen; memcpy(dep->name, args->name, dep->namelen); - tagp = xfs_dir2_data_entry_tag_p(dep); - *tagp = cpu_to_be16((char *)dep - (char *)data); + xfs_dir3_dirent_put_ftype(mp, dep, args->filetype); + tagp = xfs_dir3_data_entry_tag_p(mp, dep); + *tagp = cpu_to_be16((char *)dep - (char *)hdr); /* * Need to scan fix up the bestfree table. */ if (needscan) - xfs_dir2_data_freescan(mp, data, &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); /* * Need to log the data block's header. */ @@ -404,107 +903,15 @@ * If the bests table needs to be changed, do it. * Log the change unless we've already done that. */ - if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(data->hdr.bestfree[0].length)) { - bestsp[use_block] = data->hdr.bestfree[0].length; + if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(bf[0].length)) { + bestsp[use_block] = bf[0].length; if (!grown) - xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); - } - /* - * Now we need to make room to insert the leaf entry. - * If there are no stale entries, we just insert a hole at index. - */ - if (!leaf->hdr.stale) { - /* - * lep is still good as the index leaf entry. - */ - if (index < be16_to_cpu(leaf->hdr.count)) - memmove(lep + 1, lep, - (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep)); - /* - * Record low and high logging indices for the leaf. - */ - lfloglow = index; - lfloghigh = be16_to_cpu(leaf->hdr.count); - be16_add_cpu(&leaf->hdr.count, 1); - } - /* - * There are stale entries. - * We will use one of them for the new entry. - * It's probably not at the right location, so we'll have to - * shift some up or down first. - */ - else { - /* - * If we didn't compact before, we need to find the nearest - * stale entries before and after our insertion point. - */ - if (compact == 0) { - /* - * Find the first stale entry before the insertion - * point, if any. - */ - for (lowstale = index - 1; - lowstale >= 0 && - be32_to_cpu(leaf->ents[lowstale].address) != - XFS_DIR2_NULL_DATAPTR; - lowstale--) - continue; - /* - * Find the next stale entry at or after the insertion - * point, if any. Stop if we go so far that the - * lowstale entry would be better. - */ - for (highstale = index; - highstale < be16_to_cpu(leaf->hdr.count) && - be32_to_cpu(leaf->ents[highstale].address) != - XFS_DIR2_NULL_DATAPTR && - (lowstale < 0 || - index - lowstale - 1 >= highstale - index); - highstale++) - continue; - } - /* - * If the low one is better, use it. - */ - if (lowstale >= 0 && - (highstale == be16_to_cpu(leaf->hdr.count) || - index - lowstale - 1 < highstale - index)) { - ASSERT(index - lowstale - 1 >= 0); - ASSERT(be32_to_cpu(leaf->ents[lowstale].address) == - XFS_DIR2_NULL_DATAPTR); - /* - * Copy entries up to cover the stale entry - * and make room for the new entry. - */ - if (index - lowstale - 1 > 0) - memmove(&leaf->ents[lowstale], - &leaf->ents[lowstale + 1], - (index - lowstale - 1) * sizeof(*lep)); - lep = &leaf->ents[index - 1]; - lfloglow = MIN(lowstale, lfloglow); - lfloghigh = MAX(index - 1, lfloghigh); - } - /* - * The high one is better, so use that one. - */ - else { - ASSERT(highstale - index >= 0); - ASSERT(be32_to_cpu(leaf->ents[highstale].address) == - XFS_DIR2_NULL_DATAPTR); - /* - * Copy entries down to cover the stale entry - * and make room for the new entry. - */ - if (highstale - index > 0) - memmove(&leaf->ents[index + 1], - &leaf->ents[index], - (highstale - index) * sizeof(*lep)); - lep = &leaf->ents[index]; - lfloglow = MIN(index, lfloglow); - lfloghigh = MAX(highstale, lfloghigh); - } - be16_add_cpu(&leaf->hdr.stale, -1); + xfs_dir3_leaf_log_bests(tp, lbp, use_block, use_block); } + + lep = xfs_dir3_leaf_find_entry(&leafhdr, ents, index, compact, lowstale, + highstale, &lfloglow, &lfloghigh); + /* * Fill in the new leaf entry. */ @@ -514,83 +921,40 @@ /* * Log the leaf fields and give up the buffers. */ - xfs_dir2_leaf_log_header(tp, lbp); - xfs_dir2_leaf_log_ents(tp, lbp, lfloglow, lfloghigh); - xfs_dir2_leaf_check(dp, lbp); - xfs_da_buf_done(lbp); - xfs_dir2_data_check(dp, dbp); - xfs_da_buf_done(dbp); + xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr); + xfs_dir3_leaf_log_header(tp, lbp); + xfs_dir3_leaf_log_ents(tp, lbp, lfloglow, lfloghigh); + xfs_dir3_leaf_check(mp, lbp); + xfs_dir3_data_check(dp, dbp); return 0; } -#ifdef DEBUG -/* - * Check the internal consistency of a leaf1 block. - * Pop an assert if something is wrong. - */ -STATIC void -xfs_dir2_leaf_check( - xfs_inode_t *dp, /* incore directory inode */ - xfs_dabuf_t *bp) /* leaf's buffer */ -{ - int i; /* leaf index */ - xfs_dir2_leaf_t *leaf; /* leaf structure */ - xfs_dir2_leaf_tail_t *ltp; /* leaf tail pointer */ - xfs_mount_t *mp; /* filesystem mount point */ - int stale; /* count of stale leaves */ - - leaf = bp->data; - mp = dp->i_mount; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); - /* - * This value is not restrictive enough. - * Should factor in the size of the bests table as well. - * We can deduce a value for that from di_size. - */ - ASSERT(be16_to_cpu(leaf->hdr.count) <= xfs_dir2_max_leaf_ents(mp)); - ltp = xfs_dir2_leaf_tail_p(mp, leaf); - /* - * Leaves and bests don't overlap. - */ - ASSERT((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] <= - (char *)xfs_dir2_leaf_bests_p(ltp)); - /* - * Check hash value order, count stale entries. - */ - for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) { - if (i + 1 < be16_to_cpu(leaf->hdr.count)) - ASSERT(be32_to_cpu(leaf->ents[i].hashval) <= - be32_to_cpu(leaf->ents[i + 1].hashval)); - if (be32_to_cpu(leaf->ents[i].address) == XFS_DIR2_NULL_DATAPTR) - stale++; - } - ASSERT(be16_to_cpu(leaf->hdr.stale) == stale); -} -#endif /* DEBUG */ - /* * Compact out any stale entries in the leaf. * Log the header and changed leaf entries, if any. */ void -xfs_dir2_leaf_compact( +xfs_dir3_leaf_compact( xfs_da_args_t *args, /* operation arguments */ - xfs_dabuf_t *bp) /* leaf buffer */ + struct xfs_dir3_icleaf_hdr *leafhdr, + struct xfs_buf *bp) /* leaf buffer */ { int from; /* source leaf index */ xfs_dir2_leaf_t *leaf; /* leaf structure */ int loglow; /* first leaf entry to log */ int to; /* target leaf index */ + struct xfs_dir2_leaf_entry *ents; - leaf = bp->data; - if (!leaf->hdr.stale) { + leaf = bp->b_addr; + if (!leafhdr->stale) return; - } + /* * Compress out the stale entries in place. */ - for (from = to = 0, loglow = -1; from < be16_to_cpu(leaf->hdr.count); from++) { - if (be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) + ents = xfs_dir3_leaf_ents_p(leaf); + for (from = to = 0, loglow = -1; from < leafhdr->count; from++) { + if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) continue; /* * Only actually copy the entries that are different. @@ -598,19 +962,21 @@ if (from > to) { if (loglow == -1) loglow = to; - leaf->ents[to] = leaf->ents[from]; + ents[to] = ents[from]; } to++; } /* * Update and log the header, log the leaf entries. */ - ASSERT(be16_to_cpu(leaf->hdr.stale) == from - to); - be16_add_cpu(&leaf->hdr.count, -(be16_to_cpu(leaf->hdr.stale))); - leaf->hdr.stale = 0; - xfs_dir2_leaf_log_header(args->trans, bp); + ASSERT(leafhdr->stale == from - to); + leafhdr->count -= leafhdr->stale; + leafhdr->stale = 0; + + xfs_dir3_leaf_hdr_to_disk(leaf, leafhdr); + xfs_dir3_leaf_log_header(args->trans, bp); if (loglow != -1) - xfs_dir2_leaf_log_ents(args->trans, bp, loglow, to - 1); + xfs_dir3_leaf_log_ents(args->trans, bp, loglow, to - 1); } /* @@ -622,8 +988,9 @@ * and leaf logging indices. */ void -xfs_dir2_leaf_compact_x1( - xfs_dabuf_t *bp, /* leaf buffer */ +xfs_dir3_leaf_compact_x1( + struct xfs_dir3_icleaf_hdr *leafhdr, + struct xfs_dir2_leaf_entry *ents, int *indexp, /* insertion index */ int *lowstalep, /* out: stale entry before us */ int *highstalep, /* out: stale entry after us */ @@ -634,37 +1001,20 @@ int highstale; /* stale entry at/after index */ int index; /* insertion index */ int keepstale; /* source index of kept stale */ - xfs_dir2_leaf_t *leaf; /* leaf structure */ int lowstale; /* stale entry before index */ int newindex=0; /* new insertion index */ int to; /* destination copy index */ - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.stale) > 1); + ASSERT(leafhdr->stale > 1); index = *indexp; - /* - * Find the first stale entry before our index, if any. - */ - for (lowstale = index - 1; - lowstale >= 0 && - be32_to_cpu(leaf->ents[lowstale].address) != XFS_DIR2_NULL_DATAPTR; - lowstale--) - continue; - /* - * Find the first stale entry at or after our index, if any. - * Stop if the answer would be worse than lowstale. - */ - for (highstale = index; - highstale < be16_to_cpu(leaf->hdr.count) && - be32_to_cpu(leaf->ents[highstale].address) != XFS_DIR2_NULL_DATAPTR && - (lowstale < 0 || index - lowstale > highstale - index); - highstale++) - continue; + + xfs_dir3_leaf_find_stale(leafhdr, ents, index, &lowstale, &highstale); + /* * Pick the better of lowstale and highstale. */ if (lowstale >= 0 && - (highstale == be16_to_cpu(leaf->hdr.count) || + (highstale == leafhdr->count || index - lowstale <= highstale - index)) keepstale = lowstale; else @@ -673,14 +1023,14 @@ * Copy the entries in place, removing all the stale entries * except keepstale. */ - for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) { + for (from = to = 0; from < leafhdr->count; from++) { /* * Notice the new value of index. */ if (index == from) newindex = to; if (from != keepstale && - be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) { + ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) { if (from == to) *lowlogp = to; continue; @@ -694,7 +1044,7 @@ * Copy only the entries that have moved. */ if (from > to) - leaf->ents[to] = leaf->ents[from]; + ents[to] = ents[from]; to++; } ASSERT(from > to); @@ -708,8 +1058,8 @@ /* * Adjust the leaf header values. */ - be16_add_cpu(&leaf->hdr.count, -(from - to)); - leaf->hdr.stale = cpu_to_be16(1); + leafhdr->count -= from - to; + leafhdr->stale = 1; /* * Remember the low/high stale value only in the "right" * direction. @@ -717,90 +1067,34 @@ if (lowstale >= newindex) lowstale = -1; else - highstale = be16_to_cpu(leaf->hdr.count); - *highlogp = be16_to_cpu(leaf->hdr.count) - 1; + highstale = leafhdr->count; + *highlogp = leafhdr->count - 1; *lowstalep = lowstale; *highstalep = highstale; } /* - * Initialize a new leaf block, leaf1 or leafn magic accepted. - */ -int -xfs_dir2_leaf_init( - xfs_da_args_t *args, /* operation arguments */ - xfs_dir2_db_t bno, /* directory block number */ - xfs_dabuf_t **bpp, /* out: leaf buffer */ - int magic) /* magic number for block */ -{ - xfs_dabuf_t *bp; /* leaf buffer */ - xfs_inode_t *dp; /* incore directory inode */ - int error; /* error return code */ - xfs_dir2_leaf_t *leaf; /* leaf structure */ - xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ - xfs_mount_t *mp; /* filesystem mount point */ - xfs_trans_t *tp; /* transaction pointer */ - - dp = args->dp; - ASSERT(dp != NULL); - tp = args->trans; - mp = dp->i_mount; - ASSERT(bno >= XFS_DIR2_LEAF_FIRSTDB(mp) && - bno < XFS_DIR2_FREE_FIRSTDB(mp)); - /* - * Get the buffer for the block. - */ - error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, bno), -1, &bp, - XFS_DATA_FORK); - if (error) { - return error; - } - ASSERT(bp != NULL); - leaf = bp->data; - /* - * Initialize the header. - */ - leaf->hdr.info.magic = cpu_to_be16(magic); - leaf->hdr.info.forw = 0; - leaf->hdr.info.back = 0; - leaf->hdr.count = 0; - leaf->hdr.stale = 0; - xfs_dir2_leaf_log_header(tp, bp); - /* - * If it's a leaf-format directory initialize the tail. - * In this case our caller has the real bests table to copy into - * the block. - */ - if (magic == XFS_DIR2_LEAF1_MAGIC) { - ltp = xfs_dir2_leaf_tail_p(mp, leaf); - ltp->bestcount = 0; - xfs_dir2_leaf_log_tail(tp, bp); - } - *bpp = bp; - return 0; -} - -/* * Log the bests entries indicated from a leaf1 block. */ static void -xfs_dir2_leaf_log_bests( +xfs_dir3_leaf_log_bests( xfs_trans_t *tp, /* transaction pointer */ - xfs_dabuf_t *bp, /* leaf buffer */ + struct xfs_buf *bp, /* leaf buffer */ int first, /* first entry to log */ int last) /* last entry to log */ { __be16 *firstb; /* pointer to first entry */ __be16 *lastb; /* pointer to last entry */ - xfs_dir2_leaf_t *leaf; /* leaf structure */ + struct xfs_dir2_leaf *leaf = bp->b_addr; xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); + ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || + leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC)); + ltp = xfs_dir2_leaf_tail_p(tp->t_mountp, leaf); firstb = xfs_dir2_leaf_bests_p(ltp) + first; lastb = xfs_dir2_leaf_bests_p(ltp) + last; - xfs_da_log_buf(tp, bp, (uint)((char *)firstb - (char *)leaf), + xfs_trans_log_buf(tp, bp, (uint)((char *)firstb - (char *)leaf), (uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1)); } @@ -808,22 +1102,26 @@ * Log the leaf entries indicated from a leaf1 or leafn block. */ void -xfs_dir2_leaf_log_ents( +xfs_dir3_leaf_log_ents( xfs_trans_t *tp, /* transaction pointer */ - xfs_dabuf_t *bp, /* leaf buffer */ + struct xfs_buf *bp, /* leaf buffer */ int first, /* first entry to log */ int last) /* last entry to log */ { xfs_dir2_leaf_entry_t *firstlep; /* pointer to first entry */ xfs_dir2_leaf_entry_t *lastlep; /* pointer to last entry */ - xfs_dir2_leaf_t *leaf; /* leaf structure */ + struct xfs_dir2_leaf *leaf = bp->b_addr; + struct xfs_dir2_leaf_entry *ents; - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC || - be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); - firstlep = &leaf->ents[first]; - lastlep = &leaf->ents[last]; - xfs_da_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf), + ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || + leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) || + leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || + leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)); + + ents = xfs_dir3_leaf_ents_p(leaf); + firstlep = &ents[first]; + lastlep = &ents[last]; + xfs_trans_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf), (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1)); } @@ -831,36 +1129,40 @@ * Log the header of the leaf1 or leafn block. */ void -xfs_dir2_leaf_log_header( - xfs_trans_t *tp, /* transaction pointer */ - xfs_dabuf_t *bp) /* leaf buffer */ +xfs_dir3_leaf_log_header( + struct xfs_trans *tp, + struct xfs_buf *bp) { - xfs_dir2_leaf_t *leaf; /* leaf structure */ + struct xfs_dir2_leaf *leaf = bp->b_addr; + + ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || + leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) || + leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || + leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)); - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC || - be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); - xfs_da_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf), - (uint)(sizeof(leaf->hdr) - 1)); + xfs_trans_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf), + xfs_dir3_leaf_hdr_size(leaf) - 1); } /* * Log the tail of the leaf1 block. */ STATIC void -xfs_dir2_leaf_log_tail( - xfs_trans_t *tp, /* transaction pointer */ - xfs_dabuf_t *bp) /* leaf buffer */ +xfs_dir3_leaf_log_tail( + struct xfs_trans *tp, + struct xfs_buf *bp) { - xfs_dir2_leaf_t *leaf; /* leaf structure */ + struct xfs_dir2_leaf *leaf = bp->b_addr; xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ - xfs_mount_t *mp; /* filesystem mount point */ + struct xfs_mount *mp = tp->t_mountp; + + ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || + leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) || + leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || + leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)); - mp = tp->t_mountp; - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); ltp = xfs_dir2_leaf_tail_p(mp, leaf); - xfs_da_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf), + xfs_trans_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf), (uint)(mp->m_dirblksize - 1)); } @@ -873,15 +1175,16 @@ xfs_dir2_leaf_lookup( xfs_da_args_t *args) /* operation arguments */ { - xfs_dabuf_t *dbp; /* data block buffer */ + struct xfs_buf *dbp; /* data block buffer */ xfs_dir2_data_entry_t *dep; /* data block entry */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return code */ int index; /* found entry index */ - xfs_dabuf_t *lbp; /* leaf buffer */ + struct xfs_buf *lbp; /* leaf buffer */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_trans_t *tp; /* transaction pointer */ + struct xfs_dir2_leaf_entry *ents; trace_xfs_dir2_leaf_lookup(args); @@ -893,25 +1196,28 @@ } tp = args->trans; dp = args->dp; - xfs_dir2_leaf_check(dp, lbp); - leaf = lbp->data; + xfs_dir3_leaf_check(dp->i_mount, lbp); + leaf = lbp->b_addr; + ents = xfs_dir3_leaf_ents_p(leaf); /* * Get to the leaf entry and contained data entry address. */ - lep = &leaf->ents[index]; + lep = &ents[index]; + /* * Point to the data entry. */ dep = (xfs_dir2_data_entry_t *) - ((char *)dbp->data + + ((char *)dbp->b_addr + xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address))); /* * Return the found inode number & CI name if appropriate */ args->inumber = be64_to_cpu(dep->inumber); + args->filetype = xfs_dir3_dirent_get_ftype(dp->i_mount, dep); error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); - xfs_da_brelse(tp, dbp); - xfs_da_brelse(tp, lbp); + xfs_trans_brelse(tp, dbp); + xfs_trans_brelse(tp, lbp); return XFS_ERROR(error); } @@ -924,17 +1230,17 @@ static int /* error */ xfs_dir2_leaf_lookup_int( xfs_da_args_t *args, /* operation arguments */ - xfs_dabuf_t **lbpp, /* out: leaf buffer */ + struct xfs_buf **lbpp, /* out: leaf buffer */ int *indexp, /* out: index in leaf block */ - xfs_dabuf_t **dbpp) /* out: data buffer */ + struct xfs_buf **dbpp) /* out: data buffer */ { xfs_dir2_db_t curdb = -1; /* current data block number */ - xfs_dabuf_t *dbp = NULL; /* data buffer */ + struct xfs_buf *dbp = NULL; /* data buffer */ xfs_dir2_data_entry_t *dep; /* data entry */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return code */ int index; /* index in leaf block */ - xfs_dabuf_t *lbp; /* leaf buffer */ + struct xfs_buf *lbp; /* leaf buffer */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_mount_t *mp; /* filesystem mount point */ @@ -942,20 +1248,23 @@ xfs_trans_t *tp; /* transaction pointer */ xfs_dir2_db_t cidb = -1; /* case match data block no. */ enum xfs_dacmp cmp; /* name compare result */ + struct xfs_dir2_leaf_entry *ents; + struct xfs_dir3_icleaf_hdr leafhdr; dp = args->dp; tp = args->trans; mp = dp->i_mount; - /* - * Read the leaf block into the buffer. - */ - error = xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp, - XFS_DATA_FORK); + + error = xfs_dir3_leaf_read(tp, dp, mp->m_dirleafblk, -1, &lbp); if (error) return error; + *lbpp = lbp; - leaf = lbp->data; - xfs_dir2_leaf_check(dp, lbp); + leaf = lbp->b_addr; + xfs_dir3_leaf_check(mp, lbp); + ents = xfs_dir3_leaf_ents_p(leaf); + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + /* * Look for the first leaf entry with our hash value. */ @@ -964,9 +1273,9 @@ * Loop over all the entries with the right hash value * looking to match the name. */ - for (lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) && - be32_to_cpu(lep->hashval) == args->hashval; - lep++, index++) { + for (lep = &ents[index]; + index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval; + lep++, index++) { /* * Skip over stale leaf entries. */ @@ -982,21 +1291,20 @@ */ if (newdb != curdb) { if (dbp) - xfs_da_brelse(tp, dbp); - error = xfs_da_read_buf(tp, dp, - xfs_dir2_db_to_da(mp, newdb), - -1, &dbp, XFS_DATA_FORK); + xfs_trans_brelse(tp, dbp); + error = xfs_dir3_data_read(tp, dp, + xfs_dir2_db_to_da(mp, newdb), + -1, &dbp); if (error) { - xfs_da_brelse(tp, lbp); + xfs_trans_brelse(tp, lbp); return error; } - xfs_dir2_data_check(dp, dbp); curdb = newdb; } /* * Point to the data entry. */ - dep = (xfs_dir2_data_entry_t *)((char *)dbp->data + + dep = (xfs_dir2_data_entry_t *)((char *)dbp->b_addr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); /* * Compare name and if it's an exact match, return the index @@ -1024,12 +1332,12 @@ if (args->cmpresult == XFS_CMP_CASE) { ASSERT(cidb != -1); if (cidb != curdb) { - xfs_da_brelse(tp, dbp); - error = xfs_da_read_buf(tp, dp, - xfs_dir2_db_to_da(mp, cidb), - -1, &dbp, XFS_DATA_FORK); + xfs_trans_brelse(tp, dbp); + error = xfs_dir3_data_read(tp, dp, + xfs_dir2_db_to_da(mp, cidb), + -1, &dbp); if (error) { - xfs_da_brelse(tp, lbp); + xfs_trans_brelse(tp, lbp); return error; } } @@ -1041,8 +1349,8 @@ */ ASSERT(cidb == -1); if (dbp) - xfs_da_brelse(tp, dbp); - xfs_da_brelse(tp, lbp); + xfs_trans_brelse(tp, dbp); + xfs_trans_brelse(tp, lbp); return XFS_ERROR(ENOENT); } @@ -1054,15 +1362,15 @@ xfs_da_args_t *args) /* operation arguments */ { __be16 *bestsp; /* leaf block best freespace */ - xfs_dir2_data_t *data; /* data block structure */ + xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_db_t db; /* data block number */ - xfs_dabuf_t *dbp; /* data block buffer */ + struct xfs_buf *dbp; /* data block buffer */ xfs_dir2_data_entry_t *dep; /* data entry structure */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return code */ xfs_dir2_db_t i; /* temporary data block # */ int index; /* index into leaf entries */ - xfs_dabuf_t *lbp; /* leaf buffer */ + struct xfs_buf *lbp; /* leaf buffer */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ @@ -1071,6 +1379,9 @@ int needscan; /* need to rescan data frees */ xfs_dir2_data_off_t oldbest; /* old value of best free */ xfs_trans_t *tp; /* transaction pointer */ + struct xfs_dir2_data_free *bf; /* bestfree table */ + struct xfs_dir2_leaf_entry *ents; + struct xfs_dir3_icleaf_hdr leafhdr; trace_xfs_dir2_leaf_removename(args); @@ -1083,18 +1394,21 @@ dp = args->dp; tp = args->trans; mp = dp->i_mount; - leaf = lbp->data; - data = dbp->data; - xfs_dir2_data_check(dp, dbp); + leaf = lbp->b_addr; + hdr = dbp->b_addr; + xfs_dir3_data_check(dp, dbp); + bf = xfs_dir3_data_bestfree_p(hdr); + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + ents = xfs_dir3_leaf_ents_p(leaf); /* * Point to the leaf entry, use that to point to the data entry. */ - lep = &leaf->ents[index]; + lep = &ents[index]; db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); dep = (xfs_dir2_data_entry_t *) - ((char *)data + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); + ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); needscan = needlog = 0; - oldbest = be16_to_cpu(data->hdr.bestfree[0].length); + oldbest = be16_to_cpu(bf[0].length); ltp = xfs_dir2_leaf_tail_p(mp, leaf); bestsp = xfs_dir2_leaf_bests_p(ltp); ASSERT(be16_to_cpu(bestsp[db]) == oldbest); @@ -1102,37 +1416,40 @@ * Mark the former data entry unused. */ xfs_dir2_data_make_free(tp, dbp, - (xfs_dir2_data_aoff_t)((char *)dep - (char *)data), - xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); + (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr), + xfs_dir3_data_entsize(mp, dep->namelen), &needlog, &needscan); /* * We just mark the leaf entry stale by putting a null in it. */ - be16_add_cpu(&leaf->hdr.stale, 1); - xfs_dir2_leaf_log_header(tp, lbp); + leafhdr.stale++; + xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr); + xfs_dir3_leaf_log_header(tp, lbp); + lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); - xfs_dir2_leaf_log_ents(tp, lbp, index, index); + xfs_dir3_leaf_log_ents(tp, lbp, index, index); + /* * Scan the freespace in the data block again if necessary, * log the data block header if necessary. */ if (needscan) - xfs_dir2_data_freescan(mp, data, &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); if (needlog) xfs_dir2_data_log_header(tp, dbp); /* * If the longest freespace in the data block has changed, * put the new value in the bests table and log that. */ - if (be16_to_cpu(data->hdr.bestfree[0].length) != oldbest) { - bestsp[db] = data->hdr.bestfree[0].length; - xfs_dir2_leaf_log_bests(tp, lbp, db, db); + if (be16_to_cpu(bf[0].length) != oldbest) { + bestsp[db] = bf[0].length; + xfs_dir3_leaf_log_bests(tp, lbp, db, db); } - xfs_dir2_data_check(dp, dbp); + xfs_dir3_data_check(dp, dbp); /* * If the data block is now empty then get rid of the data block. */ - if (be16_to_cpu(data->hdr.bestfree[0].length) == - mp->m_dirblksize - (uint)sizeof(data->hdr)) { + if (be16_to_cpu(bf[0].length) == + mp->m_dirblksize - xfs_dir3_data_entry_offset(hdr)) { ASSERT(db != mp->m_dirdatablk); if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { /* @@ -1141,12 +1458,9 @@ * Just go on, returning success, leaving the * empty block in place. */ - if (error == ENOSPC && args->total == 0) { - xfs_da_buf_done(dbp); + if (error == ENOSPC && args->total == 0) error = 0; - } - xfs_dir2_leaf_check(dp, lbp); - xfs_da_buf_done(lbp); + xfs_dir3_leaf_check(mp, lbp); return error; } dbp = NULL; @@ -1159,7 +1473,7 @@ * Look for the last active entry (i). */ for (i = db - 1; i > 0; i--) { - if (be16_to_cpu(bestsp[i]) != NULLDATAOFF) + if (bestsp[i] != cpu_to_be16(NULLDATAOFF)) break; } /* @@ -1169,19 +1483,18 @@ memmove(&bestsp[db - i], bestsp, (be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp)); be32_add_cpu(<p->bestcount, -(db - i)); - xfs_dir2_leaf_log_tail(tp, lbp); - xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); + xfs_dir3_leaf_log_tail(tp, lbp); + xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); } else bestsp[db] = cpu_to_be16(NULLDATAOFF); } /* * If the data block was not the first one, drop it. */ - else if (db != mp->m_dirdatablk && dbp != NULL) { - xfs_da_buf_done(dbp); + else if (db != mp->m_dirdatablk) dbp = NULL; - } - xfs_dir2_leaf_check(dp, lbp); + + xfs_dir3_leaf_check(mp, lbp); /* * See if we can convert to block form. */ @@ -1195,15 +1508,16 @@ xfs_dir2_leaf_replace( xfs_da_args_t *args) /* operation arguments */ { - xfs_dabuf_t *dbp; /* data block buffer */ + struct xfs_buf *dbp; /* data block buffer */ xfs_dir2_data_entry_t *dep; /* data block entry */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return code */ int index; /* index of leaf entry */ - xfs_dabuf_t *lbp; /* leaf buffer */ + struct xfs_buf *lbp; /* leaf buffer */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_trans_t *tp; /* transaction pointer */ + struct xfs_dir2_leaf_entry *ents; trace_xfs_dir2_leaf_replace(args); @@ -1214,27 +1528,28 @@ return error; } dp = args->dp; - leaf = lbp->data; + leaf = lbp->b_addr; + ents = xfs_dir3_leaf_ents_p(leaf); /* * Point to the leaf entry, get data address from it. */ - lep = &leaf->ents[index]; + lep = &ents[index]; /* * Point to the data entry. */ dep = (xfs_dir2_data_entry_t *) - ((char *)dbp->data + + ((char *)dbp->b_addr + xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address))); ASSERT(args->inumber != be64_to_cpu(dep->inumber)); /* * Put the new inode number in, log it. */ dep->inumber = cpu_to_be64(args->inumber); + xfs_dir3_dirent_put_ftype(dp->i_mount, dep, args->filetype); tp = args->trans; xfs_dir2_data_log_entry(tp, dbp, dep); - xfs_da_buf_done(dbp); - xfs_dir2_leaf_check(dp, lbp); - xfs_da_brelse(tp, lbp); + xfs_dir3_leaf_check(dp->i_mount, lbp); + xfs_trans_brelse(tp, lbp); return 0; } @@ -1246,7 +1561,7 @@ int /* index value */ xfs_dir2_leaf_search_hash( xfs_da_args_t *args, /* operation arguments */ - xfs_dabuf_t *lbp) /* leaf buffer */ + struct xfs_buf *lbp) /* leaf buffer */ { xfs_dahash_t hash=0; /* hash from this entry */ xfs_dahash_t hashwant; /* hash value looking for */ @@ -1255,17 +1570,18 @@ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ int mid=0; /* current leaf index */ + struct xfs_dir2_leaf_entry *ents; + struct xfs_dir3_icleaf_hdr leafhdr; + + leaf = lbp->b_addr; + ents = xfs_dir3_leaf_ents_p(leaf); + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); - leaf = lbp->data; -#ifndef __KERNEL__ - if (!leaf->hdr.count) - return 0; -#endif /* * Note, the table cannot be empty, so we have to go through the loop. * Binary search the leaf entries looking for our hash value. */ - for (lep = leaf->ents, low = 0, high = be16_to_cpu(leaf->hdr.count) - 1, + for (lep = ents, low = 0, high = leafhdr.count - 1, hashwant = args->hashval; low <= high; ) { mid = (low + high) >> 1; @@ -1299,14 +1615,11 @@ int /* error */ xfs_dir2_leaf_trim_data( xfs_da_args_t *args, /* operation arguments */ - xfs_dabuf_t *lbp, /* leaf buffer */ + struct xfs_buf *lbp, /* leaf buffer */ xfs_dir2_db_t db) /* data block number */ { __be16 *bestsp; /* leaf bests table */ -#ifdef DEBUG - xfs_dir2_data_t *data; /* data block structure */ -#endif - xfs_dabuf_t *dbp; /* data block buffer */ + struct xfs_buf *dbp; /* data block buffer */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return value */ xfs_dir2_leaf_t *leaf; /* leaf structure */ @@ -1320,30 +1633,32 @@ /* * Read the offending data block. We need its buffer. */ - if ((error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp, - XFS_DATA_FORK))) { + error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp); + if (error) return error; - } -#ifdef DEBUG - data = dbp->data; - ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC); -#endif - /* this seems to be an error - * data is only valid if DEBUG is defined? - * RMC 09/08/1999 - */ - leaf = lbp->data; + leaf = lbp->b_addr; ltp = xfs_dir2_leaf_tail_p(mp, leaf); - ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) == - mp->m_dirblksize - (uint)sizeof(data->hdr)); + +#ifdef DEBUG +{ + struct xfs_dir2_data_hdr *hdr = dbp->b_addr; + struct xfs_dir2_data_free *bf = xfs_dir3_data_bestfree_p(hdr); + + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)); + ASSERT(be16_to_cpu(bf[0].length) == + mp->m_dirblksize - xfs_dir3_data_entry_offset(hdr)); ASSERT(db == be32_to_cpu(ltp->bestcount) - 1); +} +#endif + /* * Get rid of the data block. */ if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { ASSERT(error != ENOSPC); - xfs_da_brelse(tp, dbp); + xfs_trans_brelse(tp, dbp); return error; } /* @@ -1352,11 +1667,31 @@ bestsp = xfs_dir2_leaf_bests_p(ltp); be32_add_cpu(<p->bestcount, -1); memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp)); - xfs_dir2_leaf_log_tail(tp, lbp); - xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); + xfs_dir3_leaf_log_tail(tp, lbp); + xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); return 0; } +static inline size_t +xfs_dir3_leaf_size( + struct xfs_dir3_icleaf_hdr *hdr, + int counts) +{ + int entries; + int hdrsize; + + entries = hdr->count - hdr->stale; + if (hdr->magic == XFS_DIR2_LEAF1_MAGIC || + hdr->magic == XFS_DIR2_LEAFN_MAGIC) + hdrsize = sizeof(struct xfs_dir2_leaf_hdr); + else + hdrsize = sizeof(struct xfs_dir3_leaf_hdr); + + return hdrsize + entries * sizeof(xfs_dir2_leaf_entry_t) + + counts * sizeof(xfs_dir2_data_off_t) + + sizeof(xfs_dir2_leaf_tail_t); +} + /* * Convert node form directory to leaf form directory. * The root of the node form dir needs to already be a LEAFN block. @@ -1369,15 +1704,17 @@ xfs_da_args_t *args; /* operation arguments */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return code */ - xfs_dabuf_t *fbp; /* buffer for freespace block */ + struct xfs_buf *fbp; /* buffer for freespace block */ xfs_fileoff_t fo; /* freespace file offset */ xfs_dir2_free_t *free; /* freespace structure */ - xfs_dabuf_t *lbp; /* buffer for leaf block */ + struct xfs_buf *lbp; /* buffer for leaf block */ xfs_dir2_leaf_tail_t *ltp; /* tail of leaf structure */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_mount_t *mp; /* filesystem mount point */ int rval; /* successful free trim? */ xfs_trans_t *tp; /* transaction pointer */ + struct xfs_dir3_icleaf_hdr leafhdr; + struct xfs_dir3_icfree_hdr freehdr; /* * There's more than a leaf level in the btree, so there must @@ -1426,52 +1763,62 @@ if (XFS_FSB_TO_B(mp, fo) > XFS_DIR2_LEAF_OFFSET + mp->m_dirblksize) return 0; lbp = state->path.blk[0].bp; - leaf = lbp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); + leaf = lbp->b_addr; + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + + ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || + leafhdr.magic == XFS_DIR3_LEAFN_MAGIC); + /* * Read the freespace block. */ - if ((error = xfs_da_read_buf(tp, dp, mp->m_dirfreeblk, -1, &fbp, - XFS_DATA_FORK))) { + error = xfs_dir2_free_read(tp, dp, mp->m_dirfreeblk, &fbp); + if (error) return error; - } - free = fbp->data; - ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); - ASSERT(!free->hdr.firstdb); + free = fbp->b_addr; + xfs_dir3_free_hdr_from_disk(&freehdr, free); + + ASSERT(!freehdr.firstdb); + /* * Now see if the leafn and free data will fit in a leaf1. * If not, release the buffer and give up. */ - if ((uint)sizeof(leaf->hdr) + - (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)) * (uint)sizeof(leaf->ents[0]) + - be32_to_cpu(free->hdr.nvalid) * (uint)sizeof(leaf->bests[0]) + - (uint)sizeof(leaf->tail) > - mp->m_dirblksize) { - xfs_da_brelse(tp, fbp); + if (xfs_dir3_leaf_size(&leafhdr, freehdr.nvalid) > mp->m_dirblksize) { + xfs_trans_brelse(tp, fbp); return 0; } + /* * If the leaf has any stale entries in it, compress them out. - * The compact routine will log the header. */ - if (be16_to_cpu(leaf->hdr.stale)) - xfs_dir2_leaf_compact(args, lbp); - else - xfs_dir2_leaf_log_header(tp, lbp); - leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAF1_MAGIC); + if (leafhdr.stale) + xfs_dir3_leaf_compact(args, &leafhdr, lbp); + + lbp->b_ops = &xfs_dir3_leaf1_buf_ops; + xfs_trans_buf_set_type(tp, lbp, XFS_BLFT_DIR_LEAF1_BUF); + leafhdr.magic = (leafhdr.magic == XFS_DIR2_LEAFN_MAGIC) + ? XFS_DIR2_LEAF1_MAGIC + : XFS_DIR3_LEAF1_MAGIC; + /* * Set up the leaf tail from the freespace block. */ ltp = xfs_dir2_leaf_tail_p(mp, leaf); - ltp->bestcount = free->hdr.nvalid; + ltp->bestcount = cpu_to_be32(freehdr.nvalid); + /* * Set up the leaf bests table. */ - memcpy(xfs_dir2_leaf_bests_p(ltp), free->bests, - be32_to_cpu(ltp->bestcount) * sizeof(leaf->bests[0])); - xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); - xfs_dir2_leaf_log_tail(tp, lbp); - xfs_dir2_leaf_check(dp, lbp); + memcpy(xfs_dir2_leaf_bests_p(ltp), xfs_dir3_free_bests_p(mp, free), + freehdr.nvalid * sizeof(xfs_dir2_data_off_t)); + + xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr); + xfs_dir3_leaf_log_header(tp, lbp); + xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); + xfs_dir3_leaf_log_tail(tp, lbp); + xfs_dir3_leaf_check(mp, lbp); + /* * Get rid of the freespace block. */ diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2_node.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_dir2_node.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2_node.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_dir2_node.c 2014-05-02 00:09:16.000000000 +0000 @@ -1,5 +1,6 @@ /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * Copyright (c) 2013 Red Hat, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -21,43 +22,270 @@ /* * Function declarations. */ -static void xfs_dir2_free_log_header(xfs_trans_t *tp, xfs_dabuf_t *bp); -static int xfs_dir2_leafn_add(xfs_dabuf_t *bp, xfs_da_args_t *args, int index); -#ifdef DEBUG -static void xfs_dir2_leafn_check(xfs_inode_t *dp, xfs_dabuf_t *bp); -#else -#define xfs_dir2_leafn_check(dp, bp) -#endif -static void xfs_dir2_leafn_moveents(xfs_da_args_t *args, xfs_dabuf_t *bp_s, - int start_s, xfs_dabuf_t *bp_d, int start_d, - int count); +static int xfs_dir2_leafn_add(struct xfs_buf *bp, xfs_da_args_t *args, + int index); static void xfs_dir2_leafn_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, xfs_da_state_blk_t *blk2); -static int xfs_dir2_leafn_remove(xfs_da_args_t *args, xfs_dabuf_t *bp, +static int xfs_dir2_leafn_remove(xfs_da_args_t *args, struct xfs_buf *bp, int index, xfs_da_state_blk_t *dblk, int *rval); static int xfs_dir2_node_addname_int(xfs_da_args_t *args, xfs_da_state_blk_t *fblk); /* + * Check internal consistency of a leafn block. + */ +#ifdef DEBUG +#define xfs_dir3_leaf_check(mp, bp) \ +do { \ + if (!xfs_dir3_leafn_check((mp), (bp))) \ + ASSERT(0); \ +} while (0); + +static bool +xfs_dir3_leafn_check( + struct xfs_mount *mp, + struct xfs_buf *bp) +{ + struct xfs_dir2_leaf *leaf = bp->b_addr; + struct xfs_dir3_icleaf_hdr leafhdr; + + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + + if (leafhdr.magic == XFS_DIR3_LEAFN_MAGIC) { + struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr; + if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn) + return false; + } else if (leafhdr.magic != XFS_DIR2_LEAFN_MAGIC) + return false; + + return xfs_dir3_leaf_check_int(mp, &leafhdr, leaf); +} +#else +#define xfs_dir3_leaf_check(mp, bp) +#endif + +static bool +xfs_dir3_free_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_dir2_free_hdr *hdr = bp->b_addr; + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; + + if (hdr3->magic != cpu_to_be32(XFS_DIR3_FREE_MAGIC)) + return false; + if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_uuid)) + return false; + if (be64_to_cpu(hdr3->blkno) != bp->b_bn) + return false; + } else { + if (hdr->magic != cpu_to_be32(XFS_DIR2_FREE_MAGIC)) + return false; + } + + /* XXX: should bounds check the xfs_dir3_icfree_hdr here */ + + return true; +} + +static void +xfs_dir3_free_read_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + + if (xfs_sb_version_hascrc(&mp->m_sb) && + !xfs_buf_verify_cksum(bp, XFS_DIR3_FREE_CRC_OFF)) + xfs_buf_ioerror(bp, EFSBADCRC); + else if (!xfs_dir3_free_verify(bp)) + xfs_buf_ioerror(bp, EFSCORRUPTED); + + if (bp->b_error) + xfs_verifier_error(bp); +} + +static void +xfs_dir3_free_write_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; + + if (!xfs_dir3_free_verify(bp)) { + xfs_buf_ioerror(bp, EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return; + + if (bip) + hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn); + + xfs_buf_update_cksum(bp, XFS_DIR3_FREE_CRC_OFF); +} + +const struct xfs_buf_ops xfs_dir3_free_buf_ops = { + .verify_read = xfs_dir3_free_read_verify, + .verify_write = xfs_dir3_free_write_verify, +}; + + +static int +__xfs_dir3_free_read( + struct xfs_trans *tp, + struct xfs_inode *dp, + xfs_dablk_t fbno, + xfs_daddr_t mappedbno, + struct xfs_buf **bpp) +{ + int err; + + err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, + XFS_DATA_FORK, &xfs_dir3_free_buf_ops); + + /* try read returns without an error or *bpp if it lands in a hole */ + if (!err && tp && *bpp) + xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_FREE_BUF); + return err; +} + +int +xfs_dir2_free_read( + struct xfs_trans *tp, + struct xfs_inode *dp, + xfs_dablk_t fbno, + struct xfs_buf **bpp) +{ + return __xfs_dir3_free_read(tp, dp, fbno, -1, bpp); +} + +static int +xfs_dir2_free_try_read( + struct xfs_trans *tp, + struct xfs_inode *dp, + xfs_dablk_t fbno, + struct xfs_buf **bpp) +{ + return __xfs_dir3_free_read(tp, dp, fbno, -2, bpp); +} + + +void +xfs_dir3_free_hdr_from_disk( + struct xfs_dir3_icfree_hdr *to, + struct xfs_dir2_free *from) +{ + if (from->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)) { + to->magic = be32_to_cpu(from->hdr.magic); + to->firstdb = be32_to_cpu(from->hdr.firstdb); + to->nvalid = be32_to_cpu(from->hdr.nvalid); + to->nused = be32_to_cpu(from->hdr.nused); + } else { + struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)from; + + to->magic = be32_to_cpu(hdr3->hdr.magic); + to->firstdb = be32_to_cpu(hdr3->firstdb); + to->nvalid = be32_to_cpu(hdr3->nvalid); + to->nused = be32_to_cpu(hdr3->nused); + } + + ASSERT(to->magic == XFS_DIR2_FREE_MAGIC || + to->magic == XFS_DIR3_FREE_MAGIC); +} + +static void +xfs_dir3_free_hdr_to_disk( + struct xfs_dir2_free *to, + struct xfs_dir3_icfree_hdr *from) +{ + ASSERT(from->magic == XFS_DIR2_FREE_MAGIC || + from->magic == XFS_DIR3_FREE_MAGIC); + + if (from->magic == XFS_DIR2_FREE_MAGIC) { + to->hdr.magic = cpu_to_be32(from->magic); + to->hdr.firstdb = cpu_to_be32(from->firstdb); + to->hdr.nvalid = cpu_to_be32(from->nvalid); + to->hdr.nused = cpu_to_be32(from->nused); + } else { + struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)to; + + hdr3->hdr.magic = cpu_to_be32(from->magic); + hdr3->firstdb = cpu_to_be32(from->firstdb); + hdr3->nvalid = cpu_to_be32(from->nvalid); + hdr3->nused = cpu_to_be32(from->nused); + } +} + +static int +xfs_dir3_free_get_buf( + struct xfs_trans *tp, + struct xfs_inode *dp, + xfs_dir2_db_t fbno, + struct xfs_buf **bpp) +{ + struct xfs_mount *mp = dp->i_mount; + struct xfs_buf *bp; + int error; + struct xfs_dir3_icfree_hdr hdr; + + error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, fbno), + -1, &bp, XFS_DATA_FORK); + if (error) + return error; + + xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_FREE_BUF); + bp->b_ops = &xfs_dir3_free_buf_ops; + + /* + * Initialize the new block to be empty, and remember + * its first slot as our empty slot. + */ + memset(bp->b_addr, 0, sizeof(struct xfs_dir3_free_hdr)); + memset(&hdr, 0, sizeof(hdr)); + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + struct xfs_dir3_free_hdr *hdr3 = bp->b_addr; + + hdr.magic = XFS_DIR3_FREE_MAGIC; + + hdr3->hdr.blkno = cpu_to_be64(bp->b_bn); + hdr3->hdr.owner = cpu_to_be64(dp->i_ino); + uuid_copy(&hdr3->hdr.uuid, &mp->m_sb.sb_uuid); + } else + hdr.magic = XFS_DIR2_FREE_MAGIC; + xfs_dir3_free_hdr_to_disk(bp->b_addr, &hdr); + *bpp = bp; + return 0; +} + +/* * Log entries from a freespace block. */ STATIC void xfs_dir2_free_log_bests( - xfs_trans_t *tp, /* transaction pointer */ - xfs_dabuf_t *bp, /* freespace buffer */ + struct xfs_trans *tp, + struct xfs_buf *bp, int first, /* first entry to log */ int last) /* last entry to log */ { xfs_dir2_free_t *free; /* freespace structure */ + __be16 *bests; - free = bp->data; - ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); - xfs_da_log_buf(tp, bp, - (uint)((char *)&free->bests[first] - (char *)free), - (uint)((char *)&free->bests[last] - (char *)free + - sizeof(free->bests[0]) - 1)); + free = bp->b_addr; + bests = xfs_dir3_free_bests_p(tp->t_mountp, free); + ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) || + free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); + xfs_trans_log_buf(tp, bp, + (uint)((char *)&bests[first] - (char *)free), + (uint)((char *)&bests[last] - (char *)free + + sizeof(bests[0]) - 1)); } /* @@ -65,15 +293,17 @@ */ static void xfs_dir2_free_log_header( - xfs_trans_t *tp, /* transaction pointer */ - xfs_dabuf_t *bp) /* freespace buffer */ + struct xfs_trans *tp, + struct xfs_buf *bp) { +#ifdef DEBUG xfs_dir2_free_t *free; /* freespace structure */ - free = bp->data; - ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); - xfs_da_log_buf(tp, bp, (uint)((char *)&free->hdr - (char *)free), - (uint)(sizeof(xfs_dir2_free_hdr_t) - 1)); + free = bp->b_addr; + ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) || + free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); +#endif + xfs_trans_log_buf(tp, bp, 0, xfs_dir3_free_hdr_size(tp->t_mountp) - 1); } /* @@ -84,11 +314,11 @@ int /* error */ xfs_dir2_leaf_to_node( xfs_da_args_t *args, /* operation arguments */ - xfs_dabuf_t *lbp) /* leaf buffer */ + struct xfs_buf *lbp) /* leaf buffer */ { xfs_inode_t *dp; /* incore directory inode */ int error; /* error return value */ - xfs_dabuf_t *fbp; /* freespace buffer */ + struct xfs_buf *fbp; /* freespace buffer */ xfs_dir2_db_t fdb; /* freespace block number */ xfs_dir2_free_t *free; /* freespace structure */ __be16 *from; /* pointer to freespace entry */ @@ -100,6 +330,7 @@ xfs_dir2_data_off_t off; /* freespace entry value */ __be16 *to; /* pointer to freespace entry */ xfs_trans_t *tp; /* transaction pointer */ + struct xfs_dir3_icfree_hdr freehdr; trace_xfs_dir2_leaf_to_node(args); @@ -116,41 +347,53 @@ /* * Get the buffer for the new freespace block. */ - if ((error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, fdb), -1, &fbp, - XFS_DATA_FORK))) { + error = xfs_dir3_free_get_buf(tp, dp, fdb, &fbp); + if (error) return error; - } - ASSERT(fbp != NULL); - free = fbp->data; - leaf = lbp->data; + + free = fbp->b_addr; + xfs_dir3_free_hdr_from_disk(&freehdr, free); + leaf = lbp->b_addr; ltp = xfs_dir2_leaf_tail_p(mp, leaf); - /* - * Initialize the freespace block header. - */ - free->hdr.magic = cpu_to_be32(XFS_DIR2_FREE_MAGIC); - free->hdr.firstdb = 0; - ASSERT(be32_to_cpu(ltp->bestcount) <= (uint)dp->i_d.di_size / mp->m_dirblksize); - free->hdr.nvalid = ltp->bestcount; + ASSERT(be32_to_cpu(ltp->bestcount) <= + (uint)dp->i_d.di_size / mp->m_dirblksize); + /* * Copy freespace entries from the leaf block to the new block. * Count active entries. */ - for (i = n = 0, from = xfs_dir2_leaf_bests_p(ltp), to = free->bests; - i < be32_to_cpu(ltp->bestcount); i++, from++, to++) { + from = xfs_dir2_leaf_bests_p(ltp); + to = xfs_dir3_free_bests_p(mp, free); + for (i = n = 0; i < be32_to_cpu(ltp->bestcount); i++, from++, to++) { if ((off = be16_to_cpu(*from)) != NULLDATAOFF) n++; *to = cpu_to_be16(off); } - free->hdr.nused = cpu_to_be32(n); - leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAFN_MAGIC); + /* - * Log everything. + * Now initialize the freespace block header. */ - xfs_dir2_leaf_log_header(tp, lbp); + freehdr.nused = n; + freehdr.nvalid = be32_to_cpu(ltp->bestcount); + + xfs_dir3_free_hdr_to_disk(fbp->b_addr, &freehdr); + xfs_dir2_free_log_bests(tp, fbp, 0, freehdr.nvalid - 1); xfs_dir2_free_log_header(tp, fbp); - xfs_dir2_free_log_bests(tp, fbp, 0, be32_to_cpu(free->hdr.nvalid) - 1); - xfs_da_buf_done(fbp); - xfs_dir2_leafn_check(dp, lbp); + + /* + * Converting the leaf to a leafnode is just a matter of changing the + * magic number and the ops. Do the change directly to the buffer as + * it's less work (and less code) than decoding the header to host + * format and back again. + */ + if (leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC)) + leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAFN_MAGIC); + else + leaf->hdr.info.magic = cpu_to_be16(XFS_DIR3_LEAFN_MAGIC); + lbp->b_ops = &xfs_dir3_leafn_buf_ops; + xfs_trans_buf_set_type(tp, lbp, XFS_BLFT_DIR_LEAFN_BUF); + xfs_dir3_leaf_log_header(tp, lbp); + xfs_dir3_leaf_check(mp, lbp); return 0; } @@ -160,7 +403,7 @@ */ static int /* error */ xfs_dir2_leafn_add( - xfs_dabuf_t *bp, /* leaf buffer */ + struct xfs_buf *bp, /* leaf buffer */ xfs_da_args_t *args, /* operation arguments */ int index) /* insertion pt for new entry */ { @@ -174,13 +417,17 @@ int lowstale; /* previous stale entry */ xfs_mount_t *mp; /* filesystem mount point */ xfs_trans_t *tp; /* transaction pointer */ + struct xfs_dir3_icleaf_hdr leafhdr; + struct xfs_dir2_leaf_entry *ents; trace_xfs_dir2_leafn_add(args, index); dp = args->dp; mp = dp->i_mount; tp = args->trans; - leaf = bp->data; + leaf = bp->b_addr; + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + ents = xfs_dir3_leaf_ents_p(leaf); /* * Quick check just to make sure we are not going to index @@ -196,15 +443,15 @@ * a compact. */ - if (be16_to_cpu(leaf->hdr.count) == xfs_dir2_max_leaf_ents(mp)) { - if (!leaf->hdr.stale) + if (leafhdr.count == xfs_dir3_max_leaf_ents(mp, leaf)) { + if (!leafhdr.stale) return XFS_ERROR(ENOSPC); - compact = be16_to_cpu(leaf->hdr.stale) > 1; + compact = leafhdr.stale > 1; } else compact = 0; - ASSERT(index == 0 || be32_to_cpu(leaf->ents[index - 1].hashval) <= args->hashval); - ASSERT(index == be16_to_cpu(leaf->hdr.count) || - be32_to_cpu(leaf->ents[index].hashval) >= args->hashval); + ASSERT(index == 0 || be32_to_cpu(ents[index - 1].hashval) <= args->hashval); + ASSERT(index == leafhdr.count || + be32_to_cpu(ents[index].hashval) >= args->hashval); if (args->op_flags & XFS_DA_OP_JUSTCHECK) return 0; @@ -213,137 +460,51 @@ * Compact out all but one stale leaf entry. Leaves behind * the entry closest to index. */ - if (compact) { - xfs_dir2_leaf_compact_x1(bp, &index, &lowstale, &highstale, - &lfloglow, &lfloghigh); - } - /* - * Set impossible logging indices for this case. - */ - else if (leaf->hdr.stale) { - lfloglow = be16_to_cpu(leaf->hdr.count); - lfloghigh = -1; - } - /* - * No stale entries, just insert a space for the new entry. - */ - if (!leaf->hdr.stale) { - lep = &leaf->ents[index]; - if (index < be16_to_cpu(leaf->hdr.count)) - memmove(lep + 1, lep, - (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep)); - lfloglow = index; - lfloghigh = be16_to_cpu(leaf->hdr.count); - be16_add_cpu(&leaf->hdr.count, 1); - } - /* - * There are stale entries. We'll use one for the new entry. - */ - else { + if (compact) + xfs_dir3_leaf_compact_x1(&leafhdr, ents, &index, &lowstale, + &highstale, &lfloglow, &lfloghigh); + else if (leafhdr.stale) { /* - * If we didn't do a compact then we need to figure out - * which stale entry will be used. + * Set impossible logging indices for this case. */ - if (compact == 0) { - /* - * Find first stale entry before our insertion point. - */ - for (lowstale = index - 1; - lowstale >= 0 && - be32_to_cpu(leaf->ents[lowstale].address) != - XFS_DIR2_NULL_DATAPTR; - lowstale--) - continue; - /* - * Find next stale entry after insertion point. - * Stop looking if the answer would be worse than - * lowstale already found. - */ - for (highstale = index; - highstale < be16_to_cpu(leaf->hdr.count) && - be32_to_cpu(leaf->ents[highstale].address) != - XFS_DIR2_NULL_DATAPTR && - (lowstale < 0 || - index - lowstale - 1 >= highstale - index); - highstale++) - continue; - } - /* - * Using the low stale entry. - * Shift entries up toward the stale slot. - */ - if (lowstale >= 0 && - (highstale == be16_to_cpu(leaf->hdr.count) || - index - lowstale - 1 < highstale - index)) { - ASSERT(be32_to_cpu(leaf->ents[lowstale].address) == - XFS_DIR2_NULL_DATAPTR); - ASSERT(index - lowstale - 1 >= 0); - if (index - lowstale - 1 > 0) - memmove(&leaf->ents[lowstale], - &leaf->ents[lowstale + 1], - (index - lowstale - 1) * sizeof(*lep)); - lep = &leaf->ents[index - 1]; - lfloglow = MIN(lowstale, lfloglow); - lfloghigh = MAX(index - 1, lfloghigh); - } - /* - * Using the high stale entry. - * Shift entries down toward the stale slot. - */ - else { - ASSERT(be32_to_cpu(leaf->ents[highstale].address) == - XFS_DIR2_NULL_DATAPTR); - ASSERT(highstale - index >= 0); - if (highstale - index > 0) - memmove(&leaf->ents[index + 1], - &leaf->ents[index], - (highstale - index) * sizeof(*lep)); - lep = &leaf->ents[index]; - lfloglow = MIN(index, lfloglow); - lfloghigh = MAX(highstale, lfloghigh); - } - be16_add_cpu(&leaf->hdr.stale, -1); + lfloglow = leafhdr.count; + lfloghigh = -1; } + /* * Insert the new entry, log everything. */ + lep = xfs_dir3_leaf_find_entry(&leafhdr, ents, index, compact, lowstale, + highstale, &lfloglow, &lfloghigh); + lep->hashval = cpu_to_be32(args->hashval); lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, args->blkno, args->index)); - xfs_dir2_leaf_log_header(tp, bp); - xfs_dir2_leaf_log_ents(tp, bp, lfloglow, lfloghigh); - xfs_dir2_leafn_check(dp, bp); + + xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr); + xfs_dir3_leaf_log_header(tp, bp); + xfs_dir3_leaf_log_ents(tp, bp, lfloglow, lfloghigh); + xfs_dir3_leaf_check(mp, bp); return 0; } #ifdef DEBUG -/* - * Check internal consistency of a leafn block. - */ -void -xfs_dir2_leafn_check( - xfs_inode_t *dp, /* incore directory inode */ - xfs_dabuf_t *bp) /* leaf buffer */ -{ - int i; /* leaf index */ - xfs_dir2_leaf_t *leaf; /* leaf structure */ - xfs_mount_t *mp; /* filesystem mount point */ - int stale; /* count of stale leaves */ - - leaf = bp->data; - mp = dp->i_mount; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); - ASSERT(be16_to_cpu(leaf->hdr.count) <= xfs_dir2_max_leaf_ents(mp)); - for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) { - if (i + 1 < be16_to_cpu(leaf->hdr.count)) { - ASSERT(be32_to_cpu(leaf->ents[i].hashval) <= - be32_to_cpu(leaf->ents[i + 1].hashval)); - } - if (be32_to_cpu(leaf->ents[i].address) == XFS_DIR2_NULL_DATAPTR) - stale++; - } - ASSERT(be16_to_cpu(leaf->hdr.stale) == stale); +static void +xfs_dir2_free_hdr_check( + struct xfs_mount *mp, + struct xfs_buf *bp, + xfs_dir2_db_t db) +{ + struct xfs_dir3_icfree_hdr hdr; + + xfs_dir3_free_hdr_from_disk(&hdr, bp->b_addr); + + ASSERT((hdr.firstdb % xfs_dir3_free_max_bests(mp)) == 0); + ASSERT(hdr.firstdb <= db); + ASSERT(db < hdr.firstdb + hdr.nvalid); } +#else +#define xfs_dir2_free_hdr_check(mp, dp, db) #endif /* DEBUG */ /* @@ -352,18 +513,25 @@ */ xfs_dahash_t /* hash value */ xfs_dir2_leafn_lasthash( - xfs_dabuf_t *bp, /* leaf buffer */ + struct xfs_buf *bp, /* leaf buffer */ int *count) /* count of entries in leaf */ { - xfs_dir2_leaf_t *leaf; /* leaf structure */ + struct xfs_dir2_leaf *leaf = bp->b_addr; + struct xfs_dir2_leaf_entry *ents; + struct xfs_dir3_icleaf_hdr leafhdr; + + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + + ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || + leafhdr.magic == XFS_DIR3_LEAFN_MAGIC); - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); if (count) - *count = be16_to_cpu(leaf->hdr.count); - if (!leaf->hdr.count) + *count = leafhdr.count; + if (!leafhdr.count) return 0; - return be32_to_cpu(leaf->ents[be16_to_cpu(leaf->hdr.count) - 1].hashval); + + ents = xfs_dir3_leaf_ents_p(leaf); + return be32_to_cpu(ents[leafhdr.count - 1].hashval); } /* @@ -372,12 +540,12 @@ */ STATIC int xfs_dir2_leafn_lookup_for_addname( - xfs_dabuf_t *bp, /* leaf buffer */ + struct xfs_buf *bp, /* leaf buffer */ xfs_da_args_t *args, /* operation arguments */ int *indexp, /* out: leaf entry index */ xfs_da_state_t *state) /* state to fill in */ { - xfs_dabuf_t *curbp = NULL; /* current data/free buffer */ + struct xfs_buf *curbp = NULL; /* current data/free buffer */ xfs_dir2_db_t curdb = -1; /* current data block number */ xfs_dir2_db_t curfdb = -1; /* current free block number */ xfs_inode_t *dp; /* incore directory inode */ @@ -392,16 +560,19 @@ xfs_dir2_db_t newdb; /* new data block number */ xfs_dir2_db_t newfdb; /* new free block number */ xfs_trans_t *tp; /* transaction pointer */ + struct xfs_dir2_leaf_entry *ents; + struct xfs_dir3_icleaf_hdr leafhdr; dp = args->dp; tp = args->trans; mp = dp->i_mount; - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); -#ifdef __KERNEL__ - ASSERT(be16_to_cpu(leaf->hdr.count) > 0); -#endif - xfs_dir2_leafn_check(dp, bp); + leaf = bp->b_addr; + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + ents = xfs_dir3_leaf_ents_p(leaf); + + xfs_dir3_leaf_check(mp, bp); + ASSERT(leafhdr.count > 0); + /* * Look up the hash value in the leaf entries. */ @@ -413,16 +584,17 @@ /* If so, it's a free block buffer, get the block number. */ curbp = state->extrablk.bp; curfdb = state->extrablk.blkno; - free = curbp->data; - ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); + free = curbp->b_addr; + ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) || + free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); } - length = xfs_dir2_data_entsize(args->namelen); + length = xfs_dir3_data_entsize(mp, args->namelen); /* * Loop over leaf entries with the right hash value. */ - for (lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) && - be32_to_cpu(lep->hashval) == args->hashval; - lep++, index++) { + for (lep = &ents[index]; + index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval; + lep++, index++) { /* * Skip stale leaf entries. */ @@ -441,6 +613,8 @@ * in hand, take a look at it. */ if (newdb != curdb) { + __be16 *bests; + curdb = newdb; /* * Convert the data block to the free block @@ -455,23 +629,16 @@ * If we had one before, drop it. */ if (curbp) - xfs_da_brelse(tp, curbp); - /* - * Read the free block. - */ - error = xfs_da_read_buf(tp, dp, + xfs_trans_brelse(tp, curbp); + + error = xfs_dir2_free_read(tp, dp, xfs_dir2_db_to_da(mp, newfdb), - -1, &curbp, XFS_DATA_FORK); + &curbp); if (error) return error; - free = curbp->data; - ASSERT(be32_to_cpu(free->hdr.magic) == - XFS_DIR2_FREE_MAGIC); - ASSERT((be32_to_cpu(free->hdr.firstdb) % - XFS_DIR2_MAX_FREE_BESTS(mp)) == 0); - ASSERT(be32_to_cpu(free->hdr.firstdb) <= curdb); - ASSERT(curdb < be32_to_cpu(free->hdr.firstdb) + - be32_to_cpu(free->hdr.nvalid)); + free = curbp->b_addr; + + xfs_dir2_free_hdr_check(mp, curbp, curdb); } /* * Get the index for our entry. @@ -480,15 +647,16 @@ /* * If it has room, return it. */ - if (unlikely(be16_to_cpu(free->bests[fi]) == NULLDATAOFF)) { + bests = xfs_dir3_free_bests_p(mp, free); + if (unlikely(bests[fi] == cpu_to_be16(NULLDATAOFF))) { XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", XFS_ERRLEVEL_LOW, mp); if (curfdb != newfdb) - xfs_da_brelse(tp, curbp); + xfs_trans_brelse(tp, curbp); return XFS_ERROR(EFSCORRUPTED); } curfdb = newfdb; - if (be16_to_cpu(free->bests[fi]) >= length) + if (be16_to_cpu(bests[fi]) >= length) goto out; } } @@ -502,6 +670,12 @@ state->extrablk.bp = curbp; state->extrablk.index = fi; state->extrablk.blkno = curfdb; + + /* + * Important: this magic number is not in the buffer - it's for + * buffer type information and therefore only the free/data type + * matters here, not whether CRCs are enabled or not. + */ state->extrablk.magic = XFS_DIR2_FREE_MAGIC; } else { state->extravalid = 0; @@ -519,12 +693,12 @@ */ STATIC int xfs_dir2_leafn_lookup_for_entry( - xfs_dabuf_t *bp, /* leaf buffer */ + struct xfs_buf *bp, /* leaf buffer */ xfs_da_args_t *args, /* operation arguments */ int *indexp, /* out: leaf entry index */ xfs_da_state_t *state) /* state to fill in */ { - xfs_dabuf_t *curbp = NULL; /* current data/free buffer */ + struct xfs_buf *curbp = NULL; /* current data/free buffer */ xfs_dir2_db_t curdb = -1; /* current data block number */ xfs_dir2_data_entry_t *dep; /* data block entry */ xfs_inode_t *dp; /* incore directory inode */ @@ -536,16 +710,19 @@ xfs_dir2_db_t newdb; /* new data block number */ xfs_trans_t *tp; /* transaction pointer */ enum xfs_dacmp cmp; /* comparison result */ + struct xfs_dir2_leaf_entry *ents; + struct xfs_dir3_icleaf_hdr leafhdr; dp = args->dp; tp = args->trans; mp = dp->i_mount; - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); -#ifdef __KERNEL__ - ASSERT(be16_to_cpu(leaf->hdr.count) > 0); -#endif - xfs_dir2_leafn_check(dp, bp); + leaf = bp->b_addr; + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + ents = xfs_dir3_leaf_ents_p(leaf); + + xfs_dir3_leaf_check(mp, bp); + ASSERT(leafhdr.count > 0); + /* * Look up the hash value in the leaf entries. */ @@ -560,9 +737,9 @@ /* * Loop over leaf entries with the right hash value. */ - for (lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) && - be32_to_cpu(lep->hashval) == args->hashval; - lep++, index++) { + for (lep = &ents[index]; + index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval; + lep++, index++) { /* * Skip stale leaf entries. */ @@ -585,7 +762,7 @@ */ if (curbp && (args->cmpresult == XFS_CMP_DIFFERENT || curdb != state->extrablk.blkno)) - xfs_da_brelse(tp, curbp); + xfs_trans_brelse(tp, curbp); /* * If needing the block that is saved with a CI match, * use it otherwise read in the new data block. @@ -595,19 +772,19 @@ ASSERT(state->extravalid); curbp = state->extrablk.bp; } else { - error = xfs_da_read_buf(tp, dp, + error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(mp, newdb), - -1, &curbp, XFS_DATA_FORK); + -1, &curbp); if (error) return error; } - xfs_dir2_data_check(dp, curbp); + xfs_dir3_data_check(dp, curbp); curdb = newdb; } /* * Point to the data entry. */ - dep = (xfs_dir2_data_entry_t *)((char *)curbp->data + + dep = (xfs_dir2_data_entry_t *)((char *)curbp->b_addr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); /* * Compare the entry and if it's an exact match, return @@ -619,22 +796,24 @@ /* If there is a CI match block, drop it */ if (args->cmpresult != XFS_CMP_DIFFERENT && curdb != state->extrablk.blkno) - xfs_da_brelse(tp, state->extrablk.bp); + xfs_trans_brelse(tp, state->extrablk.bp); args->cmpresult = cmp; args->inumber = be64_to_cpu(dep->inumber); + args->filetype = xfs_dir3_dirent_get_ftype(mp, dep); *indexp = index; state->extravalid = 1; state->extrablk.bp = curbp; state->extrablk.blkno = curdb; state->extrablk.index = (int)((char *)dep - - (char *)curbp->data); + (char *)curbp->b_addr); state->extrablk.magic = XFS_DIR2_DATA_MAGIC; + curbp->b_ops = &xfs_dir3_data_buf_ops; + xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF); if (cmp == XFS_CMP_EXACT) return XFS_ERROR(EEXIST); } } - ASSERT(index == be16_to_cpu(leaf->hdr.count) || - (args->op_flags & XFS_DA_OP_OKNOENT)); + ASSERT(index == leafhdr.count || (args->op_flags & XFS_DA_OP_OKNOENT)); if (curbp) { if (args->cmpresult == XFS_CMP_DIFFERENT) { /* Giving back last used data block. */ @@ -643,10 +822,12 @@ state->extrablk.index = -1; state->extrablk.blkno = curdb; state->extrablk.magic = XFS_DIR2_DATA_MAGIC; + curbp->b_ops = &xfs_dir3_data_buf_ops; + xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF); } else { /* If the curbp is not the CI match block, drop it */ if (state->extrablk.bp != curbp) - xfs_da_brelse(tp, curbp); + xfs_trans_brelse(tp, curbp); } } else { state->extravalid = 0; @@ -662,7 +843,7 @@ */ int xfs_dir2_leafn_lookup_int( - xfs_dabuf_t *bp, /* leaf buffer */ + struct xfs_buf *bp, /* leaf buffer */ xfs_da_args_t *args, /* operation arguments */ int *indexp, /* out: leaf entry index */ xfs_da_state_t *state) /* state to fill in */ @@ -678,51 +859,50 @@ * Log entries and headers. Stale entries are preserved. */ static void -xfs_dir2_leafn_moveents( - xfs_da_args_t *args, /* operation arguments */ - xfs_dabuf_t *bp_s, /* source leaf buffer */ - int start_s, /* source leaf index */ - xfs_dabuf_t *bp_d, /* destination leaf buffer */ - int start_d, /* destination leaf index */ - int count) /* count of leaves to copy */ -{ - xfs_dir2_leaf_t *leaf_d; /* destination leaf structure */ - xfs_dir2_leaf_t *leaf_s; /* source leaf structure */ - int stale; /* count stale leaves copied */ - xfs_trans_t *tp; /* transaction pointer */ +xfs_dir3_leafn_moveents( + xfs_da_args_t *args, /* operation arguments */ + struct xfs_buf *bp_s, /* source */ + struct xfs_dir3_icleaf_hdr *shdr, + struct xfs_dir2_leaf_entry *sents, + int start_s,/* source leaf index */ + struct xfs_buf *bp_d, /* destination */ + struct xfs_dir3_icleaf_hdr *dhdr, + struct xfs_dir2_leaf_entry *dents, + int start_d,/* destination leaf index */ + int count) /* count of leaves to copy */ +{ + struct xfs_trans *tp = args->trans; + int stale; /* count stale leaves copied */ trace_xfs_dir2_leafn_moveents(args, start_s, start_d, count); /* * Silently return if nothing to do. */ - if (count == 0) { + if (count == 0) return; - } - tp = args->trans; - leaf_s = bp_s->data; - leaf_d = bp_d->data; + /* * If the destination index is not the end of the current * destination leaf entries, open up a hole in the destination * to hold the new entries. */ - if (start_d < be16_to_cpu(leaf_d->hdr.count)) { - memmove(&leaf_d->ents[start_d + count], &leaf_d->ents[start_d], - (be16_to_cpu(leaf_d->hdr.count) - start_d) * - sizeof(xfs_dir2_leaf_entry_t)); - xfs_dir2_leaf_log_ents(tp, bp_d, start_d + count, - count + be16_to_cpu(leaf_d->hdr.count) - 1); + if (start_d < dhdr->count) { + memmove(&dents[start_d + count], &dents[start_d], + (dhdr->count - start_d) * sizeof(xfs_dir2_leaf_entry_t)); + xfs_dir3_leaf_log_ents(tp, bp_d, start_d + count, + count + dhdr->count - 1); } /* * If the source has stale leaves, count the ones in the copy range * so we can update the header correctly. */ - if (leaf_s->hdr.stale) { + if (shdr->stale) { int i; /* temp leaf index */ for (i = start_s, stale = 0; i < start_s + count; i++) { - if (be32_to_cpu(leaf_s->ents[i].address) == XFS_DIR2_NULL_DATAPTR) + if (sents[i].address == + cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) stale++; } } else @@ -730,29 +910,27 @@ /* * Copy the leaf entries from source to destination. */ - memcpy(&leaf_d->ents[start_d], &leaf_s->ents[start_s], + memcpy(&dents[start_d], &sents[start_s], count * sizeof(xfs_dir2_leaf_entry_t)); - xfs_dir2_leaf_log_ents(tp, bp_d, start_d, start_d + count - 1); + xfs_dir3_leaf_log_ents(tp, bp_d, start_d, start_d + count - 1); + /* * If there are source entries after the ones we copied, * delete the ones we copied by sliding the next ones down. */ - if (start_s + count < be16_to_cpu(leaf_s->hdr.count)) { - memmove(&leaf_s->ents[start_s], &leaf_s->ents[start_s + count], + if (start_s + count < shdr->count) { + memmove(&sents[start_s], &sents[start_s + count], count * sizeof(xfs_dir2_leaf_entry_t)); - xfs_dir2_leaf_log_ents(tp, bp_s, start_s, start_s + count - 1); + xfs_dir3_leaf_log_ents(tp, bp_s, start_s, start_s + count - 1); } + /* * Update the headers and log them. */ - be16_add_cpu(&leaf_s->hdr.count, -(count)); - be16_add_cpu(&leaf_s->hdr.stale, -(stale)); - be16_add_cpu(&leaf_d->hdr.count, count); - be16_add_cpu(&leaf_d->hdr.stale, stale); - xfs_dir2_leaf_log_header(tp, bp_s); - xfs_dir2_leaf_log_header(tp, bp_d); - xfs_dir2_leafn_check(args->dp, bp_s); - xfs_dir2_leafn_check(args->dp, bp_d); + shdr->count -= count; + shdr->stale -= stale; + dhdr->count += count; + dhdr->stale += stale; } /* @@ -761,21 +939,25 @@ */ int /* sort order */ xfs_dir2_leafn_order( - xfs_dabuf_t *leaf1_bp, /* leaf1 buffer */ - xfs_dabuf_t *leaf2_bp) /* leaf2 buffer */ + struct xfs_buf *leaf1_bp, /* leaf1 buffer */ + struct xfs_buf *leaf2_bp) /* leaf2 buffer */ { - xfs_dir2_leaf_t *leaf1; /* leaf1 structure */ - xfs_dir2_leaf_t *leaf2; /* leaf2 structure */ - - leaf1 = leaf1_bp->data; - leaf2 = leaf2_bp->data; - ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); - ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); - if (be16_to_cpu(leaf1->hdr.count) > 0 && - be16_to_cpu(leaf2->hdr.count) > 0 && - (be32_to_cpu(leaf2->ents[0].hashval) < be32_to_cpu(leaf1->ents[0].hashval) || - be32_to_cpu(leaf2->ents[be16_to_cpu(leaf2->hdr.count) - 1].hashval) < - be32_to_cpu(leaf1->ents[be16_to_cpu(leaf1->hdr.count) - 1].hashval))) + struct xfs_dir2_leaf *leaf1 = leaf1_bp->b_addr; + struct xfs_dir2_leaf *leaf2 = leaf2_bp->b_addr; + struct xfs_dir2_leaf_entry *ents1; + struct xfs_dir2_leaf_entry *ents2; + struct xfs_dir3_icleaf_hdr hdr1; + struct xfs_dir3_icleaf_hdr hdr2; + + xfs_dir3_leaf_hdr_from_disk(&hdr1, leaf1); + xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf2); + ents1 = xfs_dir3_leaf_ents_p(leaf1); + ents2 = xfs_dir3_leaf_ents_p(leaf2); + + if (hdr1.count > 0 && hdr2.count > 0 && + (be32_to_cpu(ents2[0].hashval) < be32_to_cpu(ents1[0].hashval) || + be32_to_cpu(ents2[hdr2.count - 1].hashval) < + be32_to_cpu(ents1[hdr1.count - 1].hashval))) return 1; return 0; } @@ -799,11 +981,15 @@ xfs_dir2_leaf_t *leaf1; /* first leaf structure */ xfs_dir2_leaf_t *leaf2; /* second leaf structure */ int mid; /* midpoint leaf index */ -#ifdef DEBUG +#if defined(DEBUG) || defined(XFS_WARN) int oldstale; /* old count of stale leaves */ #endif int oldsum; /* old total leaf count */ int swap; /* swapped leaf blocks */ + struct xfs_dir2_leaf_entry *ents1; + struct xfs_dir2_leaf_entry *ents2; + struct xfs_dir3_icleaf_hdr hdr1; + struct xfs_dir3_icleaf_hdr hdr2; args = state->args; /* @@ -816,13 +1002,19 @@ blk1 = blk2; blk2 = tmp; } - leaf1 = blk1->bp->data; - leaf2 = blk2->bp->data; - oldsum = be16_to_cpu(leaf1->hdr.count) + be16_to_cpu(leaf2->hdr.count); -#ifdef DEBUG - oldstale = be16_to_cpu(leaf1->hdr.stale) + be16_to_cpu(leaf2->hdr.stale); + leaf1 = blk1->bp->b_addr; + leaf2 = blk2->bp->b_addr; + xfs_dir3_leaf_hdr_from_disk(&hdr1, leaf1); + xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf2); + ents1 = xfs_dir3_leaf_ents_p(leaf1); + ents2 = xfs_dir3_leaf_ents_p(leaf2); + + oldsum = hdr1.count + hdr2.count; +#if defined(DEBUG) || defined(XFS_WARN) + oldstale = hdr1.stale + hdr2.stale; #endif mid = oldsum >> 1; + /* * If the old leaf count was odd then the new one will be even, * so we need to divide the new count evenly. @@ -830,10 +1022,10 @@ if (oldsum & 1) { xfs_dahash_t midhash; /* middle entry hash value */ - if (mid >= be16_to_cpu(leaf1->hdr.count)) - midhash = be32_to_cpu(leaf2->ents[mid - be16_to_cpu(leaf1->hdr.count)].hashval); + if (mid >= hdr1.count) + midhash = be32_to_cpu(ents2[mid - hdr1.count].hashval); else - midhash = be32_to_cpu(leaf1->ents[mid].hashval); + midhash = be32_to_cpu(ents1[mid].hashval); isleft = args->hashval <= midhash; } /* @@ -847,30 +1039,42 @@ * Calculate moved entry count. Positive means left-to-right, * negative means right-to-left. Then move the entries. */ - count = be16_to_cpu(leaf1->hdr.count) - mid + (isleft == 0); + count = hdr1.count - mid + (isleft == 0); if (count > 0) - xfs_dir2_leafn_moveents(args, blk1->bp, - be16_to_cpu(leaf1->hdr.count) - count, blk2->bp, 0, count); + xfs_dir3_leafn_moveents(args, blk1->bp, &hdr1, ents1, + hdr1.count - count, blk2->bp, + &hdr2, ents2, 0, count); else if (count < 0) - xfs_dir2_leafn_moveents(args, blk2->bp, 0, blk1->bp, - be16_to_cpu(leaf1->hdr.count), count); - ASSERT(be16_to_cpu(leaf1->hdr.count) + be16_to_cpu(leaf2->hdr.count) == oldsum); - ASSERT(be16_to_cpu(leaf1->hdr.stale) + be16_to_cpu(leaf2->hdr.stale) == oldstale); + xfs_dir3_leafn_moveents(args, blk2->bp, &hdr2, ents2, 0, + blk1->bp, &hdr1, ents1, + hdr1.count, count); + + ASSERT(hdr1.count + hdr2.count == oldsum); + ASSERT(hdr1.stale + hdr2.stale == oldstale); + + /* log the changes made when moving the entries */ + xfs_dir3_leaf_hdr_to_disk(leaf1, &hdr1); + xfs_dir3_leaf_hdr_to_disk(leaf2, &hdr2); + xfs_dir3_leaf_log_header(args->trans, blk1->bp); + xfs_dir3_leaf_log_header(args->trans, blk2->bp); + + xfs_dir3_leaf_check(args->dp->i_mount, blk1->bp); + xfs_dir3_leaf_check(args->dp->i_mount, blk2->bp); + /* * Mark whether we're inserting into the old or new leaf. */ - if (be16_to_cpu(leaf1->hdr.count) < be16_to_cpu(leaf2->hdr.count)) + if (hdr1.count < hdr2.count) state->inleaf = swap; - else if (be16_to_cpu(leaf1->hdr.count) > be16_to_cpu(leaf2->hdr.count)) + else if (hdr1.count > hdr2.count) state->inleaf = !swap; else - state->inleaf = - swap ^ (blk1->index <= be16_to_cpu(leaf1->hdr.count)); + state->inleaf = swap ^ (blk1->index <= hdr1.count); /* * Adjust the expected index for insertion. */ if (!state->inleaf) - blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count); + blk2->index = blk1->index - hdr1.count; /* * Finally sanity check just to make sure we are not returning a @@ -879,11 +1083,90 @@ if(blk2->index < 0) { state->inleaf = 1; blk2->index = 0; - cmn_err(CE_ALERT, - "xfs_dir2_leafn_rebalance: picked the wrong leaf? reverting original leaf: " - "blk1->index %d\n", - blk1->index); + xfs_alert(args->dp->i_mount, + "%s: picked the wrong leaf? reverting original leaf: blk1->index %d", + __func__, blk1->index); + } +} + +static int +xfs_dir3_data_block_free( + xfs_da_args_t *args, + struct xfs_dir2_data_hdr *hdr, + struct xfs_dir2_free *free, + xfs_dir2_db_t fdb, + int findex, + struct xfs_buf *fbp, + int longest) +{ + struct xfs_trans *tp = args->trans; + int logfree = 0; + __be16 *bests; + struct xfs_dir3_icfree_hdr freehdr; + + xfs_dir3_free_hdr_from_disk(&freehdr, free); + + bests = xfs_dir3_free_bests_p(tp->t_mountp, free); + if (hdr) { + /* + * Data block is not empty, just set the free entry to the new + * value. + */ + bests[findex] = cpu_to_be16(longest); + xfs_dir2_free_log_bests(tp, fbp, findex, findex); + return 0; + } + + /* One less used entry in the free table. */ + freehdr.nused--; + + /* + * If this was the last entry in the table, we can trim the table size + * back. There might be other entries at the end referring to + * non-existent data blocks, get those too. + */ + if (findex == freehdr.nvalid - 1) { + int i; /* free entry index */ + + for (i = findex - 1; i >= 0; i--) { + if (bests[i] != cpu_to_be16(NULLDATAOFF)) + break; + } + freehdr.nvalid = i + 1; + logfree = 0; + } else { + /* Not the last entry, just punch it out. */ + bests[findex] = cpu_to_be16(NULLDATAOFF); + logfree = 1; } + + xfs_dir3_free_hdr_to_disk(free, &freehdr); + xfs_dir2_free_log_header(tp, fbp); + + /* + * If there are no useful entries left in the block, get rid of the + * block if we can. + */ + if (!freehdr.nused) { + int error; + + error = xfs_dir2_shrink_inode(args, fdb, fbp); + if (error == 0) { + fbp = NULL; + logfree = 0; + } else if (error != ENOSPC || args->total != 0) + return error; + /* + * It's possible to get ENOSPC if there is no + * space reservation. In this case some one + * else will eventually get rid of this block. + */ + } + + /* Log the free entry that changed, unless we got rid of it. */ + if (logfree) + xfs_dir2_free_log_bests(tp, fbp, findex, findex); + return 0; } /* @@ -894,14 +1177,14 @@ static int /* error */ xfs_dir2_leafn_remove( xfs_da_args_t *args, /* operation arguments */ - xfs_dabuf_t *bp, /* leaf buffer */ + struct xfs_buf *bp, /* leaf buffer */ int index, /* leaf entry index */ xfs_da_state_blk_t *dblk, /* data block */ int *rval) /* resulting block needs join */ { - xfs_dir2_data_t *data; /* data block structure */ + xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_db_t db; /* data block number */ - xfs_dabuf_t *dbp; /* data block buffer */ + struct xfs_buf *dbp; /* data block buffer */ xfs_dir2_data_entry_t *dep; /* data block entry */ xfs_inode_t *dp; /* incore directory inode */ xfs_dir2_leaf_t *leaf; /* leaf structure */ @@ -912,18 +1195,24 @@ int needlog; /* need to log data header */ int needscan; /* need to rescan data frees */ xfs_trans_t *tp; /* transaction pointer */ + struct xfs_dir2_data_free *bf; /* bestfree table */ + struct xfs_dir3_icleaf_hdr leafhdr; + struct xfs_dir2_leaf_entry *ents; trace_xfs_dir2_leafn_remove(args, index); dp = args->dp; tp = args->trans; mp = dp->i_mount; - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); + leaf = bp->b_addr; + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + ents = xfs_dir3_leaf_ents_p(leaf); + /* * Point to the entry we're removing. */ - lep = &leaf->ents[index]; + lep = &ents[index]; + /* * Extract the data block and offset from the entry. */ @@ -931,167 +1220,112 @@ ASSERT(dblk->blkno == db); off = xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)); ASSERT(dblk->index == off); + /* * Kill the leaf entry by marking it stale. * Log the leaf block changes. */ - be16_add_cpu(&leaf->hdr.stale, 1); - xfs_dir2_leaf_log_header(tp, bp); + leafhdr.stale++; + xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr); + xfs_dir3_leaf_log_header(tp, bp); + lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); - xfs_dir2_leaf_log_ents(tp, bp, index, index); + xfs_dir3_leaf_log_ents(tp, bp, index, index); + /* * Make the data entry free. Keep track of the longest freespace * in the data block in case it changes. */ dbp = dblk->bp; - data = dbp->data; - dep = (xfs_dir2_data_entry_t *)((char *)data + off); - longest = be16_to_cpu(data->hdr.bestfree[0].length); + hdr = dbp->b_addr; + dep = (xfs_dir2_data_entry_t *)((char *)hdr + off); + bf = xfs_dir3_data_bestfree_p(hdr); + longest = be16_to_cpu(bf[0].length); needlog = needscan = 0; xfs_dir2_data_make_free(tp, dbp, off, - xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); + xfs_dir3_data_entsize(mp, dep->namelen), &needlog, &needscan); /* * Rescan the data block freespaces for bestfree. * Log the data block header if needed. */ if (needscan) - xfs_dir2_data_freescan(mp, data, &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); if (needlog) xfs_dir2_data_log_header(tp, dbp); - xfs_dir2_data_check(dp, dbp); + xfs_dir3_data_check(dp, dbp); /* * If the longest data block freespace changes, need to update * the corresponding freeblock entry. */ - if (longest < be16_to_cpu(data->hdr.bestfree[0].length)) { + if (longest < be16_to_cpu(bf[0].length)) { int error; /* error return value */ - xfs_dabuf_t *fbp; /* freeblock buffer */ + struct xfs_buf *fbp; /* freeblock buffer */ xfs_dir2_db_t fdb; /* freeblock block number */ int findex; /* index in freeblock entries */ xfs_dir2_free_t *free; /* freeblock structure */ - int logfree; /* need to log free entry */ /* * Convert the data block number to a free block, * read in the free block. */ fdb = xfs_dir2_db_to_fdb(mp, db); - if ((error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, fdb), - -1, &fbp, XFS_DATA_FORK))) { + error = xfs_dir2_free_read(tp, dp, xfs_dir2_db_to_da(mp, fdb), + &fbp); + if (error) return error; - } - free = fbp->data; - ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); - ASSERT(be32_to_cpu(free->hdr.firstdb) == - XFS_DIR2_MAX_FREE_BESTS(mp) * - (fdb - XFS_DIR2_FREE_FIRSTDB(mp))); + free = fbp->b_addr; +#ifdef DEBUG + { + struct xfs_dir3_icfree_hdr freehdr; + xfs_dir3_free_hdr_from_disk(&freehdr, free); + ASSERT(freehdr.firstdb == xfs_dir3_free_max_bests(mp) * + (fdb - XFS_DIR2_FREE_FIRSTDB(mp))); + } +#endif /* * Calculate which entry we need to fix. */ findex = xfs_dir2_db_to_fdindex(mp, db); - longest = be16_to_cpu(data->hdr.bestfree[0].length); + longest = be16_to_cpu(bf[0].length); /* * If the data block is now empty we can get rid of it * (usually). */ - if (longest == mp->m_dirblksize - (uint)sizeof(data->hdr)) { + if (longest == mp->m_dirblksize - + xfs_dir3_data_entry_offset(hdr)) { /* * Try to punch out the data block. */ error = xfs_dir2_shrink_inode(args, db, dbp); if (error == 0) { dblk->bp = NULL; - data = NULL; + hdr = NULL; } /* * We can get ENOSPC if there's no space reservation. * In this case just drop the buffer and some one else * will eventually get rid of the empty block. */ - else if (error == ENOSPC && args->total == 0) - xfs_da_buf_done(dbp); - else + else if (!(error == ENOSPC && args->total == 0)) return error; } /* * If we got rid of the data block, we can eliminate that entry * in the free block. */ - if (data == NULL) { - /* - * One less used entry in the free table. - */ - be32_add_cpu(&free->hdr.nused, -1); - xfs_dir2_free_log_header(tp, fbp); - /* - * If this was the last entry in the table, we can - * trim the table size back. There might be other - * entries at the end referring to non-existent - * data blocks, get those too. - */ - if (findex == be32_to_cpu(free->hdr.nvalid) - 1) { - int i; /* free entry index */ - - for (i = findex - 1; - i >= 0 && be16_to_cpu(free->bests[i]) == NULLDATAOFF; - i--) - continue; - free->hdr.nvalid = cpu_to_be32(i + 1); - logfree = 0; - } - /* - * Not the last entry, just punch it out. - */ - else { - free->bests[findex] = cpu_to_be16(NULLDATAOFF); - logfree = 1; - } - /* - * If there are no useful entries left in the block, - * get rid of the block if we can. - */ - if (!free->hdr.nused) { - error = xfs_dir2_shrink_inode(args, fdb, fbp); - if (error == 0) { - fbp = NULL; - logfree = 0; - } else if (error != ENOSPC || args->total != 0) - return error; - /* - * It's possible to get ENOSPC if there is no - * space reservation. In this case some one - * else will eventually get rid of this block. - */ - } - } - /* - * Data block is not empty, just set the free entry to - * the new value. - */ - else { - free->bests[findex] = cpu_to_be16(longest); - logfree = 1; - } - /* - * Log the free entry that changed, unless we got rid of it. - */ - if (logfree) - xfs_dir2_free_log_bests(tp, fbp, findex, findex); - /* - * Drop the buffer if we still have it. - */ - if (fbp) - xfs_da_buf_done(fbp); + error = xfs_dir3_data_block_free(args, hdr, free, + fdb, findex, fbp, longest); + if (error) + return error; } - xfs_dir2_leafn_check(dp, bp); + + xfs_dir3_leaf_check(mp, bp); /* * Return indication of whether this leaf block is empty enough * to justify trying to join it with a neighbor. */ - *rval = - ((uint)sizeof(leaf->hdr) + - (uint)sizeof(leaf->ents[0]) * - (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale))) < + *rval = (xfs_dir3_leaf_hdr_size(leaf) + + (uint)sizeof(ents[0]) * (leafhdr.count - leafhdr.stale)) < mp->m_dir_magicpct; return 0; } @@ -1124,11 +1358,11 @@ /* * Initialize the new leaf block. */ - error = xfs_dir2_leaf_init(args, xfs_dir2_da_to_db(mp, blkno), - &newblk->bp, XFS_DIR2_LEAFN_MAGIC); - if (error) { + error = xfs_dir3_leaf_get_buf(args, xfs_dir2_da_to_db(mp, blkno), + &newblk->bp, XFS_DIR2_LEAFN_MAGIC); + if (error) return error; - } + newblk->blkno = blkno; newblk->magic = XFS_DIR2_LEAFN_MAGIC; /* @@ -1136,7 +1370,7 @@ * block into the leaves. */ xfs_dir2_leafn_rebalance(state, oldblk, newblk); - error = xfs_da_blk_link(state, oldblk, newblk); + error = xfs_da3_blk_link(state, oldblk, newblk); if (error) { return error; } @@ -1152,8 +1386,8 @@ */ oldblk->hashval = xfs_dir2_leafn_lasthash(oldblk->bp, NULL); newblk->hashval = xfs_dir2_leafn_lasthash(newblk->bp, NULL); - xfs_dir2_leafn_check(args->dp, oldblk->bp); - xfs_dir2_leafn_check(args->dp, newblk->bp); + xfs_dir3_leaf_check(mp, oldblk->bp); + xfs_dir3_leaf_check(mp, newblk->bp); return error; } @@ -1173,15 +1407,16 @@ { xfs_da_state_blk_t *blk; /* leaf block */ xfs_dablk_t blkno; /* leaf block number */ - xfs_dabuf_t *bp; /* leaf buffer */ + struct xfs_buf *bp; /* leaf buffer */ int bytes; /* bytes in use */ int count; /* leaf live entry count */ int error; /* error return value */ int forward; /* sibling block direction */ int i; /* sibling counter */ - xfs_da_blkinfo_t *info; /* leaf block header */ xfs_dir2_leaf_t *leaf; /* leaf structure */ int rval; /* result from path_shift */ + struct xfs_dir3_icleaf_hdr leafhdr; + struct xfs_dir2_leaf_entry *ents; /* * Check for the degenerate case of the block being over 50% full. @@ -1189,11 +1424,13 @@ * to coalesce with a sibling. */ blk = &state->path.blk[state->path.active - 1]; - info = blk->bp->data; - ASSERT(be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC); - leaf = (xfs_dir2_leaf_t *)info; - count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); - bytes = (uint)sizeof(leaf->hdr) + count * (uint)sizeof(leaf->ents[0]); + leaf = blk->bp->b_addr; + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + ents = xfs_dir3_leaf_ents_p(leaf); + xfs_dir3_leaf_check(state->args->dp->i_mount, blk->bp); + + count = leafhdr.count - leafhdr.stale; + bytes = xfs_dir3_leaf_hdr_size(leaf) + count * sizeof(ents[0]); if (bytes > (state->blocksize >> 1)) { /* * Blk over 50%, don't try to join. @@ -1212,9 +1449,9 @@ * Make altpath point to the block we want to keep and * path point to the block we want to drop (this one). */ - forward = (info->forw != 0); + forward = (leafhdr.forw != 0); memcpy(&state->altpath, &state->path, sizeof(state->path)); - error = xfs_da_path_shift(state, &state->altpath, forward, 0, + error = xfs_da3_path_shift(state, &state->altpath, forward, 0, &rval); if (error) return error; @@ -1228,36 +1465,39 @@ * We prefer coalescing with the lower numbered sibling so as * to shrink a directory over time. */ - forward = be32_to_cpu(info->forw) < be32_to_cpu(info->back); + forward = leafhdr.forw < leafhdr.back; for (i = 0, bp = NULL; i < 2; forward = !forward, i++) { - blkno = forward ? be32_to_cpu(info->forw) : be32_to_cpu(info->back); + struct xfs_dir3_icleaf_hdr hdr2; + + blkno = forward ? leafhdr.forw : leafhdr.back; if (blkno == 0) continue; /* * Read the sibling leaf block. */ - if ((error = - xfs_da_read_buf(state->args->trans, state->args->dp, blkno, - -1, &bp, XFS_DATA_FORK))) { + error = xfs_dir3_leafn_read(state->args->trans, state->args->dp, + blkno, -1, &bp); + if (error) return error; - } - ASSERT(bp != NULL); + /* * Count bytes in the two blocks combined. */ - leaf = (xfs_dir2_leaf_t *)info; - count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); + count = leafhdr.count - leafhdr.stale; bytes = state->blocksize - (state->blocksize >> 2); - leaf = bp->data; - ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); - count += be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); - bytes -= count * (uint)sizeof(leaf->ents[0]); + + leaf = bp->b_addr; + xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf); + ents = xfs_dir3_leaf_ents_p(leaf); + count += hdr2.count - hdr2.stale; + bytes -= count * sizeof(ents[0]); + /* * Fits with at least 25% to spare. */ if (bytes >= 0) break; - xfs_da_brelse(state->args->trans, bp); + xfs_trans_brelse(state->args->trans, bp); } /* * Didn't like either block, give up. @@ -1266,21 +1506,17 @@ *action = 0; return 0; } - /* - * Done with the sibling leaf block here, drop the dabuf - * so path_shift can get it. - */ - xfs_da_buf_done(bp); + /* * Make altpath point to the block we want to keep (the lower * numbered block) and path point to the block we want to drop. */ memcpy(&state->altpath, &state->path, sizeof(state->path)); if (blkno < blk->blkno) - error = xfs_da_path_shift(state, &state->altpath, forward, 0, + error = xfs_da3_path_shift(state, &state->altpath, forward, 0, &rval); else - error = xfs_da_path_shift(state, &state->path, forward, 0, + error = xfs_da3_path_shift(state, &state->path, forward, 0, &rval); if (error) { return error; @@ -1302,34 +1538,53 @@ xfs_da_args_t *args; /* operation arguments */ xfs_dir2_leaf_t *drop_leaf; /* dead leaf structure */ xfs_dir2_leaf_t *save_leaf; /* surviving leaf structure */ + struct xfs_dir3_icleaf_hdr savehdr; + struct xfs_dir3_icleaf_hdr drophdr; + struct xfs_dir2_leaf_entry *sents; + struct xfs_dir2_leaf_entry *dents; args = state->args; ASSERT(drop_blk->magic == XFS_DIR2_LEAFN_MAGIC); ASSERT(save_blk->magic == XFS_DIR2_LEAFN_MAGIC); - drop_leaf = drop_blk->bp->data; - save_leaf = save_blk->bp->data; - ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); - ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); + drop_leaf = drop_blk->bp->b_addr; + save_leaf = save_blk->bp->b_addr; + + xfs_dir3_leaf_hdr_from_disk(&savehdr, save_leaf); + xfs_dir3_leaf_hdr_from_disk(&drophdr, drop_leaf); + sents = xfs_dir3_leaf_ents_p(save_leaf); + dents = xfs_dir3_leaf_ents_p(drop_leaf); + /* * If there are any stale leaf entries, take this opportunity * to purge them. */ - if (drop_leaf->hdr.stale) - xfs_dir2_leaf_compact(args, drop_blk->bp); - if (save_leaf->hdr.stale) - xfs_dir2_leaf_compact(args, save_blk->bp); + if (drophdr.stale) + xfs_dir3_leaf_compact(args, &drophdr, drop_blk->bp); + if (savehdr.stale) + xfs_dir3_leaf_compact(args, &savehdr, save_blk->bp); + /* * Move the entries from drop to the appropriate end of save. */ - drop_blk->hashval = be32_to_cpu(drop_leaf->ents[be16_to_cpu(drop_leaf->hdr.count) - 1].hashval); + drop_blk->hashval = be32_to_cpu(dents[drophdr.count - 1].hashval); if (xfs_dir2_leafn_order(save_blk->bp, drop_blk->bp)) - xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp, 0, - be16_to_cpu(drop_leaf->hdr.count)); + xfs_dir3_leafn_moveents(args, drop_blk->bp, &drophdr, dents, 0, + save_blk->bp, &savehdr, sents, 0, + drophdr.count); else - xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp, - be16_to_cpu(save_leaf->hdr.count), be16_to_cpu(drop_leaf->hdr.count)); - save_blk->hashval = be32_to_cpu(save_leaf->ents[be16_to_cpu(save_leaf->hdr.count) - 1].hashval); - xfs_dir2_leafn_check(args->dp, save_blk->bp); + xfs_dir3_leafn_moveents(args, drop_blk->bp, &drophdr, dents, 0, + save_blk->bp, &savehdr, sents, + savehdr.count, drophdr.count); + save_blk->hashval = be32_to_cpu(sents[savehdr.count - 1].hashval); + + /* log the changes made when moving the entries */ + xfs_dir3_leaf_hdr_to_disk(save_leaf, &savehdr); + xfs_dir3_leaf_hdr_to_disk(drop_leaf, &drophdr); + xfs_dir3_leaf_log_header(args->trans, save_blk->bp); + xfs_dir3_leaf_log_header(args->trans, drop_blk->bp); + + xfs_dir3_leaf_check(args->dp->i_mount, save_blk->bp); + xfs_dir3_leaf_check(args->dp->i_mount, drop_blk->bp); } /* @@ -1358,7 +1613,7 @@ * Look up the name. We're not supposed to find it, but * this gives us the insertion point. */ - error = xfs_da_node_lookup_int(state, &rval); + error = xfs_da3_node_lookup_int(state, &rval); if (error) rval = error; if (rval != ENOENT) { @@ -1384,7 +1639,7 @@ * It worked, fix the hash values up the btree. */ if (!(args->op_flags & XFS_DA_OP_JUSTCHECK)) - xfs_da_fixhashpath(state, &state->path); + xfs_da3_fixhashpath(state, &state->path); } else { /* * It didn't work, we need to split the leaf block. @@ -1396,7 +1651,7 @@ /* * Split the leaf block and insert the new entry. */ - rval = xfs_da_split(state); + rval = xfs_da3_split(state); } done: xfs_da_state_free(state); @@ -1413,15 +1668,15 @@ xfs_da_args_t *args, /* operation arguments */ xfs_da_state_blk_t *fblk) /* optional freespace block */ { - xfs_dir2_data_t *data; /* data block structure */ + xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_db_t dbno; /* data block number */ - xfs_dabuf_t *dbp; /* data block buffer */ + struct xfs_buf *dbp; /* data block buffer */ xfs_dir2_data_entry_t *dep; /* data entry pointer */ xfs_inode_t *dp; /* incore directory inode */ xfs_dir2_data_unused_t *dup; /* data unused entry pointer */ int error; /* error return value */ xfs_dir2_db_t fbno; /* freespace block number */ - xfs_dabuf_t *fbp; /* freespace buffer */ + struct xfs_buf *fbp; /* freespace buffer */ int findex; /* freespace entry index */ xfs_dir2_free_t *free=NULL; /* freespace block structure */ xfs_dir2_db_t ifbno; /* initial freespace block no */ @@ -1433,11 +1688,14 @@ int needscan; /* need to rescan data frees */ __be16 *tagp; /* data entry tag pointer */ xfs_trans_t *tp; /* transaction pointer */ + __be16 *bests; + struct xfs_dir3_icfree_hdr freehdr; + struct xfs_dir2_data_free *bf; dp = args->dp; mp = dp->i_mount; tp = args->trans; - length = xfs_dir2_data_entsize(args->namelen); + length = xfs_dir3_data_entsize(mp, args->namelen); /* * If we came in with a freespace block that means that lookup * found an entry with our hash value. This is the freespace @@ -1449,37 +1707,38 @@ * Remember initial freespace block number. */ ifbno = fblk->blkno; - free = fbp->data; - ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); + free = fbp->b_addr; findex = fblk->index; + bests = xfs_dir3_free_bests_p(mp, free); + xfs_dir3_free_hdr_from_disk(&freehdr, free); + /* * This means the free entry showed that the data block had * space for our entry, so we remembered it. * Use that data block. */ if (findex >= 0) { - ASSERT(findex < be32_to_cpu(free->hdr.nvalid)); - ASSERT(be16_to_cpu(free->bests[findex]) != NULLDATAOFF); - ASSERT(be16_to_cpu(free->bests[findex]) >= length); - dbno = be32_to_cpu(free->hdr.firstdb) + findex; - } - /* - * The data block looked at didn't have enough room. - * We'll start at the beginning of the freespace entries. - */ - else { + ASSERT(findex < freehdr.nvalid); + ASSERT(be16_to_cpu(bests[findex]) != NULLDATAOFF); + ASSERT(be16_to_cpu(bests[findex]) >= length); + dbno = freehdr.firstdb + findex; + } else { + /* + * The data block looked at didn't have enough room. + * We'll start at the beginning of the freespace entries. + */ dbno = -1; findex = 0; } - } - /* - * Didn't come in with a freespace block, so don't have a data block. - */ - else { + } else { + /* + * Didn't come in with a freespace block, so no data block. + */ ifbno = dbno = -1; fbp = NULL; findex = 0; } + /* * If we don't have a data block yet, we're going to scan the * freespace blocks looking for one. Figure out what the @@ -1525,33 +1784,38 @@ * This should be really rare, so there's no reason * to avoid it. */ - if ((error = xfs_da_read_buf(tp, dp, - xfs_dir2_db_to_da(mp, fbno), -2, &fbp, - XFS_DATA_FORK))) { + error = xfs_dir2_free_try_read(tp, dp, + xfs_dir2_db_to_da(mp, fbno), + &fbp); + if (error) return error; - } - if (unlikely(fbp == NULL)) { + if (!fbp) continue; - } - free = fbp->data; - ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); + free = fbp->b_addr; findex = 0; } /* * Look at the current free entry. Is it good enough? - */ - if (be16_to_cpu(free->bests[findex]) != NULLDATAOFF && - be16_to_cpu(free->bests[findex]) >= length) - dbno = be32_to_cpu(free->hdr.firstdb) + findex; + * + * The bests initialisation should be where the bufer is read in + * the above branch. But gcc is too stupid to realise that bests + * and the freehdr are actually initialised if they are placed + * there, so we have to do it here to avoid warnings. Blech. + */ + bests = xfs_dir3_free_bests_p(mp, free); + xfs_dir3_free_hdr_from_disk(&freehdr, free); + if (be16_to_cpu(bests[findex]) != NULLDATAOFF && + be16_to_cpu(bests[findex]) >= length) + dbno = freehdr.firstdb + findex; else { /* * Are we done with the freeblock? */ - if (++findex == be32_to_cpu(free->hdr.nvalid)) { + if (++findex == freehdr.nvalid) { /* * Drop the block. */ - xfs_da_brelse(tp, fbp); + xfs_trans_brelse(tp, fbp); fbp = NULL; if (fblk && fblk->bp) fblk->bp = NULL; @@ -1566,36 +1830,23 @@ /* * Not allowed to allocate, return failure. */ - if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || - args->total == 0) { - /* - * Drop the freespace buffer unless it came from our - * caller. - */ - if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) - xfs_da_buf_done(fbp); + if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || args->total == 0) return XFS_ERROR(ENOSPC); - } + /* * Allocate and initialize the new data block. */ if (unlikely((error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, &dbno)) || - (error = xfs_dir2_data_init(args, dbno, &dbp)))) { - /* - * Drop the freespace buffer unless it came from our - * caller. - */ - if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) - xfs_da_buf_done(fbp); + (error = xfs_dir3_data_init(args, dbno, &dbp)))) return error; - } + /* * If (somehow) we have a freespace block, get rid of it. */ if (fbp) - xfs_da_brelse(tp, fbp); + xfs_trans_brelse(tp, fbp); if (fblk && fblk->bp) fblk->bp = NULL; @@ -1604,43 +1855,39 @@ * that was just allocated. */ fbno = xfs_dir2_db_to_fdb(mp, dbno); - if (unlikely(error = xfs_da_read_buf(tp, dp, - xfs_dir2_db_to_da(mp, fbno), -2, &fbp, - XFS_DATA_FORK))) { - xfs_da_buf_done(dbp); + error = xfs_dir2_free_try_read(tp, dp, + xfs_dir2_db_to_da(mp, fbno), + &fbp); + if (error) return error; - } + /* * If there wasn't a freespace block, the read will * return a NULL fbp. Allocate and initialize a new one. */ - if( fbp == NULL ) { - if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, - &fbno))) { + if (!fbp) { + error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, + &fbno); + if (error) return error; - } if (unlikely(xfs_dir2_db_to_fdb(mp, dbno) != fbno)) { - cmn_err(CE_ALERT, - "xfs_dir2_node_addname_int: dir ino " - "%llu needed freesp block %lld for\n" - " data block %lld, got %lld\n" - " ifbno %llu lastfbno %d\n", - (unsigned long long)dp->i_ino, + xfs_alert(mp, + "%s: dir ino %llu needed freesp block %lld for\n" + " data block %lld, got %lld ifbno %llu lastfbno %d", + __func__, (unsigned long long)dp->i_ino, (long long)xfs_dir2_db_to_fdb(mp, dbno), (long long)dbno, (long long)fbno, (unsigned long long)ifbno, lastfbno); if (fblk) { - cmn_err(CE_ALERT, - " fblk 0x%p blkno %llu " - "index %d magic 0x%x\n", + xfs_alert(mp, + " fblk 0x%p blkno %llu index %d magic 0x%x", fblk, (unsigned long long)fblk->blkno, fblk->index, fblk->magic); } else { - cmn_err(CE_ALERT, - " ... fblk is NULL\n"); + xfs_alert(mp, " ... fblk is NULL"); } XFS_ERROR_REPORT("xfs_dir2_node_addname_int", XFS_ERRLEVEL_LOW, mp); @@ -1650,27 +1897,22 @@ /* * Get a buffer for the new block. */ - if ((error = xfs_da_get_buf(tp, dp, - xfs_dir2_db_to_da(mp, fbno), - -1, &fbp, XFS_DATA_FORK))) { + error = xfs_dir3_free_get_buf(tp, dp, fbno, &fbp); + if (error) return error; - } - ASSERT(fbp != NULL); + free = fbp->b_addr; + bests = xfs_dir3_free_bests_p(mp, free); + xfs_dir3_free_hdr_from_disk(&freehdr, free); /* - * Initialize the new block to be empty, and remember - * its first slot as our empty slot. + * Remember the first slot as our empty slot. */ - free = fbp->data; - free->hdr.magic = cpu_to_be32(XFS_DIR2_FREE_MAGIC); - free->hdr.firstdb = cpu_to_be32( - (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) * - XFS_DIR2_MAX_FREE_BESTS(mp)); - free->hdr.nvalid = 0; - free->hdr.nused = 0; + freehdr.firstdb = (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) * + xfs_dir3_free_max_bests(mp); } else { - free = fbp->data; - ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); + free = fbp->b_addr; + bests = xfs_dir3_free_bests_p(mp, free); + xfs_dir3_free_hdr_from_disk(&freehdr, free); } /* @@ -1681,20 +1923,21 @@ * If it's after the end of the current entries in the * freespace block, extend that table. */ - if (findex >= be32_to_cpu(free->hdr.nvalid)) { - ASSERT(findex < XFS_DIR2_MAX_FREE_BESTS(mp)); - free->hdr.nvalid = cpu_to_be32(findex + 1); + if (findex >= freehdr.nvalid) { + ASSERT(findex < xfs_dir3_free_max_bests(mp)); + freehdr.nvalid = findex + 1; /* * Tag new entry so nused will go up. */ - free->bests[findex] = cpu_to_be16(NULLDATAOFF); + bests[findex] = cpu_to_be16(NULLDATAOFF); } /* * If this entry was for an empty data block * (this should always be true) then update the header. */ - if (be16_to_cpu(free->bests[findex]) == NULLDATAOFF) { - be32_add_cpu(&free->hdr.nused, 1); + if (bests[findex] == cpu_to_be16(NULLDATAOFF)) { + freehdr.nused++; + xfs_dir3_free_hdr_to_disk(fbp->b_addr, &freehdr); xfs_dir2_free_log_header(tp, fbp); } /* @@ -1702,8 +1945,9 @@ * We haven't allocated the data entry yet so this will * change again. */ - data = dbp->data; - free->bests[findex] = data->hdr.bestfree[0].length; + hdr = dbp->b_addr; + bf = xfs_dir3_data_bestfree_p(hdr); + bests[findex] = bf[0].length; logfree = 1; } /* @@ -1713,36 +1957,32 @@ /* * If just checking, we succeeded. */ - if (args->op_flags & XFS_DA_OP_JUSTCHECK) { - if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) - xfs_da_buf_done(fbp); + if (args->op_flags & XFS_DA_OP_JUSTCHECK) return 0; - } + /* * Read the data block in. */ - if (unlikely( - error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, dbno), - -1, &dbp, XFS_DATA_FORK))) { - if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) - xfs_da_buf_done(fbp); + error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(mp, dbno), + -1, &dbp); + if (error) return error; - } - data = dbp->data; + hdr = dbp->b_addr; + bf = xfs_dir3_data_bestfree_p(hdr); logfree = 0; } - ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) >= length); + ASSERT(be16_to_cpu(bf[0].length) >= length); /* * Point to the existing unused space. */ dup = (xfs_dir2_data_unused_t *) - ((char *)data + be16_to_cpu(data->hdr.bestfree[0].offset)); + ((char *)hdr + be16_to_cpu(bf[0].offset)); needscan = needlog = 0; /* * Mark the first part of the unused space, inuse for us. */ xfs_dir2_data_use_free(tp, dbp, dup, - (xfs_dir2_data_aoff_t)((char *)dup - (char *)data), length, + (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length, &needlog, &needscan); /* * Fill in the new entry and log it. @@ -1751,14 +1991,15 @@ dep->inumber = cpu_to_be64(args->inumber); dep->namelen = args->namelen; memcpy(dep->name, args->name, dep->namelen); - tagp = xfs_dir2_data_entry_tag_p(dep); - *tagp = cpu_to_be16((char *)dep - (char *)data); + xfs_dir3_dirent_put_ftype(mp, dep, args->filetype); + tagp = xfs_dir3_data_entry_tag_p(mp, dep); + *tagp = cpu_to_be16((char *)dep - (char *)hdr); xfs_dir2_data_log_entry(tp, dbp, dep); /* * Rescan the block for bestfree if needed. */ if (needscan) - xfs_dir2_data_freescan(mp, data, &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); /* * Log the data block header if needed. */ @@ -1767,8 +2008,9 @@ /* * If the freespace entry is now wrong, update it. */ - if (be16_to_cpu(free->bests[findex]) != be16_to_cpu(data->hdr.bestfree[0].length)) { - free->bests[findex] = data->hdr.bestfree[0].length; + bests = xfs_dir3_free_bests_p(mp, free); /* gcc is so stupid */ + if (be16_to_cpu(bests[findex]) != be16_to_cpu(bf[0].length)) { + bests[findex] = bf[0].length; logfree = 1; } /* @@ -1777,22 +2019,16 @@ if (logfree) xfs_dir2_free_log_bests(tp, fbp, findex, findex); /* - * If the caller didn't hand us the freespace block, drop it. - */ - if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) - xfs_da_buf_done(fbp); - /* * Return the data block and offset in args, then drop the data block. */ args->blkno = (xfs_dablk_t)dbno; args->index = be16_to_cpu(*tagp); - xfs_da_buf_done(dbp); return 0; } /* * Lookup an entry in a node-format directory. - * All the real work happens in xfs_da_node_lookup_int. + * All the real work happens in xfs_da3_node_lookup_int. * The only real output is the inode number of the entry. */ int /* error */ @@ -1817,29 +2053,30 @@ /* * Fill in the path to the entry in the cursor. */ - error = xfs_da_node_lookup_int(state, &rval); + error = xfs_da3_node_lookup_int(state, &rval); if (error) rval = error; else if (rval == ENOENT && args->cmpresult == XFS_CMP_CASE) { /* If a CI match, dup the actual name and return EEXIST */ xfs_dir2_data_entry_t *dep; - dep = (xfs_dir2_data_entry_t *)((char *)state->extrablk.bp-> - data + state->extrablk.index); + dep = (xfs_dir2_data_entry_t *) + ((char *)state->extrablk.bp->b_addr + + state->extrablk.index); rval = xfs_dir_cilookup_result(args, dep->name, dep->namelen); } /* * Release the btree blocks and leaf block. */ for (i = 0; i < state->path.active; i++) { - xfs_da_brelse(args->trans, state->path.blk[i].bp); + xfs_trans_brelse(args->trans, state->path.blk[i].bp); state->path.blk[i].bp = NULL; } /* * Release the data block if we have it. */ if (state->extravalid && state->extrablk.bp) { - xfs_da_brelse(args->trans, state->extrablk.bp); + xfs_trans_brelse(args->trans, state->extrablk.bp); state->extrablk.bp = NULL; } xfs_da_state_free(state); @@ -1851,12 +2088,12 @@ */ int /* error */ xfs_dir2_node_removename( - xfs_da_args_t *args) /* operation arguments */ + struct xfs_da_args *args) /* operation arguments */ { - xfs_da_state_blk_t *blk; /* leaf block */ + struct xfs_da_state_blk *blk; /* leaf block */ int error; /* error return value */ int rval; /* operation return value */ - xfs_da_state_t *state; /* btree cursor */ + struct xfs_da_state *state; /* btree cursor */ trace_xfs_dir2_node_removename(args); @@ -1868,19 +2105,18 @@ state->mp = args->dp->i_mount; state->blocksize = state->mp->m_dirblksize; state->node_ents = state->mp->m_dir_node_ents; - /* - * Look up the entry we're deleting, set up the cursor. - */ - error = xfs_da_node_lookup_int(state, &rval); + + /* Look up the entry we're deleting, set up the cursor. */ + error = xfs_da3_node_lookup_int(state, &rval); if (error) - rval = error; - /* - * Didn't find it, upper layer screwed up. - */ + goto out_free; + + /* Didn't find it, upper layer screwed up. */ if (rval != EEXIST) { - xfs_da_state_free(state); - return rval; + error = rval; + goto out_free; } + blk = &state->path.blk[state->path.active - 1]; ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC); ASSERT(state->extravalid); @@ -1891,21 +2127,22 @@ error = xfs_dir2_leafn_remove(args, blk->bp, blk->index, &state->extrablk, &rval); if (error) - return error; + goto out_free; /* * Fix the hash values up the btree. */ - xfs_da_fixhashpath(state, &state->path); + xfs_da3_fixhashpath(state, &state->path); /* * If we need to join leaf blocks, do it. */ if (rval && state->path.active > 1) - error = xfs_da_join(state); + error = xfs_da3_join(state); /* * If no errors so far, try conversion to leaf format. */ if (!error) error = xfs_dir2_node_to_leaf(state); +out_free: xfs_da_state_free(state); return error; } @@ -1918,7 +2155,7 @@ xfs_da_args_t *args) /* operation arguments */ { xfs_da_state_blk_t *blk; /* leaf block */ - xfs_dir2_data_t *data; /* data block structure */ + xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_data_entry_t *dep; /* data entry changed */ int error; /* error return value */ int i; /* btree level */ @@ -1942,7 +2179,7 @@ /* * Lookup the entry to change in the btree. */ - error = xfs_da_node_lookup_int(state, &rval); + error = xfs_da3_node_lookup_int(state, &rval); if (error) { rval = error; } @@ -1951,27 +2188,31 @@ * and locked it. But paranoia is good. */ if (rval == EEXIST) { + struct xfs_dir2_leaf_entry *ents; /* * Find the leaf entry. */ blk = &state->path.blk[state->path.active - 1]; ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC); - leaf = blk->bp->data; - lep = &leaf->ents[blk->index]; + leaf = blk->bp->b_addr; + ents = xfs_dir3_leaf_ents_p(leaf); + lep = &ents[blk->index]; ASSERT(state->extravalid); /* * Point to the data entry. */ - data = state->extrablk.bp->data; - ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC); + hdr = state->extrablk.bp->b_addr; + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)); dep = (xfs_dir2_data_entry_t *) - ((char *)data + + ((char *)hdr + xfs_dir2_dataptr_to_off(state->mp, be32_to_cpu(lep->address))); ASSERT(inum != be64_to_cpu(dep->inumber)); /* * Fill in the new inode number and log the entry. */ dep->inumber = cpu_to_be64(inum); + xfs_dir3_dirent_put_ftype(state->mp, dep, args->filetype); xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep); rval = 0; } @@ -1979,14 +2220,14 @@ * Didn't find it, and we're holding a data block. Drop it. */ else if (state->extravalid) { - xfs_da_brelse(args->trans, state->extrablk.bp); + xfs_trans_brelse(args->trans, state->extrablk.bp); state->extrablk.bp = NULL; } /* * Release all the buffers in the cursor. */ for (i = 0; i < state->path.active; i++) { - xfs_da_brelse(args->trans, state->path.blk[i].bp); + xfs_trans_brelse(args->trans, state->path.blk[i].bp); state->path.blk[i].bp = NULL; } xfs_da_state_free(state); @@ -2003,12 +2244,13 @@ xfs_fileoff_t fo, /* free block number */ int *rvalp) /* out: did something */ { - xfs_dabuf_t *bp; /* freespace buffer */ + struct xfs_buf *bp; /* freespace buffer */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return code */ xfs_dir2_free_t *free; /* freespace structure */ xfs_mount_t *mp; /* filesystem mount point */ xfs_trans_t *tp; /* transaction pointer */ + struct xfs_dir3_icfree_hdr freehdr; dp = args->dp; mp = dp->i_mount; @@ -2016,25 +2258,23 @@ /* * Read the freespace block. */ - if (unlikely(error = xfs_da_read_buf(tp, dp, (xfs_dablk_t)fo, -2, &bp, - XFS_DATA_FORK))) { + error = xfs_dir2_free_try_read(tp, dp, fo, &bp); + if (error) return error; - } - /* * There can be holes in freespace. If fo is a hole, there's * nothing to do. */ - if (bp == NULL) { + if (!bp) return 0; - } - free = bp->data; - ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); + free = bp->b_addr; + xfs_dir3_free_hdr_from_disk(&freehdr, free); + /* * If there are used entries, there's nothing to do. */ - if (be32_to_cpu(free->hdr.nused) > 0) { - xfs_da_brelse(tp, bp); + if (freehdr.nused > 0) { + xfs_trans_brelse(tp, bp); *rvalp = 0; return 0; } @@ -2050,7 +2290,7 @@ * pieces. This is the last block of an extent. */ ASSERT(error != ENOSPC); - xfs_da_brelse(tp, bp); + xfs_trans_brelse(tp, bp); return error; } /* diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2_priv.h xfsprogs-3.2.1ubuntu1/libxfs/xfs_dir2_priv.h --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2_priv.h 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_dir2_priv.h 2013-10-10 21:07:17.000000000 +0000 @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_DIR2_PRIV_H__ +#define __XFS_DIR2_PRIV_H__ + +struct dir_context; + +/* xfs_dir2.c */ +extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino); +extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, + xfs_dir2_db_t *dbp); +extern int xfs_dir_cilookup_result(struct xfs_da_args *args, + const unsigned char *name, int len); + +#define S_SHIFT 12 +extern const unsigned char xfs_mode_to_ftype[]; + +extern unsigned char xfs_dir3_get_dtype(struct xfs_mount *mp, + __uint8_t filetype); + + +/* xfs_dir2_block.c */ +extern int xfs_dir3_block_read(struct xfs_trans *tp, struct xfs_inode *dp, + struct xfs_buf **bpp); +extern int xfs_dir2_block_addname(struct xfs_da_args *args); +extern int xfs_dir2_block_lookup(struct xfs_da_args *args); +extern int xfs_dir2_block_removename(struct xfs_da_args *args); +extern int xfs_dir2_block_replace(struct xfs_da_args *args); +extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args, + struct xfs_buf *lbp, struct xfs_buf *dbp); + +/* xfs_dir2_data.c */ +#ifdef DEBUG +#define xfs_dir3_data_check(dp,bp) __xfs_dir3_data_check(dp, bp); +#else +#define xfs_dir3_data_check(dp,bp) +#endif + +extern int __xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp); +extern int xfs_dir3_data_read(struct xfs_trans *tp, struct xfs_inode *dp, + xfs_dablk_t bno, xfs_daddr_t mapped_bno, struct xfs_buf **bpp); +extern int xfs_dir3_data_readahead(struct xfs_trans *tp, struct xfs_inode *dp, + xfs_dablk_t bno, xfs_daddr_t mapped_bno); + +extern struct xfs_dir2_data_free * +xfs_dir2_data_freeinsert(struct xfs_dir2_data_hdr *hdr, + struct xfs_dir2_data_unused *dup, int *loghead); +extern int xfs_dir3_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno, + struct xfs_buf **bpp); + +/* xfs_dir2_leaf.c */ +extern int xfs_dir3_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp, + xfs_dablk_t fbno, xfs_daddr_t mappedbno, struct xfs_buf **bpp); +extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args, + struct xfs_buf *dbp); +extern int xfs_dir2_leaf_addname(struct xfs_da_args *args); +extern void xfs_dir3_leaf_compact(struct xfs_da_args *args, + struct xfs_dir3_icleaf_hdr *leafhdr, struct xfs_buf *bp); +extern void xfs_dir3_leaf_compact_x1(struct xfs_dir3_icleaf_hdr *leafhdr, + struct xfs_dir2_leaf_entry *ents, int *indexp, + int *lowstalep, int *highstalep, int *lowlogp, int *highlogp); +extern int xfs_dir3_leaf_get_buf(struct xfs_da_args *args, xfs_dir2_db_t bno, + struct xfs_buf **bpp, __uint16_t magic); +extern void xfs_dir3_leaf_log_ents(struct xfs_trans *tp, struct xfs_buf *bp, + int first, int last); +extern void xfs_dir3_leaf_log_header(struct xfs_trans *tp, + struct xfs_buf *bp); +extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args); +extern int xfs_dir2_leaf_removename(struct xfs_da_args *args); +extern int xfs_dir2_leaf_replace(struct xfs_da_args *args); +extern int xfs_dir2_leaf_search_hash(struct xfs_da_args *args, + struct xfs_buf *lbp); +extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args, + struct xfs_buf *lbp, xfs_dir2_db_t db); +extern struct xfs_dir2_leaf_entry * +xfs_dir3_leaf_find_entry(struct xfs_dir3_icleaf_hdr *leafhdr, + struct xfs_dir2_leaf_entry *ents, int index, int compact, + int lowstale, int highstale, int *lfloglow, int *lfloghigh); +extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state); + +extern void xfs_dir3_leaf_hdr_from_disk(struct xfs_dir3_icleaf_hdr *to, + struct xfs_dir2_leaf *from); +extern void xfs_dir3_leaf_hdr_to_disk(struct xfs_dir2_leaf *to, + struct xfs_dir3_icleaf_hdr *from); +extern bool xfs_dir3_leaf_check_int(struct xfs_mount *mp, + struct xfs_dir3_icleaf_hdr *hdr, struct xfs_dir2_leaf *leaf); + +/* xfs_dir2_node.c */ +extern int xfs_dir2_leaf_to_node(struct xfs_da_args *args, + struct xfs_buf *lbp); +extern xfs_dahash_t xfs_dir2_leafn_lasthash(struct xfs_buf *bp, int *count); +extern int xfs_dir2_leafn_lookup_int(struct xfs_buf *bp, + struct xfs_da_args *args, int *indexp, + struct xfs_da_state *state); +extern int xfs_dir2_leafn_order(struct xfs_buf *leaf1_bp, + struct xfs_buf *leaf2_bp); +extern int xfs_dir2_leafn_split(struct xfs_da_state *state, + struct xfs_da_state_blk *oldblk, struct xfs_da_state_blk *newblk); +extern int xfs_dir2_leafn_toosmall(struct xfs_da_state *state, int *action); +extern void xfs_dir2_leafn_unbalance(struct xfs_da_state *state, + struct xfs_da_state_blk *drop_blk, + struct xfs_da_state_blk *save_blk); +extern int xfs_dir2_node_addname(struct xfs_da_args *args); +extern int xfs_dir2_node_lookup(struct xfs_da_args *args); +extern int xfs_dir2_node_removename(struct xfs_da_args *args); +extern int xfs_dir2_node_replace(struct xfs_da_args *args); +extern int xfs_dir2_node_trim_free(struct xfs_da_args *args, xfs_fileoff_t fo, + int *rvalp); +extern int xfs_dir2_free_read(struct xfs_trans *tp, struct xfs_inode *dp, + xfs_dablk_t fbno, struct xfs_buf **bpp); + +/* xfs_dir2_sf.c */ +extern int xfs_dir2_block_sfsize(struct xfs_inode *dp, + struct xfs_dir2_data_hdr *block, struct xfs_dir2_sf_hdr *sfhp); +extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_buf *bp, + int size, xfs_dir2_sf_hdr_t *sfhp); +extern int xfs_dir2_sf_addname(struct xfs_da_args *args); +extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino); +extern int xfs_dir2_sf_lookup(struct xfs_da_args *args); +extern int xfs_dir2_sf_removename(struct xfs_da_args *args); +extern int xfs_dir2_sf_replace(struct xfs_da_args *args); + +/* xfs_dir2_readdir.c */ +extern int xfs_readdir(struct xfs_inode *dp, struct dir_context *ctx, + size_t bufsize); + +#endif /* __XFS_DIR2_PRIV_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2_sf.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_dir2_sf.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2_sf.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_dir2_sf.c 2014-05-02 00:09:16.000000000 +0000 @@ -15,7 +15,6 @@ * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #include /* @@ -41,6 +40,89 @@ #endif /* XFS_BIG_INUMS */ /* + * Inode numbers in short-form directories can come in two versions, + * either 4 bytes or 8 bytes wide. These helpers deal with the + * two forms transparently by looking at the headers i8count field. + * + * For 64-bit inode number the most significant byte must be zero. + */ +static xfs_ino_t +xfs_dir2_sf_get_ino( + struct xfs_dir2_sf_hdr *hdr, + xfs_dir2_inou_t *from) +{ + if (hdr->i8count) + return get_unaligned_be64(&from->i8.i) & 0x00ffffffffffffffULL; + else + return get_unaligned_be32(&from->i4.i); +} + +static void +xfs_dir2_sf_put_ino( + struct xfs_dir2_sf_hdr *hdr, + xfs_dir2_inou_t *to, + xfs_ino_t ino) +{ + ASSERT((ino & 0xff00000000000000ULL) == 0); + + if (hdr->i8count) + put_unaligned_be64(ino, &to->i8.i); + else + put_unaligned_be32(ino, &to->i4.i); +} + +xfs_ino_t +xfs_dir2_sf_get_parent_ino( + struct xfs_dir2_sf_hdr *hdr) +{ + return xfs_dir2_sf_get_ino(hdr, &hdr->parent); +} + +void +xfs_dir2_sf_put_parent_ino( + struct xfs_dir2_sf_hdr *hdr, + xfs_ino_t ino) +{ + xfs_dir2_sf_put_ino(hdr, &hdr->parent, ino); +} + +/* + * In short-form directory entries the inode numbers are stored at variable + * offset behind the entry name. If the entry stores a filetype value, then it + * sits between the name and the inode number. Hence the inode numbers may only + * be accessed through the helpers below. + */ +static xfs_dir2_inou_t * +xfs_dir3_sfe_inop( + struct xfs_mount *mp, + struct xfs_dir2_sf_entry *sfep) +{ + __uint8_t *ptr = &sfep->name[sfep->namelen]; + if (xfs_sb_version_hasftype(&mp->m_sb)) + ptr++; + return (xfs_dir2_inou_t *)ptr; +} + +xfs_ino_t +xfs_dir3_sfe_get_ino( + struct xfs_mount *mp, + struct xfs_dir2_sf_hdr *hdr, + struct xfs_dir2_sf_entry *sfep) +{ + return xfs_dir2_sf_get_ino(hdr, xfs_dir3_sfe_inop(mp, sfep)); +} + +void +xfs_dir3_sfe_put_ino( + struct xfs_mount *mp, + struct xfs_dir2_sf_hdr *hdr, + struct xfs_dir2_sf_entry *sfep, + xfs_ino_t ino) +{ + xfs_dir2_sf_put_ino(hdr, xfs_dir3_sfe_inop(mp, sfep), ino); +} + +/* * Given a block directory (dp/block), calculate its size as a shortform (sf) * directory and a header for the sf directory, if it will fit it the * space currently present in the inode. If it won't fit, the output @@ -49,7 +131,7 @@ int /* size for sf form */ xfs_dir2_block_sfsize( xfs_inode_t *dp, /* incore inode pointer */ - xfs_dir2_block_t *block, /* block directory data */ + xfs_dir2_data_hdr_t *hdr, /* block directory data */ xfs_dir2_sf_hdr_t *sfhp) /* output: header for sf form */ { xfs_dir2_dataptr_t addr; /* data entry address */ @@ -65,11 +147,18 @@ int namelen; /* total name bytes */ xfs_ino_t parent = 0; /* parent inode number */ int size=0; /* total computed size */ + int has_ftype; mp = dp->i_mount; + /* + * if there is a filetype field, add the extra byte to the namelen + * for each entry that we see. + */ + has_ftype = xfs_sb_version_hasftype(&mp->m_sb) ? 1 : 0; + count = i8count = namelen = 0; - btp = xfs_dir2_block_tail_p(mp, block); + btp = xfs_dir2_block_tail_p(mp, hdr); blp = xfs_dir2_block_leaf_p(btp); /* @@ -82,7 +171,7 @@ * Calculate the pointer to the entry at hand. */ dep = (xfs_dir2_data_entry_t *) - ((char *)block + xfs_dir2_dataptr_to_off(mp, addr)); + ((char *)hdr + xfs_dir2_dataptr_to_off(mp, addr)); /* * Detect . and .., so we can special-case them. * . is not included in sf directories. @@ -96,9 +185,10 @@ if (!isdot) i8count += be64_to_cpu(dep->inumber) > XFS_DIR2_MAX_SHORT_INUM; #endif + /* take into account the file type field */ if (!isdot && !isdotdot) { count++; - namelen += dep->namelen; + namelen += dep->namelen + has_ftype; } else if (isdotdot) parent = be64_to_cpu(dep->inumber); /* @@ -119,7 +209,7 @@ */ sfhp->count = count; sfhp->i8count = i8count; - xfs_dir2_sf_put_inumber((xfs_dir2_sf_t *)sfhp, &parent, &sfhp->parent); + xfs_dir2_sf_put_parent_ino(sfhp, parent); return size; } @@ -130,11 +220,11 @@ int /* error */ xfs_dir2_block_to_sf( xfs_da_args_t *args, /* operation arguments */ - xfs_dabuf_t *bp, /* block buffer */ + struct xfs_buf *bp, int size, /* shortform directory size */ xfs_dir2_sf_hdr_t *sfhp) /* shortform directory hdr */ { - xfs_dir2_block_t *block; /* block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_block_tail_t *btp; /* block tail pointer */ xfs_dir2_data_entry_t *dep; /* data entry pointer */ xfs_inode_t *dp; /* incore directory inode */ @@ -145,8 +235,7 @@ xfs_mount_t *mp; /* filesystem mount point */ char *ptr; /* current data pointer */ xfs_dir2_sf_entry_t *sfep; /* shortform entry */ - xfs_dir2_sf_t *sfp; /* shortform structure */ - xfs_ino_t temp; + xfs_dir2_sf_hdr_t *sfp; /* shortform directory header */ trace_xfs_dir2_block_to_sf(args); @@ -157,13 +246,14 @@ * Make a copy of the block data, so we can shrink the inode * and add local data. */ - block = kmem_alloc(mp->m_dirblksize, KM_SLEEP); - memcpy(block, bp->data, mp->m_dirblksize); + hdr = kmem_alloc(mp->m_dirblksize, KM_SLEEP); + memcpy(hdr, bp->b_addr, mp->m_dirblksize); logflags = XFS_ILOG_CORE; if ((error = xfs_dir2_shrink_inode(args, mp->m_dirdatablk, bp))) { ASSERT(error != ENOSPC); goto out; } + /* * The buffer is now unconditionally gone, whether * xfs_dir2_shrink_inode worked or not. @@ -179,14 +269,14 @@ /* * Copy the header into the newly allocate local space. */ - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; memcpy(sfp, sfhp, xfs_dir2_sf_hdr_size(sfhp->i8count)); dp->i_d.di_size = size; /* * Set up to loop over the block's entries. */ - btp = xfs_dir2_block_tail_p(mp, block); - ptr = (char *)block->u; + btp = xfs_dir2_block_tail_p(mp, hdr); + ptr = (char *)xfs_dir3_data_entry_p(hdr); endptr = (char *)xfs_dir2_block_leaf_p(btp); sfep = xfs_dir2_sf_firstentry(sfp); /* @@ -214,7 +304,7 @@ else if (dep->namelen == 2 && dep->name[0] == '.' && dep->name[1] == '.') ASSERT(be64_to_cpu(dep->inumber) == - xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent)); + xfs_dir2_sf_get_parent_ino(sfp)); /* * Normal entry, copy it into shortform. */ @@ -222,20 +312,22 @@ sfep->namelen = dep->namelen; xfs_dir2_sf_put_offset(sfep, (xfs_dir2_data_aoff_t) - ((char *)dep - (char *)block)); + ((char *)dep - (char *)hdr)); memcpy(sfep->name, dep->name, dep->namelen); - temp = be64_to_cpu(dep->inumber); - xfs_dir2_sf_put_inumber(sfp, &temp, - xfs_dir2_sf_inumberp(sfep)); - sfep = xfs_dir2_sf_nextentry(sfp, sfep); + xfs_dir3_sfe_put_ino(mp, sfp, sfep, + be64_to_cpu(dep->inumber)); + xfs_dir3_sfe_put_ftype(mp, sfp, sfep, + xfs_dir3_dirent_get_ftype(mp, dep)); + + sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep); } - ptr += xfs_dir2_data_entsize(dep->namelen); + ptr += xfs_dir3_data_entsize(mp, dep->namelen); } ASSERT((char *)sfep - (char *)sfp == size); xfs_dir2_sf_check(args); out: xfs_trans_log_inode(args->trans, dp, logflags); - kmem_free(block); + kmem_free(hdr); return error; } @@ -258,7 +350,7 @@ xfs_dir2_data_aoff_t offset = 0; /* offset for new entry */ int old_isize; /* di_size before adding name */ int pick; /* which algorithm to use */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ xfs_dir2_sf_entry_t *sfep = NULL; /* shortform entry */ trace_xfs_dir2_sf_addname(args); @@ -275,19 +367,19 @@ } ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); ASSERT(dp->i_df.if_u1.if_data != NULL); - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->i8count)); /* * Compute entry (and change in) size. */ - add_entsize = xfs_dir2_sf_entsize_byname(sfp, args->namelen); + add_entsize = xfs_dir3_sf_entsize(dp->i_mount, sfp, args->namelen); incr_isize = add_entsize; objchange = 0; #if XFS_BIG_INUMS /* * Do we have to change to 8 byte inodes? */ - if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->hdr.i8count == 0) { + if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->i8count == 0) { /* * Yes, adjust the entry size and the total size. */ @@ -295,7 +387,7 @@ (uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t); incr_isize += - (sfp->hdr.count + 2) * + (sfp->count + 2) * ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)); objchange = 1; @@ -365,21 +457,22 @@ { int byteoff; /* byte offset in sf dir */ xfs_inode_t *dp; /* incore directory inode */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ dp = args->dp; - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; byteoff = (int)((char *)sfep - (char *)sfp); /* * Grow the in-inode space. */ - xfs_idata_realloc(dp, xfs_dir2_sf_entsize_byname(sfp, args->namelen), - XFS_DATA_FORK); + xfs_idata_realloc(dp, + xfs_dir3_sf_entsize(dp->i_mount, sfp, args->namelen), + XFS_DATA_FORK); /* * Need to set up again due to realloc of the inode data. */ - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; sfep = (xfs_dir2_sf_entry_t *)((char *)sfp + byteoff); /* * Fill in the new entry. @@ -387,15 +480,16 @@ sfep->namelen = args->namelen; xfs_dir2_sf_put_offset(sfep, offset); memcpy(sfep->name, args->name, sfep->namelen); - xfs_dir2_sf_put_inumber(sfp, &args->inumber, - xfs_dir2_sf_inumberp(sfep)); + xfs_dir3_sfe_put_ino(dp->i_mount, sfp, sfep, args->inumber); + xfs_dir3_sfe_put_ftype(dp->i_mount, sfp, sfep, args->filetype); + /* * Update the header and inode. */ - sfp->hdr.count++; + sfp->count++; #if XFS_BIG_INUMS if (args->inumber > XFS_DIR2_MAX_SHORT_INUM) - sfp->hdr.i8count++; + sfp->i8count++; #endif dp->i_d.di_size = new_isize; xfs_dir2_sf_check(args); @@ -425,32 +519,34 @@ xfs_dir2_data_aoff_t offset; /* current offset value */ int old_isize; /* previous di_size */ xfs_dir2_sf_entry_t *oldsfep; /* entry in original dir */ - xfs_dir2_sf_t *oldsfp; /* original shortform dir */ + xfs_dir2_sf_hdr_t *oldsfp; /* original shortform dir */ xfs_dir2_sf_entry_t *sfep; /* entry in new dir */ - xfs_dir2_sf_t *sfp; /* new shortform dir */ + xfs_dir2_sf_hdr_t *sfp; /* new shortform dir */ + struct xfs_mount *mp; /* * Copy the old directory to the stack buffer. */ dp = args->dp; + mp = dp->i_mount; - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; old_isize = (int)dp->i_d.di_size; buf = kmem_alloc(old_isize, KM_SLEEP); - oldsfp = (xfs_dir2_sf_t *)buf; + oldsfp = (xfs_dir2_sf_hdr_t *)buf; memcpy(oldsfp, sfp, old_isize); /* * Loop over the old directory finding the place we're going * to insert the new entry. * If it's going to end up at the end then oldsfep will point there. */ - for (offset = XFS_DIR2_DATA_FIRST_OFFSET, + for (offset = xfs_dir3_data_first_offset(mp), oldsfep = xfs_dir2_sf_firstentry(oldsfp), - add_datasize = xfs_dir2_data_entsize(args->namelen), + add_datasize = xfs_dir3_data_entsize(mp, args->namelen), eof = (char *)oldsfep == &buf[old_isize]; !eof; - offset = new_offset + xfs_dir2_data_entsize(oldsfep->namelen), - oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep), + offset = new_offset + xfs_dir3_data_entsize(mp, oldsfep->namelen), + oldsfep = xfs_dir3_sf_nextentry(mp, oldsfp, oldsfep), eof = (char *)oldsfep == &buf[old_isize]) { new_offset = xfs_dir2_sf_get_offset(oldsfep); if (offset + add_datasize <= new_offset) @@ -466,7 +562,7 @@ /* * Reset the pointer since the buffer was reallocated. */ - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; /* * Copy the first part of the directory, including the header. */ @@ -479,18 +575,18 @@ sfep->namelen = args->namelen; xfs_dir2_sf_put_offset(sfep, offset); memcpy(sfep->name, args->name, sfep->namelen); - xfs_dir2_sf_put_inumber(sfp, &args->inumber, - xfs_dir2_sf_inumberp(sfep)); - sfp->hdr.count++; + xfs_dir3_sfe_put_ino(mp, sfp, sfep, args->inumber); + xfs_dir3_sfe_put_ftype(mp, sfp, sfep, args->filetype); + sfp->count++; #if XFS_BIG_INUMS if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange) - sfp->hdr.i8count++; + sfp->i8count++; #endif /* * If there's more left to copy, do that. */ if (!eof) { - sfep = xfs_dir2_sf_nextentry(sfp, sfep); + sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep); memcpy(sfep, oldsfep, old_isize - nbytes); } kmem_free(buf); @@ -518,16 +614,16 @@ xfs_mount_t *mp; /* filesystem mount point */ xfs_dir2_data_aoff_t offset; /* data block offset */ xfs_dir2_sf_entry_t *sfep; /* shortform entry */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ int size; /* entry's data size */ int used; /* data bytes used */ dp = args->dp; mp = dp->i_mount; - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - size = xfs_dir2_data_entsize(args->namelen); - offset = XFS_DIR2_DATA_FIRST_OFFSET; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + size = xfs_dir3_data_entsize(mp, args->namelen); + offset = xfs_dir3_data_first_offset(mp); sfep = xfs_dir2_sf_firstentry(sfp); holefit = 0; /* @@ -535,19 +631,19 @@ * Keep track of data offset and whether we've seen a place * to insert the new entry. */ - for (i = 0; i < sfp->hdr.count; i++) { + for (i = 0; i < sfp->count; i++) { if (!holefit) holefit = offset + size <= xfs_dir2_sf_get_offset(sfep); offset = xfs_dir2_sf_get_offset(sfep) + - xfs_dir2_data_entsize(sfep->namelen); - sfep = xfs_dir2_sf_nextentry(sfp, sfep); + xfs_dir3_data_entsize(mp, sfep->namelen); + sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep); } /* * Calculate data bytes used excluding the new entry, if this * was a data block (block form directory). */ used = offset + - (sfp->hdr.count + 3) * (uint)sizeof(xfs_dir2_leaf_entry_t) + + (sfp->count + 3) * (uint)sizeof(xfs_dir2_leaf_entry_t) + (uint)sizeof(xfs_dir2_block_tail_t); /* * If it won't fit in a block form then we can't insert it, @@ -593,32 +689,35 @@ xfs_ino_t ino; /* entry inode number */ int offset; /* data offset */ xfs_dir2_sf_entry_t *sfep; /* shortform dir entry */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ + struct xfs_mount *mp; dp = args->dp; + mp = dp->i_mount; - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - offset = XFS_DIR2_DATA_FIRST_OFFSET; - ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + offset = xfs_dir3_data_first_offset(mp); + ino = xfs_dir2_sf_get_parent_ino(sfp); i8count = ino > XFS_DIR2_MAX_SHORT_INUM; for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); - i < sfp->hdr.count; - i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { + i < sfp->count; + i++, sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep)) { ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset); - ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); + ino = xfs_dir3_sfe_get_ino(mp, sfp, sfep); i8count += ino > XFS_DIR2_MAX_SHORT_INUM; offset = xfs_dir2_sf_get_offset(sfep) + - xfs_dir2_data_entsize(sfep->namelen); + xfs_dir3_data_entsize(mp, sfep->namelen); + ASSERT(xfs_dir3_sfe_get_ftype(mp, sfp, sfep) < + XFS_DIR3_FT_MAX); } - ASSERT(i8count == sfp->hdr.i8count); + ASSERT(i8count == sfp->i8count); ASSERT(XFS_BIG_INUMS || i8count == 0); ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size); ASSERT(offset + - (sfp->hdr.count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) + - (uint)sizeof(xfs_dir2_block_tail_t) <= - dp->i_mount->m_dirblksize); + (sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) + + (uint)sizeof(xfs_dir2_block_tail_t) <= mp->m_dirblksize); } #endif /* DEBUG */ @@ -632,7 +731,7 @@ { xfs_inode_t *dp; /* incore directory inode */ int i8count; /* parent inode is an 8-byte number */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ int size; /* directory size */ trace_xfs_dir2_sf_create(args); @@ -662,13 +761,13 @@ /* * Fill in the header, */ - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - sfp->hdr.i8count = i8count; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + sfp->i8count = i8count; /* * Now can put in the inode number, since i8count is set. */ - xfs_dir2_sf_put_inumber(sfp, &pino, &sfp->hdr.parent); - sfp->hdr.count = 0; + xfs_dir2_sf_put_parent_ino(sfp, pino); + sfp->count = 0; dp->i_d.di_size = size; xfs_dir2_sf_check(args); xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); @@ -687,7 +786,7 @@ int i; /* entry index */ int error; xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ enum xfs_dacmp cmp; /* comparison result */ xfs_dir2_sf_entry_t *ci_sfep; /* case-insens. entry */ @@ -706,14 +805,15 @@ } ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); ASSERT(dp->i_df.if_u1.if_data != NULL); - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->i8count)); /* * Special case for . */ if (args->namelen == 1 && args->name[0] == '.') { args->inumber = dp->i_ino; args->cmpresult = XFS_CMP_EXACT; + args->filetype = XFS_DIR3_FT_DIR; return XFS_ERROR(EEXIST); } /* @@ -721,16 +821,17 @@ */ if (args->namelen == 2 && args->name[0] == '.' && args->name[1] == '.') { - args->inumber = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); + args->inumber = xfs_dir2_sf_get_parent_ino(sfp); args->cmpresult = XFS_CMP_EXACT; + args->filetype = XFS_DIR3_FT_DIR; return XFS_ERROR(EEXIST); } /* * Loop over all the entries trying to match ours. */ ci_sfep = NULL; - for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->hdr.count; - i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { + for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; + i++, sfep = xfs_dir3_sf_nextentry(dp->i_mount, sfp, sfep)) { /* * Compare name and if it's an exact match, return the inode * number. If it's the first case-insensitive match, store the @@ -740,8 +841,10 @@ sfep->namelen); if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { args->cmpresult = cmp; - args->inumber = xfs_dir2_sf_get_inumber(sfp, - xfs_dir2_sf_inumberp(sfep)); + args->inumber = xfs_dir3_sfe_get_ino(dp->i_mount, + sfp, sfep); + args->filetype = xfs_dir3_sfe_get_ftype(dp->i_mount, + sfp, sfep); if (cmp == XFS_CMP_EXACT) return XFS_ERROR(EEXIST); ci_sfep = sfep; @@ -773,7 +876,7 @@ int newsize; /* new inode size */ int oldsize; /* old inode size */ xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ trace_xfs_dir2_sf_removename(args); @@ -790,32 +893,31 @@ } ASSERT(dp->i_df.if_bytes == oldsize); ASSERT(dp->i_df.if_u1.if_data != NULL); - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(oldsize >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + ASSERT(oldsize >= xfs_dir2_sf_hdr_size(sfp->i8count)); /* * Loop over the old directory entries. * Find the one we're deleting. */ - for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->hdr.count; - i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { + for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; + i++, sfep = xfs_dir3_sf_nextentry(dp->i_mount, sfp, sfep)) { if (xfs_da_compname(args, sfep->name, sfep->namelen) == XFS_CMP_EXACT) { - ASSERT(xfs_dir2_sf_get_inumber(sfp, - xfs_dir2_sf_inumberp(sfep)) == - args->inumber); + ASSERT(xfs_dir3_sfe_get_ino(dp->i_mount, sfp, sfep) == + args->inumber); break; } } /* * Didn't find it. */ - if (i == sfp->hdr.count) + if (i == sfp->count) return XFS_ERROR(ENOENT); /* * Calculate sizes. */ byteoff = (int)((char *)sfep - (char *)sfp); - entsize = xfs_dir2_sf_entsize_byname(sfp, args->namelen); + entsize = xfs_dir3_sf_entsize(dp->i_mount, sfp, args->namelen); newsize = oldsize - entsize; /* * Copy the part if any after the removed entry, sliding it down. @@ -826,22 +928,22 @@ /* * Fix up the header and file size. */ - sfp->hdr.count--; + sfp->count--; dp->i_d.di_size = newsize; /* * Reallocate, making it smaller. */ xfs_idata_realloc(dp, newsize - oldsize, XFS_DATA_FORK); - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; #if XFS_BIG_INUMS /* * Are we changing inode number size? */ if (args->inumber > XFS_DIR2_MAX_SHORT_INUM) { - if (sfp->hdr.i8count == 1) + if (sfp->i8count == 1) xfs_dir2_sf_toino4(args); else - sfp->hdr.i8count--; + sfp->i8count--; } #endif xfs_dir2_sf_check(args); @@ -865,7 +967,7 @@ int i8elevated; /* sf_toino8 set i8count=1 */ #endif xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ trace_xfs_dir2_sf_replace(args); @@ -881,19 +983,19 @@ } ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); ASSERT(dp->i_df.if_u1.if_data != NULL); - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->i8count)); #if XFS_BIG_INUMS /* * New inode number is large, and need to convert to 8-byte inodes. */ - if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->hdr.i8count == 0) { + if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->i8count == 0) { int error; /* error return value */ int newsize; /* new inode size */ newsize = dp->i_df.if_bytes + - (sfp->hdr.count + 1) * + (sfp->count + 1) * ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)); /* @@ -911,7 +1013,7 @@ */ xfs_dir2_sf_toino8(args); i8elevated = 1; - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; } else i8elevated = 0; #endif @@ -922,34 +1024,35 @@ if (args->namelen == 2 && args->name[0] == '.' && args->name[1] == '.') { #if XFS_BIG_INUMS || defined(DEBUG) - ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); + ino = xfs_dir2_sf_get_parent_ino(sfp); ASSERT(args->inumber != ino); #endif - xfs_dir2_sf_put_inumber(sfp, &args->inumber, &sfp->hdr.parent); + xfs_dir2_sf_put_parent_ino(sfp, args->inumber); } /* * Normal entry, look for the name. */ else { - for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); - i < sfp->hdr.count; - i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { + for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; + i++, sfep = xfs_dir3_sf_nextentry(dp->i_mount, sfp, sfep)) { if (xfs_da_compname(args, sfep->name, sfep->namelen) == XFS_CMP_EXACT) { #if XFS_BIG_INUMS || defined(DEBUG) - ino = xfs_dir2_sf_get_inumber(sfp, - xfs_dir2_sf_inumberp(sfep)); + ino = xfs_dir3_sfe_get_ino(dp->i_mount, + sfp, sfep); ASSERT(args->inumber != ino); #endif - xfs_dir2_sf_put_inumber(sfp, &args->inumber, - xfs_dir2_sf_inumberp(sfep)); + xfs_dir3_sfe_put_ino(dp->i_mount, sfp, sfep, + args->inumber); + xfs_dir3_sfe_put_ftype(dp->i_mount, sfp, sfep, + args->filetype); break; } } /* * Didn't find it. */ - if (i == sfp->hdr.count) { + if (i == sfp->count) { ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); #if XFS_BIG_INUMS if (i8elevated) @@ -967,10 +1070,10 @@ /* * And the old count was one, so need to convert to small. */ - if (sfp->hdr.i8count == 1) + if (sfp->i8count == 1) xfs_dir2_sf_toino4(args); else - sfp->hdr.i8count--; + sfp->i8count--; } /* * See if the old number was small, the new number is large. @@ -981,9 +1084,9 @@ * add to the i8count unless we just converted to 8-byte * inodes (which does an implied i8count = 1) */ - ASSERT(sfp->hdr.i8count != 0); + ASSERT(sfp->i8count != 0); if (!i8elevated) - sfp->hdr.i8count++; + sfp->i8count++; } #endif xfs_dir2_sf_check(args); @@ -1003,17 +1106,18 @@ char *buf; /* old dir's buffer */ xfs_inode_t *dp; /* incore directory inode */ int i; /* entry index */ - xfs_ino_t ino; /* entry inode number */ int newsize; /* new inode size */ xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ - xfs_dir2_sf_t *oldsfp; /* old sf directory */ + xfs_dir2_sf_hdr_t *oldsfp; /* old sf directory */ int oldsize; /* old inode size */ xfs_dir2_sf_entry_t *sfep; /* new sf entry */ - xfs_dir2_sf_t *sfp; /* new sf directory */ + xfs_dir2_sf_hdr_t *sfp; /* new sf directory */ + struct xfs_mount *mp; trace_xfs_dir2_sf_toino4(args); dp = args->dp; + mp = dp->i_mount; /* * Copy the old directory to the buffer. @@ -1022,44 +1126,44 @@ */ oldsize = dp->i_df.if_bytes; buf = kmem_alloc(oldsize, KM_SLEEP); - oldsfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(oldsfp->hdr.i8count == 1); + oldsfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + ASSERT(oldsfp->i8count == 1); memcpy(buf, oldsfp, oldsize); /* * Compute the new inode size. */ newsize = oldsize - - (oldsfp->hdr.count + 1) * + (oldsfp->count + 1) * ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)); xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK); xfs_idata_realloc(dp, newsize, XFS_DATA_FORK); /* * Reset our pointers, the data has moved. */ - oldsfp = (xfs_dir2_sf_t *)buf; - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + oldsfp = (xfs_dir2_sf_hdr_t *)buf; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; /* * Fill in the new header. */ - sfp->hdr.count = oldsfp->hdr.count; - sfp->hdr.i8count = 0; - ino = xfs_dir2_sf_get_inumber(oldsfp, &oldsfp->hdr.parent); - xfs_dir2_sf_put_inumber(sfp, &ino, &sfp->hdr.parent); + sfp->count = oldsfp->count; + sfp->i8count = 0; + xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp)); /* * Copy the entries field by field. */ for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), oldsfep = xfs_dir2_sf_firstentry(oldsfp); - i < sfp->hdr.count; - i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep), - oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) { + i < sfp->count; + i++, sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep), + oldsfep = xfs_dir3_sf_nextentry(mp, oldsfp, oldsfep)) { sfep->namelen = oldsfep->namelen; sfep->offset = oldsfep->offset; memcpy(sfep->name, oldsfep->name, sfep->namelen); - ino = xfs_dir2_sf_get_inumber(oldsfp, - xfs_dir2_sf_inumberp(oldsfep)); - xfs_dir2_sf_put_inumber(sfp, &ino, xfs_dir2_sf_inumberp(sfep)); + xfs_dir3_sfe_put_ino(mp, sfp, sfep, + xfs_dir3_sfe_get_ino(mp, oldsfp, oldsfep)); + xfs_dir3_sfe_put_ftype(mp, sfp, sfep, + xfs_dir3_sfe_get_ftype(mp, oldsfp, oldsfep)); } /* * Clean up the inode. @@ -1081,17 +1185,18 @@ char *buf; /* old dir's buffer */ xfs_inode_t *dp; /* incore directory inode */ int i; /* entry index */ - xfs_ino_t ino; /* entry inode number */ int newsize; /* new inode size */ xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ - xfs_dir2_sf_t *oldsfp; /* old sf directory */ + xfs_dir2_sf_hdr_t *oldsfp; /* old sf directory */ int oldsize; /* old inode size */ xfs_dir2_sf_entry_t *sfep; /* new sf entry */ - xfs_dir2_sf_t *sfp; /* new sf directory */ + xfs_dir2_sf_hdr_t *sfp; /* new sf directory */ + struct xfs_mount *mp; trace_xfs_dir2_sf_toino8(args); dp = args->dp; + mp = dp->i_mount; /* * Copy the old directory to the buffer. @@ -1100,44 +1205,44 @@ */ oldsize = dp->i_df.if_bytes; buf = kmem_alloc(oldsize, KM_SLEEP); - oldsfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(oldsfp->hdr.i8count == 0); + oldsfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + ASSERT(oldsfp->i8count == 0); memcpy(buf, oldsfp, oldsize); /* * Compute the new inode size. */ newsize = oldsize + - (oldsfp->hdr.count + 1) * + (oldsfp->count + 1) * ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)); xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK); xfs_idata_realloc(dp, newsize, XFS_DATA_FORK); /* * Reset our pointers, the data has moved. */ - oldsfp = (xfs_dir2_sf_t *)buf; - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + oldsfp = (xfs_dir2_sf_hdr_t *)buf; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; /* * Fill in the new header. */ - sfp->hdr.count = oldsfp->hdr.count; - sfp->hdr.i8count = 1; - ino = xfs_dir2_sf_get_inumber(oldsfp, &oldsfp->hdr.parent); - xfs_dir2_sf_put_inumber(sfp, &ino, &sfp->hdr.parent); + sfp->count = oldsfp->count; + sfp->i8count = 1; + xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp)); /* * Copy the entries field by field. */ for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), oldsfep = xfs_dir2_sf_firstentry(oldsfp); - i < sfp->hdr.count; - i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep), - oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) { + i < sfp->count; + i++, sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep), + oldsfep = xfs_dir3_sf_nextentry(mp, oldsfp, oldsfep)) { sfep->namelen = oldsfep->namelen; sfep->offset = oldsfep->offset; memcpy(sfep->name, oldsfep->name, sfep->namelen); - ino = xfs_dir2_sf_get_inumber(oldsfp, - xfs_dir2_sf_inumberp(oldsfep)); - xfs_dir2_sf_put_inumber(sfp, &ino, xfs_dir2_sf_inumberp(sfep)); + xfs_dir3_sfe_put_ino(mp, sfp, sfep, + xfs_dir3_sfe_get_ino(mp, oldsfp, oldsfep)); + xfs_dir3_sfe_put_ftype(mp, sfp, sfep, + xfs_dir3_sfe_get_ftype(mp, oldsfp, oldsfep)); } /* * Clean up the inode. diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_dquot_buf.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_dquot_buf.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_dquot_buf.c 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_dquot_buf.c 2014-05-02 00:09:16.000000000 +0000 @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2000-2006 Silicon Graphics, Inc. + * Copyright (c) 2013 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "xfs.h" + +int +xfs_calc_dquots_per_chunk( + struct xfs_mount *mp, + unsigned int nbblks) /* basic block units */ +{ + ASSERT(nbblks > 0); + return BBTOB(nbblks) / sizeof(xfs_dqblk_t); +} + +/* + * Do some primitive error checking on ondisk dquot data structures. + */ +int +xfs_dqcheck( + struct xfs_mount *mp, + xfs_disk_dquot_t *ddq, + xfs_dqid_t id, + uint type, /* used only when IO_dorepair is true */ + uint flags, + char *str) +{ + xfs_dqblk_t *d = (xfs_dqblk_t *)ddq; + int errs = 0; + + /* + * We can encounter an uninitialized dquot buffer for 2 reasons: + * 1. If we crash while deleting the quotainode(s), and those blks got + * used for user data. This is because we take the path of regular + * file deletion; however, the size field of quotainodes is never + * updated, so all the tricks that we play in itruncate_finish + * don't quite matter. + * + * 2. We don't play the quota buffers when there's a quotaoff logitem. + * But the allocation will be replayed so we'll end up with an + * uninitialized quota block. + * + * This is all fine; things are still consistent, and we haven't lost + * any quota information. Just don't complain about bad dquot blks. + */ + if (ddq->d_magic != cpu_to_be16(XFS_DQUOT_MAGIC)) { + if (flags & XFS_QMOPT_DOWARN) + xfs_alert(mp, + "%s : XFS dquot ID 0x%x, magic 0x%x != 0x%x", + str, id, be16_to_cpu(ddq->d_magic), XFS_DQUOT_MAGIC); + errs++; + } + if (ddq->d_version != XFS_DQUOT_VERSION) { + if (flags & XFS_QMOPT_DOWARN) + xfs_alert(mp, + "%s : XFS dquot ID 0x%x, version 0x%x != 0x%x", + str, id, ddq->d_version, XFS_DQUOT_VERSION); + errs++; + } + + if (ddq->d_flags != XFS_DQ_USER && + ddq->d_flags != XFS_DQ_PROJ && + ddq->d_flags != XFS_DQ_GROUP) { + if (flags & XFS_QMOPT_DOWARN) + xfs_alert(mp, + "%s : XFS dquot ID 0x%x, unknown flags 0x%x", + str, id, ddq->d_flags); + errs++; + } + + if (id != -1 && id != be32_to_cpu(ddq->d_id)) { + if (flags & XFS_QMOPT_DOWARN) + xfs_alert(mp, + "%s : ondisk-dquot 0x%p, ID mismatch: " + "0x%x expected, found id 0x%x", + str, ddq, id, be32_to_cpu(ddq->d_id)); + errs++; + } + + if (!errs && ddq->d_id) { + if (ddq->d_blk_softlimit && + be64_to_cpu(ddq->d_bcount) > + be64_to_cpu(ddq->d_blk_softlimit)) { + if (!ddq->d_btimer) { + if (flags & XFS_QMOPT_DOWARN) + xfs_alert(mp, + "%s : Dquot ID 0x%x (0x%p) BLK TIMER NOT STARTED", + str, (int)be32_to_cpu(ddq->d_id), ddq); + errs++; + } + } + if (ddq->d_ino_softlimit && + be64_to_cpu(ddq->d_icount) > + be64_to_cpu(ddq->d_ino_softlimit)) { + if (!ddq->d_itimer) { + if (flags & XFS_QMOPT_DOWARN) + xfs_alert(mp, + "%s : Dquot ID 0x%x (0x%p) INODE TIMER NOT STARTED", + str, (int)be32_to_cpu(ddq->d_id), ddq); + errs++; + } + } + if (ddq->d_rtb_softlimit && + be64_to_cpu(ddq->d_rtbcount) > + be64_to_cpu(ddq->d_rtb_softlimit)) { + if (!ddq->d_rtbtimer) { + if (flags & XFS_QMOPT_DOWARN) + xfs_alert(mp, + "%s : Dquot ID 0x%x (0x%p) RTBLK TIMER NOT STARTED", + str, (int)be32_to_cpu(ddq->d_id), ddq); + errs++; + } + } + } + + if (!errs || !(flags & XFS_QMOPT_DQREPAIR)) + return errs; + + if (flags & XFS_QMOPT_DOWARN) + xfs_notice(mp, "Re-initializing dquot ID 0x%x", id); + + /* + * Typically, a repair is only requested by quotacheck. + */ + ASSERT(id != -1); + ASSERT(flags & XFS_QMOPT_DQREPAIR); + memset(d, 0, sizeof(xfs_dqblk_t)); + + d->dd_diskdq.d_magic = cpu_to_be16(XFS_DQUOT_MAGIC); + d->dd_diskdq.d_version = XFS_DQUOT_VERSION; + d->dd_diskdq.d_flags = type; + d->dd_diskdq.d_id = cpu_to_be32(id); + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + uuid_copy(&d->dd_uuid, &mp->m_sb.sb_uuid); + xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk), + XFS_DQUOT_CRC_OFF); + } + + return errs; +} + +STATIC bool +xfs_dquot_buf_verify_crc( + struct xfs_mount *mp, + struct xfs_buf *bp) +{ + struct xfs_dqblk *d = (struct xfs_dqblk *)bp->b_addr; + int ndquots; + int i; + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return true; + + /* + * if we are in log recovery, the quota subsystem has not been + * initialised so we have no quotainfo structure. In that case, we need + * to manually calculate the number of dquots in the buffer. + */ + if (mp->m_quotainfo) + ndquots = mp->m_quotainfo->qi_dqperchunk; + else + ndquots = xfs_calc_dquots_per_chunk(mp, + XFS_BB_TO_FSB(mp, bp->b_length)); + + for (i = 0; i < ndquots; i++, d++) { + if (!xfs_verify_cksum((char *)d, sizeof(struct xfs_dqblk), + XFS_DQUOT_CRC_OFF)) + return false; + if (!uuid_equal(&d->dd_uuid, &mp->m_sb.sb_uuid)) + return false; + } + return true; +} + +STATIC bool +xfs_dquot_buf_verify( + struct xfs_mount *mp, + struct xfs_buf *bp) +{ + struct xfs_dqblk *d = (struct xfs_dqblk *)bp->b_addr; + xfs_dqid_t id = 0; + int ndquots; + int i; + + /* + * if we are in log recovery, the quota subsystem has not been + * initialised so we have no quotainfo structure. In that case, we need + * to manually calculate the number of dquots in the buffer. + */ + if (mp->m_quotainfo) + ndquots = mp->m_quotainfo->qi_dqperchunk; + else + ndquots = xfs_calc_dquots_per_chunk(mp, bp->b_length); + + /* + * On the first read of the buffer, verify that each dquot is valid. + * We don't know what the id of the dquot is supposed to be, just that + * they should be increasing monotonically within the buffer. If the + * first id is corrupt, then it will fail on the second dquot in the + * buffer so corruptions could point to the wrong dquot in this case. + */ + for (i = 0; i < ndquots; i++) { + struct xfs_disk_dquot *ddq; + int error; + + ddq = &d[i].dd_diskdq; + + if (i == 0) + id = be32_to_cpu(ddq->d_id); + + error = xfs_dqcheck(mp, ddq, id + i, 0, XFS_QMOPT_DOWARN, + "xfs_dquot_buf_verify"); + if (error) + return false; + } + return true; +} + +static void +xfs_dquot_buf_read_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + + if (!xfs_dquot_buf_verify_crc(mp, bp)) + xfs_buf_ioerror(bp, EFSBADCRC); + else if (!xfs_dquot_buf_verify(mp, bp)) + xfs_buf_ioerror(bp, EFSCORRUPTED); + + if (bp->b_error) + xfs_verifier_error(bp); +} + +/* + * we don't calculate the CRC here as that is done when the dquot is flushed to + * the buffer after the update is done. This ensures that the dquot in the + * buffer always has an up-to-date CRC value. + */ +void +xfs_dquot_buf_write_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + + if (!xfs_dquot_buf_verify(mp, bp)) { + xfs_buf_ioerror(bp, EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } +} + +const struct xfs_buf_ops xfs_dquot_buf_ops = { + .verify_read = xfs_dquot_buf_read_verify, + .verify_write = xfs_dquot_buf_write_verify, +}; + diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs.h xfsprogs-3.2.1ubuntu1/libxfs/xfs.h --- xfsprogs-3.1.9ubuntu2/libxfs/xfs.h 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs.h 2014-06-19 22:42:17.000000000 +0000 @@ -43,14 +43,52 @@ */ #include +#include "xfs_dir2_priv.h" -typedef struct { dev_t dev; } xfs_buftarg_t; +#undef ASSERT +#define ASSERT(ex) assert(ex) -typedef __uint32_t uint_t; +typedef __uint32_t uint_t; typedef __uint32_t inst_t; /* an instruction */ +/* + * Argument structure for xfs_bmap_alloc. + */ +typedef struct xfs_bmalloca { + xfs_fsblock_t *firstblock; /* i/o first block allocated */ + struct xfs_bmap_free *flist; /* bmap freelist */ + struct xfs_trans *tp; /* transaction pointer */ + struct xfs_inode *ip; /* incore inode pointer */ + struct xfs_bmbt_irec prev; /* extent before the new one */ + struct xfs_bmbt_irec got; /* extent after, or delayed */ + + xfs_fileoff_t offset; /* offset in file filling in */ + xfs_extlen_t length; /* i/o length asked/allocated */ + xfs_fsblock_t blkno; /* starting block of new extent */ + + struct xfs_btree_cur *cur; /* btree cursor */ + xfs_extnum_t idx; /* current extent index */ + int nallocs;/* number of extents alloc'd */ + int logflags;/* flags for transaction logging */ + + xfs_extlen_t total; /* total blocks needed for xaction */ + xfs_extlen_t minlen; /* minimum allocation size (blocks) */ + xfs_extlen_t minleft; /* amount must be left after alloc */ + char eof; /* set if allocating past last extent */ + char wasdel; /* replacing a delayed allocation */ + char userdata;/* set if is user data */ + char aeof; /* allocated space at eof */ + char conv; /* overwriting unwritten extents */ + char stack_switch; + int flags; +} xfs_bmalloca_t; + +#define xfs_bmapi_allocate __xfs_bmapi_allocate + +#ifndef EWRONGFS +#define EWRONGFS EINVAL +#endif -#define m_ddev_targp m_dev #define xfs_error_level 0 #define STATIC static @@ -64,10 +102,22 @@ #define IHOLD(ip) ((void) 0) -#define XFS_CORRUPTION_ERROR(e,l,mp,m) ((void) 0) +#define XFS_IGET_CREATE 0x1 +#define XFS_IGET_UNTRUSTED 0x2 + +/* stop unused var warnings by assigning mp to itself */ +#define XFS_CORRUPTION_ERROR(e,l,mp,m) do { \ + (mp) = (mp); \ + cmn_err(CE_ALERT, "%s: XFS_CORRUPTION_ERROR", (e)); \ +} while (0) + +#define XFS_ERROR_REPORT(e,l,mp) do { \ + (mp) = (mp); \ + cmn_err(CE_ALERT, "%s: XFS_ERROR_REPORT", (e)); \ +} while (0) + #define XFS_QM_DQATTACH(mp,ip,flags) 0 #define XFS_ERROR(e) (e) -#define XFS_ERROR_REPORT(e,l,mp) ((void) 0) #define XFS_ERRLEVEL_LOW 1 #define XFS_FORCED_SHUTDOWN(mp) 0 #define XFS_ILOCK_EXCL 0 @@ -87,6 +137,8 @@ #define __return_address __builtin_return_address(0) #endif +#define XFS_DQUOT_CLUSTER_SIZE_FSB (xfs_filblks_t)1 + /* miscellaneous kernel routines not in user space */ #define down_read(a) ((void) 0) #define up_read(a) ((void) 0) @@ -99,10 +151,10 @@ #define rcu_read_unlock() ((void) 0) /* - * random32 is used for di_gen inode allocation, it must be zero for libxfs + * prandom_u32 is used for di_gen inode allocation, it must be zero for libxfs * or all sorts of badness can occur! */ -#define random32() 0 +#define prandom_u32() 0 #define PAGE_CACHE_SIZE getpagesize() @@ -124,35 +176,6 @@ ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) -static inline __uint32_t __get_unaligned_be32(const __uint8_t *p) -{ - return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; -} - -static inline __uint64_t get_unaligned_be64(void *p) -{ - return (__uint64_t)__get_unaligned_be32(p) << 32 | - __get_unaligned_be32(p + 4); -} - -static inline void __put_unaligned_be16(__uint16_t val, __uint8_t *p) -{ - *p++ = val >> 8; - *p++ = val; -} - -static inline void __put_unaligned_be32(__uint32_t val, __uint8_t *p) -{ - __put_unaligned_be16(val >> 16, p); - __put_unaligned_be16(val, p + 2); -} - -static inline void put_unaligned_be64(__uint64_t val, void *p) -{ - __put_unaligned_be32(val >> 32, p); - __put_unaligned_be32(val, p + 4); -} - static inline __attribute__((const)) int is_power_of_2(unsigned long n) @@ -185,29 +208,43 @@ return 0; } +static inline __uint64_t +roundup_64(__uint64_t x, __uint32_t y) +{ + x += y - 1; + do_div(x, y); + return x * y; +} + /* buffer management */ #define XFS_BUF_LOCK 0 #define XFS_BUF_TRYLOCK 0 #define XBF_LOCK XFS_BUF_LOCK #define XBF_TRYLOCK XFS_BUF_TRYLOCK #define XBF_DONT_BLOCK 0 +#define XBF_UNMAPPED 0 +#define XBF_DONE 0 #define XFS_BUF_GETERROR(bp) 0 #define XFS_BUF_DONE(bp) ((bp)->b_flags |= LIBXFS_B_UPTODATE) #define XFS_BUF_ISDONE(bp) ((bp)->b_flags & LIBXFS_B_UPTODATE) -#define XFS_BUF_STALE(bp) ((bp)->b_flags |= LIBXFS_B_STALE) +#define xfs_buf_stale(bp) ((bp)->b_flags |= LIBXFS_B_STALE) #define XFS_BUF_UNDELAYWRITE(bp) ((bp)->b_flags &= ~LIBXFS_B_DIRTY) #define XFS_BUF_SET_VTYPE(a,b) ((void) 0) #define XFS_BUF_SET_VTYPE_REF(a,b,c) ((void) 0) #define XFS_BUF_SET_BDSTRAT_FUNC(a,b) ((void) 0) -#define xfs_incore(bt,blkno,len,lockit) 0 +/* avoid gcc warning */ +#define xfs_incore(bt,blkno,len,lockit) ({ \ + typeof(blkno) __foo = (blkno); \ + typeof(len) __bar = (len); \ + (blkno) = __foo; \ + (len) = __bar; /* no set-but-unused warning */ \ + NULL; \ +}) #define xfs_buf_relse(bp) libxfs_putbuf(bp) -#define xfs_read_buf(mp,devp,blkno,len,f,bpp) \ - (*(bpp) = libxfs_readbuf((devp), \ - (blkno), (len), 1), 0) -#define xfs_buf_get(devp,blkno,len,f) \ - (libxfs_getbuf((devp), (blkno), (len))) -#define xfs_bwrite(mp,bp) libxfs_writebuf((bp), 0) +#define xfs_buf_get(devp,blkno,len,f) (libxfs_getbuf((devp), (blkno), (len))) +#define xfs_bwrite(bp) libxfs_writebuf((bp), 0) +#define xfs_buf_delwri_queue(bp, bl) libxfs_writebuf((bp), 0) #define XBRW_READ LIBXFS_BREAD #define XBRW_WRITE LIBXFS_BWRITE @@ -220,6 +257,7 @@ #define XFS_MOUNT_SMALL_INUMS 0 /* ignored in userspace */ #define XFS_MOUNT_WSYNC 0 /* ignored in userspace */ #define XFS_MOUNT_NOALIGN 0 /* ignored in userspace */ +#define XFS_MOUNT_IKEEP 0 /* ignored in userspace */ #define xfs_icsb_modify_counters(mp, field, delta, rsvd) \ xfs_mod_incore_sb(mp, field, delta, rsvd) @@ -242,38 +280,56 @@ #define xfs_mod_incore_sb libxfs_mod_incore_sb #define xfs_trans_alloc libxfs_trans_alloc +#define xfs_trans_add_item libxfs_trans_add_item #define xfs_trans_bhold libxfs_trans_bhold #define xfs_trans_binval libxfs_trans_binval #define xfs_trans_bjoin libxfs_trans_bjoin #define xfs_trans_brelse libxfs_trans_brelse #define xfs_trans_commit libxfs_trans_commit #define xfs_trans_cancel libxfs_trans_cancel +#define xfs_trans_del_item libxfs_trans_del_item #define xfs_trans_dup libxfs_trans_dup #define xfs_trans_get_buf libxfs_trans_get_buf #define xfs_trans_getsb libxfs_trans_getsb #define xfs_trans_iget libxfs_trans_iget -#define xfs_trans_ihold libxfs_trans_ihold #define xfs_trans_ijoin libxfs_trans_ijoin #define xfs_trans_ijoin_ref libxfs_trans_ijoin_ref +#define xfs_trans_init libxfs_trans_init #define xfs_trans_inode_alloc_buf libxfs_trans_inode_alloc_buf #define xfs_trans_log_buf libxfs_trans_log_buf #define xfs_trans_log_inode libxfs_trans_log_inode #define xfs_trans_mod_sb libxfs_trans_mod_sb #define xfs_trans_read_buf libxfs_trans_read_buf +#define xfs_trans_read_buf_map libxfs_trans_read_buf_map +#define xfs_trans_roll libxfs_trans_roll +#define xfs_trans_get_buf_map libxfs_trans_get_buf_map #define xfs_trans_reserve libxfs_trans_reserve #define xfs_trans_get_block_res(tp) 1 #define xfs_trans_set_sync(tp) ((void) 0) +#define xfs_trans_ordered_buf(tp, bp) ((void) 0) #define xfs_trans_agblocks_delta(tp, d) #define xfs_trans_agflist_delta(tp, d) #define xfs_trans_agbtree_delta(tp, d) +#define xfs_trans_buf_set_type(tp, bp, t) ({ \ + int __t = (t); \ + __t = __t; /* no set-but-unused warning */ \ +}) -#define xfs_buf_readahead(a,b,c) ((void) 0) /* no readahead */ -#define xfs_btree_reada_bufl(m,fsb,c) ((void) 0) -#define xfs_btree_reada_bufs(m,fsb,c,x) ((void) 0) -#define xfs_buftrace(x,y) ((void) 0) /* debug only */ +#define xfs_trans_buf_copy_type(dbp, sbp) + +/* no readahead, need to avoid set-but-unused var warnings. */ +#define xfs_buf_readahead(a,d,c,ops) ({ \ + xfs_daddr_t __d = d; \ + __d = __d; /* no set-but-unused warning */ \ +}) +#define xfs_buf_readahead_map(a,b,c,ops) ((void) 0) /* no readahead */ +#define xfs_buftrace(x,y) ((void) 0) /* debug only */ #define xfs_cmn_err(tag,level,mp,fmt,args...) cmn_err(level,fmt, ## args) +#define xfs_warn(mp,fmt,args...) cmn_err(CE_WARN,fmt, ## args) +#define xfs_alert(mp,fmt,args...) cmn_err(CE_ALERT,fmt, ## args) +#define xfs_alert_tag(mp,tag,fmt,args...) cmn_err(CE_ALERT,fmt, ## args) #define xfs_dir2_trace_args(where, args) ((void) 0) #define xfs_dir2_trace_args_b(where, args, bp) ((void) 0) @@ -289,15 +345,28 @@ #define xfs_initialize_perag_icache(pag) ((void) 0) #define xfs_ilock(ip,mode) ((void) 0) +#define xfs_ilock_nowait(ip,mode) ((void) 0) +#define xfs_ilock_demote(ip,mode) ((void) 0) #define xfs_iunlock(ip,mode) ((void) 0) +#define xfs_ilock_map_shared(ip,mode) ((void) 0) +#define xfs_iunlock_map_shared(ip,mode) ((void) 0) +#define __xfs_flock(ip) ((void) 0) /* space allocation */ -#define xfs_alloc_busy_search(tp,ag,b,len) 0 +#define xfs_extent_busy_reuse(mp,ag,bno,len,user) ((void) 0) +#define xfs_extent_busy_insert(tp,ag,bno,len,flags) ((void) 0) +#define xfs_extent_busy_trim(args,fbno,flen,bno,len) \ +do { \ + *(bno) = (fbno); \ + *(len) = (flen); \ +} while (0) + /* avoid unused variable warning */ #define xfs_alloc_busy_insert(tp,ag,b,len) ({ \ xfs_agnumber_t __foo = ag; \ __foo = 0; \ }) + #define xfs_rotorstep 1 #define xfs_bmap_rtalloc(a) (ENOSYS) #define xfs_rtpick_extent(mp,tp,len,p) (ENOSYS) @@ -306,6 +375,21 @@ #define xfs_filestream_lookup_ag(ip) (0) #define xfs_filestream_new_ag(ip,ag) (0) +#define xfs_log_force(mp,flags) ((void) 0) +#define XFS_LOG_SYNC 1 + +/* quota bits */ +#define xfs_trans_mod_dquot_byino(t,i,f,d) ((void) 0) +#define xfs_trans_reserve_quota_nblks(t,i,b,n,f) (0) +#define xfs_trans_unreserve_quota_nblks(t,i,b,n,f) ((void) 0) +#define xfs_qm_dqattach(i,f) (0) + +#define uuid_copy(s,d) platform_uuid_copy((s),(d)) +#define uuid_equal(s,d) (platform_uuid_compare((s),(d)) == 0) + +#define xfs_icreate_log(tp, agno, agbno, cnt, isize, len, gen) ((void) 0) +#define xfs_sb_validate_fsb_count(sbp, nblks) (0) + /* * Prototypes for kernel static functions that are aren't in their * associated header files @@ -318,14 +402,20 @@ void xfs_bmap_del_free(xfs_bmap_free_t *, xfs_bmap_free_item_t *, xfs_bmap_free_item_t *); -/* xfs_da_btree.c */ -int xfs_da_do_buf(xfs_trans_t *, xfs_inode_t *, xfs_dablk_t, xfs_daddr_t *, - xfs_dabuf_t **, int, int, inst_t *); - /* xfs_inode.c */ void xfs_iflush_fork(xfs_inode_t *, xfs_dinode_t *, xfs_inode_log_item_t *, int, xfs_buf_t *); -int xfs_iformat(xfs_inode_t *, xfs_dinode_t *); +/* + * For regular files we only update the on-disk filesize when actually + * writing data back to disk. Until then only the copy in the VFS inode + * is uptodate. + */ +static inline xfs_fsize_t XFS_ISIZE(struct xfs_inode *ip) +{ + if (S_ISREG(ip->i_d.di_mode)) + return ip->i_size; + return ip->i_d.di_size; +} /* xfs_mount.c */ int xfs_initialize_perag_data(xfs_mount_t *, xfs_agnumber_t); @@ -334,6 +424,8 @@ /* * logitem.c and trans.c prototypes */ +void xfs_trans_init(struct xfs_mount *); +int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *); /* xfs_trans_item.c */ void xfs_trans_add_item(struct xfs_trans *, struct xfs_log_item *); @@ -348,9 +440,12 @@ void xfs_buf_item_log (xfs_buf_log_item_t *, uint, uint); /* xfs_trans_buf.c */ -xfs_buf_t *xfs_trans_buf_item_match (xfs_trans_t *, xfs_buftarg_t *, - xfs_daddr_t, int); +xfs_buf_t *xfs_trans_buf_item_match(xfs_trans_t *, struct xfs_buftarg *, + struct xfs_buf_map *, int); /* local source files */ int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int); void xfs_trans_mod_sb(xfs_trans_t *, uint, long); +void xfs_trans_init(struct xfs_mount *); +int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *); +void xfs_verifier_error(struct xfs_buf *bp); diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_ialloc_btree.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_ialloc_btree.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_ialloc_btree.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_ialloc_btree.c 2014-06-19 22:42:17.000000000 +0000 @@ -30,7 +30,8 @@ struct xfs_btree_cur *cur) { return xfs_inobt_init_cursor(cur->bc_mp, cur->bc_tp, - cur->bc_private.a.agbp, cur->bc_private.a.agno); + cur->bc_private.a.agbp, cur->bc_private.a.agno, + cur->bc_btnum); } STATIC void @@ -47,6 +48,21 @@ xfs_ialloc_log_agi(cur->bc_tp, agbp, XFS_AGI_ROOT | XFS_AGI_LEVEL); } +STATIC void +xfs_finobt_set_root( + struct xfs_btree_cur *cur, + union xfs_btree_ptr *nptr, + int inc) /* level change */ +{ + struct xfs_buf *agbp = cur->bc_private.a.agbp; + struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); + + agi->agi_free_root = nptr->s; + be32_add_cpu(&agi->agi_free_level, inc); + xfs_ialloc_log_agi(cur->bc_tp, agbp, + XFS_AGI_FREE_ROOT | XFS_AGI_FREE_LEVEL); +} + STATIC int xfs_inobt_alloc_block( struct xfs_btree_cur *cur, @@ -154,6 +170,17 @@ ptr->s = agi->agi_root; } +STATIC void +xfs_finobt_init_ptr_from_cur( + struct xfs_btree_cur *cur, + union xfs_btree_ptr *ptr) +{ + struct xfs_agi *agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp); + + ASSERT(cur->bc_private.a.agno == be32_to_cpu(agi->agi_seqno)); + ptr->s = agi->agi_free_root; +} + STATIC __int64_t xfs_inobt_key_diff( struct xfs_btree_cur *cur, @@ -163,7 +190,100 @@ cur->bc_rec.i.ir_startino; } -#ifdef DEBUG +static int +xfs_inobt_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); + struct xfs_perag *pag = bp->b_pag; + unsigned int level; + + /* + * During growfs operations, we can't verify the exact owner as the + * perag is not fully initialised and hence not attached to the buffer. + * + * Similarly, during log recovery we will have a perag structure + * attached, but the agi information will not yet have been initialised + * from the on disk AGI. We don't currently use any of this information, + * but beware of the landmine (i.e. need to check pag->pagi_init) if we + * ever do. + */ + switch (block->bb_magic) { + case cpu_to_be32(XFS_IBT_CRC_MAGIC): + case cpu_to_be32(XFS_FIBT_CRC_MAGIC): + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return false; + if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) + return false; + if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) + return false; + if (pag && + be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + return false; + /* fall through */ + case cpu_to_be32(XFS_IBT_MAGIC): + case cpu_to_be32(XFS_FIBT_MAGIC): + break; + default: + return 0; + } + + /* numrecs and level verification */ + level = be16_to_cpu(block->bb_level); + if (level >= mp->m_in_maxlevels) + return false; + if (be16_to_cpu(block->bb_numrecs) > mp->m_inobt_mxr[level != 0]) + return false; + + /* sibling pointer verification */ + if (!block->bb_u.s.bb_leftsib || + (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks && + block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK))) + return false; + if (!block->bb_u.s.bb_rightsib || + (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks && + block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK))) + return false; + + return true; +} + +static void +xfs_inobt_read_verify( + struct xfs_buf *bp) +{ + if (!xfs_btree_sblock_verify_crc(bp)) + xfs_buf_ioerror(bp, EFSBADCRC); + else if (!xfs_inobt_verify(bp)) + xfs_buf_ioerror(bp, EFSCORRUPTED); + + if (bp->b_error) { + trace_xfs_btree_corrupt(bp, _RET_IP_); + xfs_verifier_error(bp); + } +} + +static void +xfs_inobt_write_verify( + struct xfs_buf *bp) +{ + if (!xfs_inobt_verify(bp)) { + trace_xfs_btree_corrupt(bp, _RET_IP_); + xfs_buf_ioerror(bp, EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + xfs_btree_sblock_calc_crc(bp); + +} + +const struct xfs_buf_ops xfs_inobt_buf_ops = { + .verify_read = xfs_inobt_read_verify, + .verify_write = xfs_inobt_write_verify, +}; + +#if defined(DEBUG) || defined(XFS_WARN) STATIC int xfs_inobt_keys_inorder( struct xfs_btree_cur *cur, @@ -266,8 +386,8 @@ .init_rec_from_cur = xfs_inobt_init_rec_from_cur, .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur, .key_diff = xfs_inobt_key_diff, - -#ifdef DEBUG + .buf_ops = &xfs_inobt_buf_ops, +#if defined(DEBUG) || defined(XFS_WARN) .keys_inorder = xfs_inobt_keys_inorder, .recs_inorder = xfs_inobt_recs_inorder, #endif @@ -280,6 +400,28 @@ #endif }; +static const struct xfs_btree_ops xfs_finobt_ops = { + .rec_len = sizeof(xfs_inobt_rec_t), + .key_len = sizeof(xfs_inobt_key_t), + + .dup_cursor = xfs_inobt_dup_cursor, + .set_root = xfs_finobt_set_root, + .alloc_block = xfs_inobt_alloc_block, + .free_block = xfs_inobt_free_block, + .get_minrecs = xfs_inobt_get_minrecs, + .get_maxrecs = xfs_inobt_get_maxrecs, + .init_key_from_rec = xfs_inobt_init_key_from_rec, + .init_rec_from_key = xfs_inobt_init_rec_from_key, + .init_rec_from_cur = xfs_inobt_init_rec_from_cur, + .init_ptr_from_cur = xfs_finobt_init_ptr_from_cur, + .key_diff = xfs_inobt_key_diff, + .buf_ops = &xfs_inobt_buf_ops, +#if defined(DEBUG) || defined(XFS_WARN) + .keys_inorder = xfs_inobt_keys_inorder, + .recs_inorder = xfs_inobt_recs_inorder, +#endif +}; + /* * Allocate a new inode btree cursor. */ @@ -288,7 +430,8 @@ struct xfs_mount *mp, /* file system mount point */ struct xfs_trans *tp, /* transaction pointer */ struct xfs_buf *agbp, /* buffer for agi structure */ - xfs_agnumber_t agno) /* allocation group number */ + xfs_agnumber_t agno, /* allocation group number */ + xfs_btnum_t btnum) /* ialloc or free ino btree */ { struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); struct xfs_btree_cur *cur; @@ -297,11 +440,19 @@ cur->bc_tp = tp; cur->bc_mp = mp; - cur->bc_nlevels = be32_to_cpu(agi->agi_level); - cur->bc_btnum = XFS_BTNUM_INO; + cur->bc_btnum = btnum; + if (btnum == XFS_BTNUM_INO) { + cur->bc_nlevels = be32_to_cpu(agi->agi_level); + cur->bc_ops = &xfs_inobt_ops; + } else { + cur->bc_nlevels = be32_to_cpu(agi->agi_free_level); + cur->bc_ops = &xfs_finobt_ops; + } + cur->bc_blocklog = mp->m_sb.sb_blocklog; - cur->bc_ops = &xfs_inobt_ops; + if (xfs_sb_version_hascrc(&mp->m_sb)) + cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; cur->bc_private.a.agbp = agbp; cur->bc_private.a.agno = agno; diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_ialloc.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_ialloc.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_ialloc.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_ialloc.c 2014-06-19 22:42:17.000000000 +0000 @@ -88,6 +88,66 @@ } /* + * Insert a single inobt record. Cursor must already point to desired location. + */ +STATIC int +xfs_inobt_insert_rec( + struct xfs_btree_cur *cur, + __int32_t freecount, + xfs_inofree_t free, + int *stat) +{ + cur->bc_rec.i.ir_freecount = freecount; + cur->bc_rec.i.ir_free = free; + return xfs_btree_insert(cur, stat); +} + +/* + * Insert records describing a newly allocated inode chunk into the inobt. + */ +STATIC int +xfs_inobt_insert( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_agino_t newino, + xfs_agino_t newlen, + xfs_btnum_t btnum) +{ + struct xfs_btree_cur *cur; + struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); + xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno); + xfs_agino_t thisino; + int i; + int error; + + cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, btnum); + + for (thisino = newino; + thisino < newino + newlen; + thisino += XFS_INODES_PER_CHUNK) { + error = xfs_inobt_lookup(cur, thisino, XFS_LOOKUP_EQ, &i); + if (error) { + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); + return error; + } + ASSERT(i == 0); + + error = xfs_inobt_insert_rec(cur, XFS_INODES_PER_CHUNK, + XFS_INOBT_ALL_FREE, &i); + if (error) { + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); + return error; + } + ASSERT(i == 1); + } + + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + + return 0; +} + +/* * Verify that the number of free inodes in the AGI is correct. */ #ifdef DEBUG @@ -129,12 +189,16 @@ #endif /* - * Initialise a new set of inodes. + * Initialise a new set of inodes. When called without a transaction context + * (e.g. from recovery) we initiate a delayed write of the inode buffers rather + * than logging them (which in a transaction context puts them into the AIL + * for writeback rather than the xfsbufd queue). */ -STATIC void +int xfs_ialloc_inode_init( struct xfs_mount *mp, struct xfs_trans *tp, + struct list_head *buffer_list, xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_agblock_t length, @@ -146,6 +210,7 @@ int version; int i, j; xfs_daddr_t d; + xfs_ino_t ino = 0; /* * Loop over the new block(s), filling in the inodes. @@ -164,13 +229,41 @@ } /* - * Figure out what version number to use in the inodes we create. - * If the superblock version has caught up to the one that supports - * the new inode format, then use the new inode version. Otherwise - * use the old version so that old kernels will continue to be - * able to use the file system. - */ - if (xfs_sb_version_hasnlink(&mp->m_sb)) + * Figure out what version number to use in the inodes we create. If + * the superblock version has caught up to the one that supports the new + * inode format, then use the new inode version. Otherwise use the old + * version so that old kernels will continue to be able to use the file + * system. + * + * For v3 inodes, we also need to write the inode number into the inode, + * so calculate the first inode number of the chunk here as + * XFS_OFFBNO_TO_AGINO() only works within a filesystem block, not + * across multiple filesystem blocks (such as a cluster) and so cannot + * be used in the cluster buffer loop below. + * + * Further, because we are writing the inode directly into the buffer + * and calculating a CRC on the entire inode, we have ot log the entire + * inode so that the entire range the CRC covers is present in the log. + * That means for v3 inode we log the entire buffer rather than just the + * inode cores. + */ + if (xfs_sb_version_hascrc(&mp->m_sb)) { + version = 3; + ino = XFS_AGINO_TO_INO(mp, agno, + XFS_OFFBNO_TO_AGINO(mp, agbno, 0)); + + /* + * log the initialisation that is about to take place as an + * logical operation. This means the transaction does not + * need to log the physical changes to the inode buffers as log + * recovery will know what initialisation is actually needed. + * Hence we only need to log the buffers as "ordered" buffers so + * they track in the AIL as if they were physically logged. + */ + if (tp) + xfs_icreate_log(tp, agno, agbno, XFS_IALLOC_INODES(mp), + mp->m_sb.sb_inodesize, length, gen); + } else if (xfs_sb_version_hasnlink(&mp->m_sb)) version = 2; else version = 1; @@ -182,31 +275,63 @@ d = XFS_AGB_TO_DADDR(mp, agno, agbno + (j * blks_per_cluster)); fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize * blks_per_cluster, - XBF_LOCK); - ASSERT(fbuf); - ASSERT(!XFS_BUF_GETERROR(fbuf)); - - /* - * Initialize all inodes in this buffer and then log them. - * - * XXX: It would be much better if we had just one transaction - * to log a whole cluster of inodes instead of all the - * individual transactions causing a lot of log traffic. - */ - xfs_buf_zero(fbuf, 0, ninodes << mp->m_sb.sb_inodelog); + XBF_UNMAPPED); + if (!fbuf) + return ENOMEM; + + /* Initialize the inode buffers and log them appropriately. */ + fbuf->b_ops = &xfs_inode_buf_ops; + xfs_buf_zero(fbuf, 0, BBTOB(fbuf->b_length)); for (i = 0; i < ninodes; i++) { int ioffset = i << mp->m_sb.sb_inodelog; - uint isize = sizeof(struct xfs_dinode); + uint isize = xfs_dinode_size(version); free = xfs_make_iptr(mp, fbuf, i); free->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); free->di_version = version; free->di_gen = cpu_to_be32(gen); free->di_next_unlinked = cpu_to_be32(NULLAGINO); - xfs_trans_log_buf(tp, fbuf, ioffset, ioffset + isize - 1); + + if (version == 3) { + free->di_ino = cpu_to_be64(ino); + ino++; + uuid_copy(&free->di_uuid, &mp->m_sb.sb_uuid); + xfs_dinode_calc_crc(mp, free); + } else if (tp) { + /* just log the inode core */ + xfs_trans_log_buf(tp, fbuf, ioffset, + ioffset + isize - 1); + } + } + + if (tp) { + /* + * Mark the buffer as an inode allocation buffer so it + * sticks in AIL at the point of this allocation + * transaction. This ensures the they are on disk before + * the tail of the log can be moved past this + * transaction (i.e. by preventing relogging from moving + * it forward in the log). + */ + xfs_trans_inode_alloc_buf(tp, fbuf); + if (version == 3) { + /* + * Mark the buffer as ordered so that they are + * not physically logged in the transaction but + * still tracked in the AIL as part of the + * transaction and pin the log appropriately. + */ + xfs_trans_ordered_buf(tp, fbuf); + xfs_trans_log_buf(tp, fbuf, 0, + BBTOB(fbuf->b_length) - 1); + } + } else { + fbuf->b_flags |= XBF_DONE; + xfs_buf_delwri_queue(fbuf, buffer_list); + xfs_buf_relse(fbuf); } - xfs_trans_inode_alloc_buf(tp, fbuf); } + return 0; } /* @@ -221,17 +346,15 @@ { xfs_agi_t *agi; /* allocation group header */ xfs_alloc_arg_t args; /* allocation argument structure */ - xfs_btree_cur_t *cur; /* inode btree cursor */ xfs_agnumber_t agno; int error; - int i; xfs_agino_t newino; /* new first inode's number */ xfs_agino_t newlen; /* new number of inodes */ - xfs_agino_t thisino; /* current inode number, for loop */ int isaligned = 0; /* inode allocation at stripe unit */ /* boundary */ struct xfs_perag *pag; + memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = tp->t_mountp; @@ -248,7 +371,7 @@ * First try to allocate inodes contiguous with the last-allocated * chunk of inodes. If the filesystem is striped, this will fill * an entire stripe unit with inodes. - */ + */ agi = XFS_BUF_TO_AGI(agbp); newino = be32_to_cpu(agi->agi_newino); agno = be32_to_cpu(agi->agi_seqno); @@ -258,8 +381,6 @@ (args.agbno < be32_to_cpu(agi->agi_length)))) { args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno); args.type = XFS_ALLOCTYPE_THIS_BNO; - args.mod = args.total = args.wasdel = args.isfl = - args.userdata = args.minalignslop = 0; args.prod = 1; /* @@ -312,8 +433,6 @@ * Allocate a fixed-size extent of inodes. */ args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.mod = args.total = args.wasdel = args.isfl = - args.userdata = args.minalignslop = 0; args.prod = 1; /* * Allow space for the inode btree to split. @@ -351,9 +470,11 @@ * rather than a linear progression to prevent the next generation * number from being easily guessable. */ - xfs_ialloc_inode_init(args.mp, tp, agno, args.agbno, args.len, - random32()); + error = xfs_ialloc_inode_init(args.mp, tp, NULL, agno, args.agbno, + args.len, prandom_u32()); + if (error) + return error; /* * Convert the results. */ @@ -366,29 +487,19 @@ agi->agi_newino = cpu_to_be32(newino); /* - * Insert records describing the new inode chunk into the btree. + * Insert records describing the new inode chunk into the btrees. */ - cur = xfs_inobt_init_cursor(args.mp, tp, agbp, agno); - for (thisino = newino; - thisino < newino + newlen; - thisino += XFS_INODES_PER_CHUNK) { - cur->bc_rec.i.ir_startino = thisino; - cur->bc_rec.i.ir_freecount = XFS_INODES_PER_CHUNK; - cur->bc_rec.i.ir_free = XFS_INOBT_ALL_FREE; - error = xfs_btree_lookup(cur, XFS_LOOKUP_EQ, &i); - if (error) { - xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); - return error; - } - ASSERT(i == 0); - error = xfs_btree_insert(cur, &i); - if (error) { - xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); + error = xfs_inobt_insert(args.mp, tp, agbp, newino, newlen, + XFS_BTNUM_INO); + if (error) + return error; + + if (xfs_sb_version_hasfinobt(&args.mp->m_sb)) { + error = xfs_inobt_insert(args.mp, tp, agbp, newino, newlen, + XFS_BTNUM_FINO); + if (error) return error; - } - ASSERT(i == 1); } - xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); /* * Log allocation group header fields */ @@ -411,7 +522,7 @@ spin_lock(&mp->m_agirotor_lock); agno = mp->m_agirotor; - if (++mp->m_agirotor == mp->m_maxagi) + if (++mp->m_agirotor >= mp->m_maxagi) mp->m_agirotor = 0; spin_unlock(&mp->m_agirotor_lock); @@ -420,16 +531,15 @@ /* * Select an allocation group to look for a free inode in, based on the parent - * inode and then mode. Return the allocation group buffer. + * inode and the mode. Return the allocation group buffer. */ -STATIC xfs_buf_t * /* allocation group buffer */ +STATIC xfs_agnumber_t xfs_ialloc_ag_select( xfs_trans_t *tp, /* transaction pointer */ xfs_ino_t parent, /* parent directory inode number */ - mode_t mode, /* bits set to indicate file type */ + umode_t mode, /* bits set to indicate file type */ int okalloc) /* ok to allocate more space */ { - xfs_buf_t *agbp; /* allocation group header buffer */ xfs_agnumber_t agcount; /* number of ag's in the filesystem */ xfs_agnumber_t agno; /* current ag number */ int flags; /* alloc buffer locking flags */ @@ -439,6 +549,7 @@ int needspace; /* file mode implies space allocated */ xfs_perag_t *pag; /* per allocation group data */ xfs_agnumber_t pagno; /* parent (starting) ag number */ + int error; /* * Files of these types need at least one block if length > 0 @@ -454,7 +565,9 @@ if (pagno >= agcount) pagno = 0; } + ASSERT(pagno < agcount); + /* * Loop through allocation groups, looking for one with a little * free space in it. Note we don't look for free inodes, exactly. @@ -466,51 +579,45 @@ flags = XFS_ALLOC_FLAG_TRYLOCK; for (;;) { pag = xfs_perag_get(mp, agno); + if (!pag->pagi_inodeok) { + xfs_ialloc_next_ag(mp); + goto nextag; + } + if (!pag->pagi_init) { - if (xfs_ialloc_read_agi(mp, tp, agno, &agbp)) { - agbp = NULL; + error = xfs_ialloc_pagi_init(mp, tp, agno); + if (error) goto nextag; - } - } else - agbp = NULL; + } - if (!pag->pagi_inodeok) { - xfs_ialloc_next_ag(mp); - goto unlock_nextag; + if (pag->pagi_freecount) { + xfs_perag_put(pag); + return agno; } - /* - * Is there enough free space for the file plus a block - * of inodes (if we need to allocate some)? - */ - ineed = pag->pagi_freecount ? 0 : XFS_IALLOC_BLOCKS(mp); - if (ineed && !pag->pagf_init) { - if (agbp == NULL && - xfs_ialloc_read_agi(mp, tp, agno, &agbp)) { - agbp = NULL; + if (!okalloc) + goto nextag; + + if (!pag->pagf_init) { + error = xfs_alloc_pagf_init(mp, tp, agno, flags); + if (error) goto nextag; - } - (void)xfs_alloc_pagf_init(mp, tp, agno, flags); } - if (!ineed || pag->pagf_init) { - if (ineed && !(longest = pag->pagf_longest)) - longest = pag->pagf_flcount > 0; - if (!ineed || - (pag->pagf_freeblks >= needspace + ineed && - longest >= ineed && - okalloc)) { - if (agbp == NULL && - xfs_ialloc_read_agi(mp, tp, agno, &agbp)) { - agbp = NULL; - goto nextag; - } - xfs_perag_put(pag); - return agbp; - } + + /* + * Is there enough free space for the file plus a block of + * inodes? (if we need to allocate some)? + */ + ineed = XFS_IALLOC_BLOCKS(mp); + longest = pag->pagf_longest; + if (!longest) + longest = pag->pagf_flcount > 0; + + if (pag->pagf_freeblks >= needspace + ineed && + longest >= ineed) { + xfs_perag_put(pag); + return agno; } -unlock_nextag: - if (agbp) - xfs_trans_brelse(tp, agbp); nextag: xfs_perag_put(pag); /* @@ -518,13 +625,13 @@ * down. */ if (XFS_FORCED_SHUTDOWN(mp)) - return NULL; + return NULLAGNUMBER; agno++; if (agno >= agcount) agno = 0; if (agno == pagno) { if (flags == 0) - return NULL; + return NULLAGNUMBER; flags = 0; } } @@ -566,8 +673,7 @@ struct xfs_btree_cur *cur, xfs_agino_t agino, xfs_inobt_rec_incore_t *rec, - int *done, - int left) + int *done) { int error; int i; @@ -587,188 +693,39 @@ } /* - * Visible inode allocation functions. - */ - -/* - * Allocate an inode on disk. - * Mode is used to tell whether the new inode will need space, and whether - * it is a directory. - * - * The arguments IO_agbp and alloc_done are defined to work within - * the constraint of one allocation per transaction. - * xfs_dialloc() is designed to be called twice if it has to do an - * allocation to make more free inodes. On the first call, - * IO_agbp should be set to NULL. If an inode is available, - * i.e., xfs_dialloc() did not need to do an allocation, an inode - * number is returned. In this case, IO_agbp would be set to the - * current ag_buf and alloc_done set to false. - * If an allocation needed to be done, xfs_dialloc would return - * the current ag_buf in IO_agbp and set alloc_done to true. - * The caller should then commit the current transaction, allocate a new - * transaction, and call xfs_dialloc() again, passing in the previous - * value of IO_agbp. IO_agbp should be held across the transactions. - * Since the agbp is locked across the two calls, the second call is - * guaranteed to have a free inode available. + * Allocate an inode. * - * Once we successfully pick an inode its number is returned and the - * on-disk data structures are updated. The inode itself is not read - * in, since doing so would break ordering constraints with xfs_reclaim. + * The caller selected an AG for us, and made sure that free inodes are + * available. */ -int -xfs_dialloc( - xfs_trans_t *tp, /* transaction pointer */ - xfs_ino_t parent, /* parent inode (directory) */ - mode_t mode, /* mode bits for new inode */ - int okalloc, /* ok to allocate more space */ - xfs_buf_t **IO_agbp, /* in/out ag header's buffer */ - boolean_t *alloc_done, /* true if we needed to replenish - inode freelist */ - xfs_ino_t *inop) /* inode number allocated */ -{ - xfs_agnumber_t agcount; /* number of allocation groups */ - xfs_buf_t *agbp; /* allocation group header's buffer */ - xfs_agnumber_t agno; /* allocation group number */ - xfs_agi_t *agi; /* allocation group header structure */ - xfs_btree_cur_t *cur; /* inode allocation btree cursor */ - int error; /* error return value */ - int i; /* result code */ - int ialloced; /* inode allocation status */ - int noroom = 0; /* no space for inode blk allocation */ - xfs_ino_t ino; /* fs-relative inode to be returned */ - /* REFERENCED */ - int j; /* result code */ - xfs_mount_t *mp; /* file system mount structure */ - int offset; /* index of inode in chunk */ - xfs_agino_t pagino; /* parent's AG relative inode # */ - xfs_agnumber_t pagno; /* parent's AG number */ - xfs_inobt_rec_incore_t rec; /* inode allocation record */ - xfs_agnumber_t tagno; /* testing allocation group number */ - xfs_btree_cur_t *tcur; /* temp cursor */ - xfs_inobt_rec_incore_t trec; /* temp inode allocation record */ - struct xfs_perag *pag; - - - if (*IO_agbp == NULL) { - /* - * We do not have an agbp, so select an initial allocation - * group for inode allocation. - */ - agbp = xfs_ialloc_ag_select(tp, parent, mode, okalloc); - /* - * Couldn't find an allocation group satisfying the - * criteria, give up. - */ - if (!agbp) { - *inop = NULLFSINO; - return 0; - } - agi = XFS_BUF_TO_AGI(agbp); - ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC); - } else { - /* - * Continue where we left off before. In this case, we - * know that the allocation group has free inodes. - */ - agbp = *IO_agbp; - agi = XFS_BUF_TO_AGI(agbp); - ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC); - ASSERT(be32_to_cpu(agi->agi_freecount) > 0); - } - mp = tp->t_mountp; - agcount = mp->m_sb.sb_agcount; - agno = be32_to_cpu(agi->agi_seqno); - tagno = agno; - pagno = XFS_INO_TO_AGNO(mp, parent); - pagino = XFS_INO_TO_AGINO(mp, parent); - - /* - * If we have already hit the ceiling of inode blocks then clear - * okalloc so we scan all available agi structures for a free - * inode. - */ - - if (mp->m_maxicount && - mp->m_sb.sb_icount + XFS_IALLOC_INODES(mp) > mp->m_maxicount) { - noroom = 1; - okalloc = 0; - } +STATIC int +xfs_dialloc_ag_slow( + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_ino_t parent, + xfs_ino_t *inop) +{ + struct xfs_mount *mp = tp->t_mountp; + struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); + xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno); + xfs_agnumber_t pagno = XFS_INO_TO_AGNO(mp, parent); + xfs_agino_t pagino = XFS_INO_TO_AGINO(mp, parent); + struct xfs_perag *pag; + struct xfs_btree_cur *cur, *tcur; + struct xfs_inobt_rec_incore rec, trec; + xfs_ino_t ino; + int error; + int offset; + int i, j; - /* - * Loop until we find an allocation group that either has free inodes - * or in which we can allocate some inodes. Iterate through the - * allocation groups upward, wrapping at the end. - */ - *alloc_done = B_FALSE; - while (!agi->agi_freecount) { - /* - * Don't do anything if we're not supposed to allocate - * any blocks, just go on to the next ag. - */ - if (okalloc) { - /* - * Try to allocate some new inodes in the allocation - * group. - */ - if ((error = xfs_ialloc_ag_alloc(tp, agbp, &ialloced))) { - xfs_trans_brelse(tp, agbp); - if (error == ENOSPC) { - *inop = NULLFSINO; - return 0; - } else - return error; - } - if (ialloced) { - /* - * We successfully allocated some inodes, return - * the current context to the caller so that it - * can commit the current transaction and call - * us again where we left off. - */ - ASSERT(be32_to_cpu(agi->agi_freecount) > 0); - *alloc_done = B_TRUE; - *IO_agbp = agbp; - *inop = NULLFSINO; - return 0; - } - } - /* - * If it failed, give up on this ag. - */ - xfs_trans_brelse(tp, agbp); - /* - * Go on to the next ag: get its ag header. - */ -nextag: - if (++tagno == agcount) - tagno = 0; - if (tagno == agno) { - *inop = NULLFSINO; - return noroom ? ENOSPC : 0; - } - pag = xfs_perag_get(mp, tagno); - if (pag->pagi_inodeok == 0) { - xfs_perag_put(pag); - goto nextag; - } - error = xfs_ialloc_read_agi(mp, tp, tagno, &agbp); - xfs_perag_put(pag); - if (error) - goto nextag; - agi = XFS_BUF_TO_AGI(agbp); - ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC); - } - /* - * Here with an allocation group that has a free inode. - * Reset agno since we may have chosen a new ag in the - * loop above. - */ - agno = tagno; - *IO_agbp = NULL; pag = xfs_perag_get(mp, agno); + ASSERT(pag->pagi_init); + ASSERT(pag->pagi_inodeok); + ASSERT(pag->pagi_freecount > 0); + restart_pagno: - cur = xfs_inobt_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno)); + cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO); /* * If pagino is 0 (this is the root inode allocation) use newino. * This must work because we've just allocated some. @@ -796,7 +753,7 @@ error = xfs_inobt_get_rec(cur, &rec, &j); if (error) goto error0; - XFS_WANT_CORRUPTED_GOTO(i == 1, error0); + XFS_WANT_CORRUPTED_GOTO(j == 1, error0); if (rec.ir_freecount > 0) { /* @@ -824,12 +781,12 @@ pag->pagl_leftrec != NULLAGINO && pag->pagl_rightrec != NULLAGINO) { error = xfs_ialloc_get_rec(tcur, pag->pagl_leftrec, - &trec, &doneleft, 1); + &trec, &doneleft); if (error) goto error1; error = xfs_ialloc_get_rec(cur, pag->pagl_rightrec, - &rec, &doneright, 0); + &rec, &doneright); if (error) goto error1; } else { @@ -925,7 +882,7 @@ * See if the most recently allocated block has any free. */ newino: - if (be32_to_cpu(agi->agi_newino) != NULLAGINO) { + if (agi->agi_newino != cpu_to_be32(NULLAGINO)) { error = xfs_inobt_lookup(cur, be32_to_cpu(agi->agi_newino), XFS_LOOKUP_EQ, &i); if (error) @@ -968,7 +925,7 @@ } alloc_inode: - offset = xfs_ialloc_find_free(&rec.ir_free); + offset = xfs_lowbit64(rec.ir_free); ASSERT(offset >= 0); ASSERT(offset < XFS_INODES_PER_CHUNK); ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) % @@ -1001,65 +958,743 @@ } STATIC int -xfs_imap_lookup( - struct xfs_mount *mp, +xfs_dialloc_ag( struct xfs_trans *tp, - xfs_agnumber_t agno, - xfs_agino_t agino, - xfs_agblock_t agbno, - xfs_agblock_t *chunk_agbno, - xfs_agblock_t *offset_agbno, - int flags) + struct xfs_buf *agbp, + xfs_ino_t parent, + xfs_ino_t *inop) { - struct xfs_inobt_rec_incore rec; - struct xfs_btree_cur *cur; - struct xfs_buf *agbp; - int error; - int i; + struct xfs_mount *mp = tp->t_mountp; + struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); + xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno); + xfs_agnumber_t pagno = XFS_INO_TO_AGNO(mp, parent); + xfs_agino_t pagino = XFS_INO_TO_AGINO(mp, parent); + struct xfs_perag *pag; + struct xfs_btree_cur *cur; + struct xfs_btree_cur *tcur; + struct xfs_inobt_rec_incore rec; + struct xfs_inobt_rec_incore trec; + xfs_ino_t ino; + int error; + int offset; + int i, j; - error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); - if (error) { - xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " - "xfs_ialloc_read_agi() returned " - "error %d, agno %d", - error, agno); - return error; - } + if (!xfs_sb_version_hasfinobt(&mp->m_sb)) + return xfs_dialloc_ag_slow(tp, agbp, parent, inop); + + pag = xfs_perag_get(mp, agno); /* - * Lookup the inode record for the given agino. If the record cannot be - * found, then it's an invalid inode number and we should abort. Once - * we have a record, we need to ensure it contains the inode number - * we are looking up. + * If pagino is 0 (this is the root inode allocation) use newino. + * This must work because we've just allocated some. */ - cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); - error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i); - if (!error) { - if (i) - error = xfs_inobt_get_rec(cur, &rec, &i); - if (!error && i == 0) - error = EINVAL; - } + if (!pagino) + pagino = be32_to_cpu(agi->agi_newino); - xfs_trans_brelse(tp, agbp); - xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_FINO); + + error = xfs_check_agi_freecount(cur, agi); if (error) - return error; + goto error_cur; - /* check that the returned record contains the required inode */ - if (rec.ir_startino > agino || - rec.ir_startino + XFS_IALLOC_INODES(mp) <= agino) - return EINVAL; + if (agno == pagno) { + /* + * We're in the same AG as the parent inode so allocate the + * closest inode to the parent. + */ + error = xfs_inobt_lookup(cur, pagino, XFS_LOOKUP_LE, &i); + if (error) + goto error_cur; + if (i == 1) { + error = xfs_inobt_get_rec(cur, &rec, &i); + if (error) + goto error_cur; + XFS_WANT_CORRUPTED_GOTO(i == 1, error_cur); - /* for untrusted inodes check it is allocated first */ - if ((flags & XFS_IGET_UNTRUSTED) && - (rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino))) - return EINVAL; + /* + * See if we've landed in the parent inode record. The + * finobt only tracks chunks with at least one free + * inode, so record existence is enough. + */ + if (pagino >= rec.ir_startino && + pagino < (rec.ir_startino + XFS_INODES_PER_CHUNK)) + goto alloc_inode; + } - *chunk_agbno = XFS_AGINO_TO_AGBNO(mp, rec.ir_startino); - *offset_agbno = agbno - *chunk_agbno; - return 0; -} + error = xfs_btree_dup_cursor(cur, &tcur); + if (error) + goto error_cur; + + error = xfs_inobt_lookup(tcur, pagino, XFS_LOOKUP_GE, &j); + if (error) + goto error_tcur; + if (j == 1) { + error = xfs_inobt_get_rec(tcur, &trec, &j); + if (error) + goto error_tcur; + XFS_WANT_CORRUPTED_GOTO(j == 1, error_tcur); + } + + if (i == 1 && j == 1) { + if ((pagino - rec.ir_startino + XFS_INODES_PER_CHUNK - 1) > + (trec.ir_startino - pagino)) { + rec = trec; + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + cur = tcur; + } else { + xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); + } + } else if (j == 1) { + rec = trec; + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + cur = tcur; + } else { + xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); + } + } else { + /* + * Different AG from the parent inode. Check the record for the + * most recently allocated inode. + */ + if (agi->agi_newino != cpu_to_be32(NULLAGINO)) { + error = xfs_inobt_lookup(cur, agi->agi_newino, + XFS_LOOKUP_EQ, &i); + if (error) + goto error_cur; + if (i == 1) { + error = xfs_inobt_get_rec(cur, &rec, &i); + if (error) + goto error_cur; + XFS_WANT_CORRUPTED_GOTO(i == 1, error_cur); + goto alloc_inode; + } + } + + /* + * Allocate the first inode available in the AG. + */ + error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i); + if (error) + goto error_cur; + XFS_WANT_CORRUPTED_GOTO(i == 1, error_cur); + + error = xfs_inobt_get_rec(cur, &rec, &i); + if (error) + goto error_cur; + XFS_WANT_CORRUPTED_GOTO(i == 1, error_cur); + } + +alloc_inode: + offset = xfs_lowbit64(rec.ir_free); + ASSERT(offset >= 0); + ASSERT(offset < XFS_INODES_PER_CHUNK); + ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) % + XFS_INODES_PER_CHUNK) == 0); + ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + offset); + + /* + * Modify or remove the finobt record. + */ + rec.ir_free &= ~XFS_INOBT_MASK(offset); + rec.ir_freecount--; + if (rec.ir_freecount) + error = xfs_inobt_update(cur, &rec); + else + error = xfs_btree_delete(cur, &i); + if (error) + goto error_cur; + + /* + * Lookup and modify the equivalent record in the inobt. + */ + tcur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO); + + error = xfs_check_agi_freecount(tcur, agi); + if (error) + goto error_tcur; + + error = xfs_inobt_lookup(tcur, rec.ir_startino, XFS_LOOKUP_EQ, &i); + if (error) + goto error_tcur; + XFS_WANT_CORRUPTED_GOTO(i == 1, error_tcur); + + error = xfs_inobt_get_rec(tcur, &trec, &i); + if (error) + goto error_tcur; + XFS_WANT_CORRUPTED_GOTO(i == 1, error_tcur); + ASSERT((XFS_AGINO_TO_OFFSET(mp, trec.ir_startino) % + XFS_INODES_PER_CHUNK) == 0); + + trec.ir_free &= ~XFS_INOBT_MASK(offset); + trec.ir_freecount--; + + XFS_WANT_CORRUPTED_GOTO((rec.ir_free == trec.ir_free) && + (rec.ir_freecount == trec.ir_freecount), + error_tcur); + + error = xfs_inobt_update(tcur, &trec); + if (error) + goto error_tcur; + + /* + * Update the perag and superblock. + */ + be32_add_cpu(&agi->agi_freecount, -1); + xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT); + pag->pagi_freecount--; + + xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1); + + error = xfs_check_agi_freecount(tcur, agi); + if (error) + goto error_tcur; + error = xfs_check_agi_freecount(cur, agi); + if (error) + goto error_tcur; + + xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + xfs_perag_put(pag); + *inop = ino; + return 0; + +error_tcur: + xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR); +error_cur: + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); + xfs_perag_put(pag); + return error; +} + +/* + * Allocate an inode on disk. + * + * Mode is used to tell whether the new inode will need space, and whether it + * is a directory. + * + * This function is designed to be called twice if it has to do an allocation + * to make more free inodes. On the first call, *IO_agbp should be set to NULL. + * If an inode is available without having to performn an allocation, an inode + * number is returned. In this case, *IO_agbp is set to NULL. If an allocation + * needs to be done, xfs_dialloc returns the current AGI buffer in *IO_agbp. + * The caller should then commit the current transaction, allocate a + * new transaction, and call xfs_dialloc() again, passing in the previous value + * of *IO_agbp. IO_agbp should be held across the transactions. Since the AGI + * buffer is locked across the two calls, the second call is guaranteed to have + * a free inode available. + * + * Once we successfully pick an inode its number is returned and the on-disk + * data structures are updated. The inode itself is not read in, since doing so + * would break ordering constraints with xfs_reclaim. + */ +int +xfs_dialloc( + struct xfs_trans *tp, + xfs_ino_t parent, + umode_t mode, + int okalloc, + struct xfs_buf **IO_agbp, + xfs_ino_t *inop) +{ + struct xfs_mount *mp = tp->t_mountp; + struct xfs_buf *agbp; + xfs_agnumber_t agno; + int error; + int ialloced; + int noroom = 0; + xfs_agnumber_t start_agno; + struct xfs_perag *pag; + + if (*IO_agbp) { + /* + * If the caller passes in a pointer to the AGI buffer, + * continue where we left off before. In this case, we + * know that the allocation group has free inodes. + */ + agbp = *IO_agbp; + goto out_alloc; + } + + /* + * We do not have an agbp, so select an initial allocation + * group for inode allocation. + */ + start_agno = xfs_ialloc_ag_select(tp, parent, mode, okalloc); + if (start_agno == NULLAGNUMBER) { + *inop = NULLFSINO; + return 0; + } + + /* + * If we have already hit the ceiling of inode blocks then clear + * okalloc so we scan all available agi structures for a free + * inode. + */ + if (mp->m_maxicount && + mp->m_sb.sb_icount + XFS_IALLOC_INODES(mp) > mp->m_maxicount) { + noroom = 1; + okalloc = 0; + } + + /* + * Loop until we find an allocation group that either has free inodes + * or in which we can allocate some inodes. Iterate through the + * allocation groups upward, wrapping at the end. + */ + agno = start_agno; + for (;;) { + pag = xfs_perag_get(mp, agno); + if (!pag->pagi_inodeok) { + xfs_ialloc_next_ag(mp); + goto nextag; + } + + if (!pag->pagi_init) { + error = xfs_ialloc_pagi_init(mp, tp, agno); + if (error) + goto out_error; + } + + /* + * Do a first racy fast path check if this AG is usable. + */ + if (!pag->pagi_freecount && !okalloc) + goto nextag; + + /* + * Then read in the AGI buffer and recheck with the AGI buffer + * lock held. + */ + error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); + if (error) + goto out_error; + + if (pag->pagi_freecount) { + xfs_perag_put(pag); + goto out_alloc; + } + + if (!okalloc) + goto nextag_relse_buffer; + + + error = xfs_ialloc_ag_alloc(tp, agbp, &ialloced); + if (error) { + xfs_trans_brelse(tp, agbp); + + if (error != ENOSPC) + goto out_error; + + xfs_perag_put(pag); + *inop = NULLFSINO; + return 0; + } + + if (ialloced) { + /* + * We successfully allocated some inodes, return + * the current context to the caller so that it + * can commit the current transaction and call + * us again where we left off. + */ + ASSERT(pag->pagi_freecount > 0); + xfs_perag_put(pag); + + *IO_agbp = agbp; + *inop = NULLFSINO; + return 0; + } + +nextag_relse_buffer: + xfs_trans_brelse(tp, agbp); +nextag: + xfs_perag_put(pag); + if (++agno == mp->m_sb.sb_agcount) + agno = 0; + if (agno == start_agno) { + *inop = NULLFSINO; + return noroom ? ENOSPC : 0; + } + } + +out_alloc: + *IO_agbp = NULL; + return xfs_dialloc_ag(tp, agbp, parent, inop); +out_error: + xfs_perag_put(pag); + return XFS_ERROR(error); +} + +STATIC int +xfs_difree_inobt( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_agino_t agino, + struct xfs_bmap_free *flist, + int *deleted, + xfs_ino_t *first_ino, + struct xfs_inobt_rec_incore *orec) +{ + struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); + xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno); + struct xfs_perag *pag; + struct xfs_btree_cur *cur; + struct xfs_inobt_rec_incore rec; + int ilen; + int error; + int i; + int off; + + ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC)); + ASSERT(XFS_AGINO_TO_AGBNO(mp, agino) < be32_to_cpu(agi->agi_length)); + + /* + * Initialize the cursor. + */ + cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO); + + error = xfs_check_agi_freecount(cur, agi); + if (error) + goto error0; + + /* + * Look for the entry describing this inode. + */ + if ((error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i))) { + xfs_warn(mp, "%s: xfs_inobt_lookup() returned error %d.", + __func__, error); + goto error0; + } + XFS_WANT_CORRUPTED_GOTO(i == 1, error0); + error = xfs_inobt_get_rec(cur, &rec, &i); + if (error) { + xfs_warn(mp, "%s: xfs_inobt_get_rec() returned error %d.", + __func__, error); + goto error0; + } + XFS_WANT_CORRUPTED_GOTO(i == 1, error0); + /* + * Get the offset in the inode chunk. + */ + off = agino - rec.ir_startino; + ASSERT(off >= 0 && off < XFS_INODES_PER_CHUNK); + ASSERT(!(rec.ir_free & XFS_INOBT_MASK(off))); + /* + * Mark the inode free & increment the count. + */ + rec.ir_free |= XFS_INOBT_MASK(off); + rec.ir_freecount++; + + /* + * When an inode cluster is free, it becomes eligible for removal + */ + if (!(mp->m_flags & XFS_MOUNT_IKEEP) && + (rec.ir_freecount == XFS_IALLOC_INODES(mp))) { + + *deleted = 1; + *first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino); + + /* + * Remove the inode cluster from the AGI B+Tree, adjust the + * AGI and Superblock inode counts, and mark the disk space + * to be freed when the transaction is committed. + */ + ilen = XFS_IALLOC_INODES(mp); + be32_add_cpu(&agi->agi_count, -ilen); + be32_add_cpu(&agi->agi_freecount, -(ilen - 1)); + xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT); + pag = xfs_perag_get(mp, agno); + pag->pagi_freecount -= ilen - 1; + xfs_perag_put(pag); + xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, -ilen); + xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -(ilen - 1)); + + if ((error = xfs_btree_delete(cur, &i))) { + xfs_warn(mp, "%s: xfs_btree_delete returned error %d.", + __func__, error); + goto error0; + } + + xfs_bmap_add_free(XFS_AGB_TO_FSB(mp, + agno, XFS_INO_TO_AGBNO(mp,rec.ir_startino)), + XFS_IALLOC_BLOCKS(mp), flist, mp); + } else { + *deleted = 0; + + error = xfs_inobt_update(cur, &rec); + if (error) { + xfs_warn(mp, "%s: xfs_inobt_update returned error %d.", + __func__, error); + goto error0; + } + + /* + * Change the inode free counts and log the ag/sb changes. + */ + be32_add_cpu(&agi->agi_freecount, 1); + xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT); + pag = xfs_perag_get(mp, agno); + pag->pagi_freecount++; + xfs_perag_put(pag); + xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1); + } + + error = xfs_check_agi_freecount(cur, agi); + if (error) + goto error0; + + *orec = rec; + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + return 0; + +error0: + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); + return error; +} + +/* + * Free an inode in the free inode btree. + */ +STATIC int +xfs_difree_finobt( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_agino_t agino, + struct xfs_inobt_rec_incore *ibtrec) /* inobt record */ +{ + struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); + xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno); + struct xfs_btree_cur *cur; + struct xfs_inobt_rec_incore rec; + int offset = agino - ibtrec->ir_startino; + int error; + int i; + + cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_FINO); + + error = xfs_inobt_lookup(cur, ibtrec->ir_startino, XFS_LOOKUP_EQ, &i); + if (error) + goto error; + if (i == 0) { + /* + * If the record does not exist in the finobt, we must have just + * freed an inode in a previously fully allocated chunk. If not, + * something is out of sync. + */ + XFS_WANT_CORRUPTED_GOTO(ibtrec->ir_freecount == 1, error); + + error = xfs_inobt_insert_rec(cur, ibtrec->ir_freecount, + ibtrec->ir_free, &i); + if (error) + goto error; + ASSERT(i == 1); + + goto out; + } + + /* + * Read and update the existing record. + */ + error = xfs_inobt_get_rec(cur, &rec, &i); + if (error) + goto error; + XFS_WANT_CORRUPTED_GOTO(i == 1, error); + + rec.ir_free |= XFS_INOBT_MASK(offset); + rec.ir_freecount++; + + XFS_WANT_CORRUPTED_GOTO((rec.ir_free == ibtrec->ir_free) && + (rec.ir_freecount == ibtrec->ir_freecount), + error); + + /* + * The content of inobt records should always match between the inobt + * and finobt. The lifecycle of records in the finobt is different from + * the inobt in that the finobt only tracks records with at least one + * free inode. This is to optimize lookup for inode allocation purposes. + * The following checks determine whether to update the existing record or + * remove it entirely. + */ + + if (rec.ir_freecount == XFS_IALLOC_INODES(mp) && + !(mp->m_flags & XFS_MOUNT_IKEEP)) { + /* + * If all inodes are free and we're in !ikeep mode, the entire + * inode chunk has been deallocated. Remove the record from the + * finobt. + */ + error = xfs_btree_delete(cur, &i); + if (error) + goto error; + ASSERT(i == 1); + } else { + /* + * The existing finobt record was modified and has a combination + * of allocated and free inodes or is completely free and ikeep + * is enabled. Update the record. + */ + error = xfs_inobt_update(cur, &rec); + if (error) + goto error; + } + +out: + error = xfs_check_agi_freecount(cur, agi); + if (error) + goto error; + + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + return 0; + +error: + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); + return error; +} + +/* + * Free disk inode. Carefully avoids touching the incore inode, all + * manipulations incore are the caller's responsibility. + * The on-disk inode is not changed by this operation, only the + * btree (free inode mask) is changed. + */ +int +xfs_difree( + struct xfs_trans *tp, /* transaction pointer */ + xfs_ino_t inode, /* inode to be freed */ + struct xfs_bmap_free *flist, /* extents to free */ + int *deleted,/* set if inode cluster was deleted */ + xfs_ino_t *first_ino)/* first inode in deleted cluster */ +{ + /* REFERENCED */ + xfs_agblock_t agbno; /* block number containing inode */ + struct xfs_buf *agbp; /* buffer for allocation group header */ + xfs_agino_t agino; /* allocation group inode number */ + xfs_agnumber_t agno; /* allocation group number */ + int error; /* error return value */ + struct xfs_mount *mp; /* mount structure for filesystem */ + struct xfs_inobt_rec_incore rec;/* btree record */ + + mp = tp->t_mountp; + + /* + * Break up inode number into its components. + */ + agno = XFS_INO_TO_AGNO(mp, inode); + if (agno >= mp->m_sb.sb_agcount) { + xfs_warn(mp, "%s: agno >= mp->m_sb.sb_agcount (%d >= %d).", + __func__, agno, mp->m_sb.sb_agcount); + ASSERT(0); + return XFS_ERROR(EINVAL); + } + agino = XFS_INO_TO_AGINO(mp, inode); + if (inode != XFS_AGINO_TO_INO(mp, agno, agino)) { + xfs_warn(mp, "%s: inode != XFS_AGINO_TO_INO() (%llu != %llu).", + __func__, (unsigned long long)inode, + (unsigned long long)XFS_AGINO_TO_INO(mp, agno, agino)); + ASSERT(0); + return XFS_ERROR(EINVAL); + } + agbno = XFS_AGINO_TO_AGBNO(mp, agino); + if (agbno >= mp->m_sb.sb_agblocks) { + xfs_warn(mp, "%s: agbno >= mp->m_sb.sb_agblocks (%d >= %d).", + __func__, agbno, mp->m_sb.sb_agblocks); + ASSERT(0); + return XFS_ERROR(EINVAL); + } + /* + * Get the allocation group header. + */ + error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); + if (error) { + xfs_warn(mp, "%s: xfs_ialloc_read_agi() returned error %d.", + __func__, error); + return error; + } + + /* + * Fix up the inode allocation btree. + */ + error = xfs_difree_inobt(mp, tp, agbp, agino, flist, deleted, first_ino, + &rec); + if (error) + goto error0; + + /* + * Fix up the free inode btree. + */ + if (xfs_sb_version_hasfinobt(&mp->m_sb)) { + error = xfs_difree_finobt(mp, tp, agbp, agino, &rec); + if (error) + goto error0; + } + + return 0; + +error0: + return error; +} + +STATIC int +xfs_imap_lookup( + struct xfs_mount *mp, + struct xfs_trans *tp, + xfs_agnumber_t agno, + xfs_agino_t agino, + xfs_agblock_t agbno, + xfs_agblock_t *chunk_agbno, + xfs_agblock_t *offset_agbno, + int flags) +{ + struct xfs_inobt_rec_incore rec; + struct xfs_btree_cur *cur; + struct xfs_buf *agbp; + int error; + int i; + + error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); + if (error) { + xfs_alert(mp, + "%s: xfs_ialloc_read_agi() returned error %d, agno %d", + __func__, error, agno); + return error; + } + + /* + * Lookup the inode record for the given agino. If the record cannot be + * found, then it's an invalid inode number and we should abort. Once + * we have a record, we need to ensure it contains the inode number + * we are looking up. + */ + cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO); + error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i); + if (!error) { + if (i) + error = xfs_inobt_get_rec(cur, &rec, &i); + if (!error && i == 0) + error = EINVAL; + } + + xfs_trans_brelse(tp, agbp); + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + if (error) + return error; + + /* check that the returned record contains the required inode */ + if (rec.ir_startino > agino || + rec.ir_startino + XFS_IALLOC_INODES(mp) <= agino) + return EINVAL; + + /* for untrusted inodes check it is allocated first */ + if ((flags & XFS_IGET_UNTRUSTED) && + (rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino))) + return EINVAL; + + *chunk_agbno = XFS_AGINO_TO_AGBNO(mp, rec.ir_startino); + *offset_agbno = agbno - *chunk_agbno; + return 0; +} /* * Return the location of the inode in imap, for mapping it into a buffer. @@ -1100,24 +1735,21 @@ if (flags & XFS_IGET_UNTRUSTED) return XFS_ERROR(EINVAL); if (agno >= mp->m_sb.sb_agcount) { - xfs_fs_cmn_err(CE_ALERT, mp, - "xfs_imap: agno (%d) >= " - "mp->m_sb.sb_agcount (%d)", - agno, mp->m_sb.sb_agcount); + xfs_alert(mp, + "%s: agno (%d) >= mp->m_sb.sb_agcount (%d)", + __func__, agno, mp->m_sb.sb_agcount); } if (agbno >= mp->m_sb.sb_agblocks) { - xfs_fs_cmn_err(CE_ALERT, mp, - "xfs_imap: agbno (0x%llx) >= " - "mp->m_sb.sb_agblocks (0x%lx)", - (unsigned long long) agbno, - (unsigned long) mp->m_sb.sb_agblocks); + xfs_alert(mp, + "%s: agbno (0x%llx) >= mp->m_sb.sb_agblocks (0x%lx)", + __func__, (unsigned long long)agbno, + (unsigned long)mp->m_sb.sb_agblocks); } if (ino != XFS_AGINO_TO_INO(mp, agno, agino)) { - xfs_fs_cmn_err(CE_ALERT, mp, - "xfs_imap: ino (0x%llx) != " - "XFS_AGINO_TO_INO(mp, agno, agino) " - "(0x%llx)", - ino, XFS_AGINO_TO_INO(mp, agno, agino)); + xfs_alert(mp, + "%s: ino (0x%llx) != XFS_AGINO_TO_INO() (0x%llx)", + __func__, ino, + XFS_AGINO_TO_INO(mp, agno, agino)); } xfs_stack_trace(); #endif /* DEBUG */ @@ -1189,10 +1821,9 @@ */ if ((imap->im_blkno + imap->im_len) > XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)) { - xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " - "(imap->im_blkno (0x%llx) + imap->im_len (0x%llx)) > " - " XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks) (0x%llx)", - (unsigned long long) imap->im_blkno, + xfs_alert(mp, + "%s: (im_blkno (0x%llx) + im_len (0x%llx)) > sb_dblocks (0x%llx)", + __func__, (unsigned long long) imap->im_blkno, (unsigned long long) imap->im_len, XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)); return XFS_ERROR(EINVAL); @@ -1247,22 +1878,50 @@ offsetof(xfs_agi_t, agi_newino), offsetof(xfs_agi_t, agi_dirino), offsetof(xfs_agi_t, agi_unlinked), + offsetof(xfs_agi_t, agi_free_root), + offsetof(xfs_agi_t, agi_free_level), sizeof(xfs_agi_t) }; #ifdef DEBUG xfs_agi_t *agi; /* allocation group header */ agi = XFS_BUF_TO_AGI(bp); - ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC); + ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC)); #endif /* - * Compute byte offsets for the first and last fields. + * The growth of the agi buffer over time now requires that we interpret + * the buffer as two logical regions delineated at the end of the unlinked + * list. This is due to the size of the hash table and its location in the + * middle of the agi. + * + * For example, a request to log a field before agi_unlinked and a field + * after agi_unlinked could cause us to log the entire hash table and use + * an excessive amount of log space. To avoid this behavior, log the + * region up through agi_unlinked in one call and the region after + * agi_unlinked through the end of the structure in another. + */ + xfs_trans_buf_set_type(tp, bp, XFS_BLFT_AGI_BUF); + + /* + * Compute byte offsets for the first and last fields in the first + * region and log agi buffer. This only logs up through agi_unlinked. */ - xfs_btree_offsets(fields, offsets, XFS_AGI_NUM_BITS, &first, &last); + if (fields & XFS_AGI_ALL_BITS_R1) { + xfs_btree_offsets(fields, offsets, XFS_AGI_NUM_BITS_R1, + &first, &last); + xfs_trans_log_buf(tp, bp, first, last); + } + /* - * Log the allocation group inode header buffer. + * Mask off the bits in the first region and calculate the first and last + * field offsets for any bits in the second region. */ - xfs_trans_log_buf(tp, bp, first, last); + fields &= ~XFS_AGI_ALL_BITS_R1; + if (fields) { + xfs_btree_offsets(fields, offsets, XFS_AGI_NUM_BITS_R2, + &first, &last); + xfs_trans_log_buf(tp, bp, first, last); + } } #ifdef DEBUG @@ -1279,6 +1938,81 @@ #define xfs_check_agi_unlinked(agi) #endif +static bool +xfs_agi_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_agi *agi = XFS_BUF_TO_AGI(bp); + + if (xfs_sb_version_hascrc(&mp->m_sb) && + !uuid_equal(&agi->agi_uuid, &mp->m_sb.sb_uuid)) + return false; + /* + * Validate the magic number of the agi block. + */ + if (agi->agi_magicnum != cpu_to_be32(XFS_AGI_MAGIC)) + return false; + if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum))) + return false; + + /* + * during growfs operations, the perag is not fully initialised, + * so we can't use it for any useful checking. growfs ensures we can't + * use it by using uncached buffers that don't have the perag attached + * so we can detect and avoid this problem. + */ + if (bp->b_pag && be32_to_cpu(agi->agi_seqno) != bp->b_pag->pag_agno) + return false; + + xfs_check_agi_unlinked(agi); + return true; +} + +static void +xfs_agi_read_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + + if (xfs_sb_version_hascrc(&mp->m_sb) && + !xfs_buf_verify_cksum(bp, XFS_AGI_CRC_OFF)) + xfs_buf_ioerror(bp, EFSBADCRC); + else if (XFS_TEST_ERROR(!xfs_agi_verify(bp), mp, + XFS_ERRTAG_IALLOC_READ_AGI, + XFS_RANDOM_IALLOC_READ_AGI)) + xfs_buf_ioerror(bp, EFSCORRUPTED); + + if (bp->b_error) + xfs_verifier_error(bp); +} + +static void +xfs_agi_write_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_buf_log_item *bip = bp->b_fspriv; + + if (!xfs_agi_verify(bp)) { + xfs_buf_ioerror(bp, EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return; + + if (bip) + XFS_BUF_TO_AGI(bp)->agi_lsn = cpu_to_be64(bip->bli_item.li_lsn); + xfs_buf_update_cksum(bp, XFS_AGI_CRC_OFF); +} + +const struct xfs_buf_ops xfs_agi_buf_ops = { + .verify_read = xfs_agi_read_verify, + .verify_write = xfs_agi_write_verify, +}; + /* * Read in the allocation group header (inode allocation section) */ @@ -1289,38 +2023,18 @@ xfs_agnumber_t agno, /* allocation group number */ struct xfs_buf **bpp) /* allocation group hdr buf */ { - struct xfs_agi *agi; /* allocation group header */ - int agi_ok; /* agi is consistent */ int error; ASSERT(agno != NULLAGNUMBER); error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), - XFS_FSS_TO_BB(mp, 1), 0, bpp); + XFS_FSS_TO_BB(mp, 1), 0, bpp, &xfs_agi_buf_ops); if (error) return error; - ASSERT(*bpp && !XFS_BUF_GETERROR(*bpp)); - agi = XFS_BUF_TO_AGI(*bpp); - - /* - * Validate the magic number of the agi block. - */ - agi_ok = be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC && - XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)) && - be32_to_cpu(agi->agi_seqno) == agno; - if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI, - XFS_RANDOM_IALLOC_READ_AGI))) { - XFS_CORRUPTION_ERROR("xfs_read_agi", XFS_ERRLEVEL_LOW, - mp, agi); - xfs_trans_brelse(tp, *bpp); - return XFS_ERROR(EFSCORRUPTED); - } - - XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_AGI, XFS_AGI_REF); - - xfs_check_agi_unlinked(agi); + ASSERT(!xfs_buf_geterror(*bpp)); + xfs_buf_set_ref(*bpp, XFS_AGI_REF); return 0; } diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_inode_buf.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_inode_buf.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_inode_buf.c 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_inode_buf.c 2014-05-02 00:09:16.000000000 +0000 @@ -0,0 +1,440 @@ +/* + * Copyright (c) 2000-2006 Silicon Graphics, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Check that none of the inode's in the buffer have a next + * unlinked field of 0. + */ +#if defined(DEBUG) +void +xfs_inobp_check( + xfs_mount_t *mp, + xfs_buf_t *bp) +{ + int i; + int j; + xfs_dinode_t *dip; + + j = mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog; + + for (i = 0; i < j; i++) { + dip = (xfs_dinode_t *)xfs_buf_offset(bp, + i * mp->m_sb.sb_inodesize); + if (!dip->di_next_unlinked) { + xfs_alert(mp, + "Detected bogus zero next_unlinked field in inode %d buffer 0x%llx.", + i, (long long)bp->b_bn); + } + } +} +#endif + +/* + * If we are doing readahead on an inode buffer, we might be in log recovery + * reading an inode allocation buffer that hasn't yet been replayed, and hence + * has not had the inode cores stamped into it. Hence for readahead, the buffer + * may be potentially invalid. + * + * If the readahead buffer is invalid, we don't want to mark it with an error, + * but we do want to clear the DONE status of the buffer so that a followup read + * will re-read it from disk. This will ensure that we don't get an unnecessary + * warnings during log recovery and we don't get unnecessary panics on debug + * kernels. + */ +static void +xfs_inode_buf_verify( + struct xfs_buf *bp, + bool readahead) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + int i; + int ni; + + /* + * Validate the magic number and version of every inode in the buffer + */ + ni = XFS_BB_TO_FSB(mp, bp->b_length) * mp->m_sb.sb_inopblock; + for (i = 0; i < ni; i++) { + int di_ok; + xfs_dinode_t *dip; + + dip = (struct xfs_dinode *)xfs_buf_offset(bp, + (i << mp->m_sb.sb_inodelog)); + di_ok = dip->di_magic == cpu_to_be16(XFS_DINODE_MAGIC) && + XFS_DINODE_GOOD_VERSION(dip->di_version); + if (unlikely(XFS_TEST_ERROR(!di_ok, mp, + XFS_ERRTAG_ITOBP_INOTOBP, + XFS_RANDOM_ITOBP_INOTOBP))) { + if (readahead) { + bp->b_flags &= ~XBF_DONE; + return; + } + + xfs_buf_ioerror(bp, EFSCORRUPTED); + xfs_verifier_error(bp); +#ifdef DEBUG + xfs_alert(mp, + "bad inode magic/vsn daddr %lld #%d (magic=%x)", + (unsigned long long)bp->b_bn, i, + be16_to_cpu(dip->di_magic)); +#endif + } + } + xfs_inobp_check(mp, bp); +} + + +static void +xfs_inode_buf_read_verify( + struct xfs_buf *bp) +{ + xfs_inode_buf_verify(bp, false); +} + +static void +xfs_inode_buf_readahead_verify( + struct xfs_buf *bp) +{ + xfs_inode_buf_verify(bp, true); +} + +static void +xfs_inode_buf_write_verify( + struct xfs_buf *bp) +{ + xfs_inode_buf_verify(bp, false); +} + +const struct xfs_buf_ops xfs_inode_buf_ops = { + .verify_read = xfs_inode_buf_read_verify, + .verify_write = xfs_inode_buf_write_verify, +}; + +const struct xfs_buf_ops xfs_inode_buf_ra_ops = { + .verify_read = xfs_inode_buf_readahead_verify, + .verify_write = xfs_inode_buf_write_verify, +}; + + +/* + * This routine is called to map an inode to the buffer containing the on-disk + * version of the inode. It returns a pointer to the buffer containing the + * on-disk inode in the bpp parameter, and in the dipp parameter it returns a + * pointer to the on-disk inode within that buffer. + * + * If a non-zero error is returned, then the contents of bpp and dipp are + * undefined. + */ +int +xfs_imap_to_bp( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_imap *imap, + struct xfs_dinode **dipp, + struct xfs_buf **bpp, + uint buf_flags, + uint iget_flags) +{ + struct xfs_buf *bp; + int error; + + buf_flags |= XBF_UNMAPPED; + error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno, + (int)imap->im_len, buf_flags, &bp, + &xfs_inode_buf_ops); + if (error) { + if (error == EAGAIN) { + ASSERT(buf_flags & XBF_TRYLOCK); + return error; + } + + if (error == EFSCORRUPTED && + (iget_flags & XFS_IGET_UNTRUSTED)) + return XFS_ERROR(EINVAL); + + xfs_warn(mp, "%s: xfs_trans_read_buf() returned error %d.", + __func__, error); + return error; + } + + *bpp = bp; + *dipp = (struct xfs_dinode *)xfs_buf_offset(bp, imap->im_boffset); + return 0; +} + +void +xfs_dinode_from_disk( + xfs_icdinode_t *to, + xfs_dinode_t *from) +{ + to->di_magic = be16_to_cpu(from->di_magic); + to->di_mode = be16_to_cpu(from->di_mode); + to->di_version = from ->di_version; + to->di_format = from->di_format; + to->di_onlink = be16_to_cpu(from->di_onlink); + to->di_uid = be32_to_cpu(from->di_uid); + to->di_gid = be32_to_cpu(from->di_gid); + to->di_nlink = be32_to_cpu(from->di_nlink); + to->di_projid_lo = be16_to_cpu(from->di_projid_lo); + to->di_projid_hi = be16_to_cpu(from->di_projid_hi); + memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); + to->di_flushiter = be16_to_cpu(from->di_flushiter); + to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec); + to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec); + to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec); + to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec); + to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec); + to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec); + to->di_size = be64_to_cpu(from->di_size); + to->di_nblocks = be64_to_cpu(from->di_nblocks); + to->di_extsize = be32_to_cpu(from->di_extsize); + to->di_nextents = be32_to_cpu(from->di_nextents); + to->di_anextents = be16_to_cpu(from->di_anextents); + to->di_forkoff = from->di_forkoff; + to->di_aformat = from->di_aformat; + to->di_dmevmask = be32_to_cpu(from->di_dmevmask); + to->di_dmstate = be16_to_cpu(from->di_dmstate); + to->di_flags = be16_to_cpu(from->di_flags); + to->di_gen = be32_to_cpu(from->di_gen); + + if (to->di_version == 3) { + to->di_changecount = be64_to_cpu(from->di_changecount); + to->di_crtime.t_sec = be32_to_cpu(from->di_crtime.t_sec); + to->di_crtime.t_nsec = be32_to_cpu(from->di_crtime.t_nsec); + to->di_flags2 = be64_to_cpu(from->di_flags2); + to->di_ino = be64_to_cpu(from->di_ino); + to->di_lsn = be64_to_cpu(from->di_lsn); + memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); + uuid_copy(&to->di_uuid, &from->di_uuid); + } +} + +void +xfs_dinode_to_disk( + xfs_dinode_t *to, + xfs_icdinode_t *from) +{ + to->di_magic = cpu_to_be16(from->di_magic); + to->di_mode = cpu_to_be16(from->di_mode); + to->di_version = from ->di_version; + to->di_format = from->di_format; + to->di_onlink = cpu_to_be16(from->di_onlink); + to->di_uid = cpu_to_be32(from->di_uid); + to->di_gid = cpu_to_be32(from->di_gid); + to->di_nlink = cpu_to_be32(from->di_nlink); + to->di_projid_lo = cpu_to_be16(from->di_projid_lo); + to->di_projid_hi = cpu_to_be16(from->di_projid_hi); + memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); + to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec); + to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec); + to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec); + to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec); + to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec); + to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec); + to->di_size = cpu_to_be64(from->di_size); + to->di_nblocks = cpu_to_be64(from->di_nblocks); + to->di_extsize = cpu_to_be32(from->di_extsize); + to->di_nextents = cpu_to_be32(from->di_nextents); + to->di_anextents = cpu_to_be16(from->di_anextents); + to->di_forkoff = from->di_forkoff; + to->di_aformat = from->di_aformat; + to->di_dmevmask = cpu_to_be32(from->di_dmevmask); + to->di_dmstate = cpu_to_be16(from->di_dmstate); + to->di_flags = cpu_to_be16(from->di_flags); + to->di_gen = cpu_to_be32(from->di_gen); + + if (from->di_version == 3) { + to->di_changecount = cpu_to_be64(from->di_changecount); + to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec); + to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec); + to->di_flags2 = cpu_to_be64(from->di_flags2); + to->di_ino = cpu_to_be64(from->di_ino); + to->di_lsn = cpu_to_be64(from->di_lsn); + memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); + uuid_copy(&to->di_uuid, &from->di_uuid); + to->di_flushiter = 0; + } else { + to->di_flushiter = cpu_to_be16(from->di_flushiter); + } +} + +bool +xfs_dinode_verify( + struct xfs_mount *mp, + xfs_ino_t ino, + struct xfs_dinode *dip) +{ + if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC)) + return false; + + /* only version 3 or greater inodes are extensively verified here */ + if (dip->di_version < 3) + return true; + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return false; + if (!xfs_verify_cksum((char *)dip, mp->m_sb.sb_inodesize, + XFS_DINODE_CRC_OFF)) + return false; + if (be64_to_cpu(dip->di_ino) != ino) + return false; + if (!uuid_equal(&dip->di_uuid, &mp->m_sb.sb_uuid)) + return false; + return true; +} + +void +xfs_dinode_calc_crc( + struct xfs_mount *mp, + struct xfs_dinode *dip) +{ + __uint32_t crc; + + if (dip->di_version < 3) + return; + + ASSERT(xfs_sb_version_hascrc(&mp->m_sb)); + crc = xfs_start_cksum((char *)dip, mp->m_sb.sb_inodesize, + XFS_DINODE_CRC_OFF); + dip->di_crc = xfs_end_cksum(crc); +} + +/* + * Read the disk inode attributes into the in-core inode structure. + */ +int +xfs_iread( + xfs_mount_t *mp, + xfs_trans_t *tp, + xfs_inode_t *ip, + uint iget_flags) +{ + xfs_buf_t *bp; + xfs_dinode_t *dip; + int error; + + /* + * Fill in the location information in the in-core inode. + */ + error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, iget_flags); + if (error) + return error; + + /* + * Get pointers to the on-disk inode and the buffer containing it. + */ + error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &bp, 0, iget_flags); + if (error) + return error; + + /* even unallocated inodes are verified */ + if (!xfs_dinode_verify(mp, ip->i_ino, dip)) { + xfs_alert(mp, "%s: validation failed for inode %lld failed", + __func__, ip->i_ino); + + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, dip); + error = XFS_ERROR(EFSCORRUPTED); + goto out_brelse; + } + + /* + * If the on-disk inode is already linked to a directory + * entry, copy all of the inode into the in-core inode. + * xfs_iformat_fork() handles copying in the inode format + * specific information. + * Otherwise, just get the truly permanent information. + */ + if (dip->di_mode) { + xfs_dinode_from_disk(&ip->i_d, dip); + error = xfs_iformat_fork(ip, dip); + if (error) { +#ifdef DEBUG + xfs_alert(mp, "%s: xfs_iformat() returned error %d", + __func__, error); +#endif /* DEBUG */ + goto out_brelse; + } + } else { + /* + * Partial initialisation of the in-core inode. Just the bits + * that xfs_ialloc won't overwrite or relies on being correct. + */ + ip->i_d.di_magic = be16_to_cpu(dip->di_magic); + ip->i_d.di_version = dip->di_version; + ip->i_d.di_gen = be32_to_cpu(dip->di_gen); + ip->i_d.di_flushiter = be16_to_cpu(dip->di_flushiter); + + if (dip->di_version == 3) { + ip->i_d.di_ino = be64_to_cpu(dip->di_ino); + uuid_copy(&ip->i_d.di_uuid, &dip->di_uuid); + } + + /* + * Make sure to pull in the mode here as well in + * case the inode is released without being used. + * This ensures that xfs_inactive() will see that + * the inode is already free and not try to mess + * with the uninitialized part of it. + */ + ip->i_d.di_mode = 0; + } + + /* + * The inode format changed when we moved the link count and + * made it 32 bits long. If this is an old format inode, + * convert it in memory to look like a new one. If it gets + * flushed to disk we will convert back before flushing or + * logging it. We zero out the new projid field and the old link + * count field. We'll handle clearing the pad field (the remains + * of the old uuid field) when we actually convert the inode to + * the new format. We don't change the version number so that we + * can distinguish this from a real new format inode. + */ + if (ip->i_d.di_version == 1) { + ip->i_d.di_nlink = ip->i_d.di_onlink; + ip->i_d.di_onlink = 0; + xfs_set_projid(&ip->i_d, 0); + } + + ip->i_delayed_blks = 0; + + /* + * Mark the buffer containing the inode as something to keep + * around for a while. This helps to keep recently accessed + * meta-data in-core longer. + */ + xfs_buf_set_ref(bp, XFS_INO_REF); + + /* + * Use xfs_trans_brelse() to release the buffer containing the on-disk + * inode, because it was acquired with xfs_trans_read_buf() in + * xfs_imap_to_bp() above. If tp is NULL, this is just a normal + * brelse(). If we're within a transaction, then xfs_trans_brelse() + * will only release the buffer if it is not dirty within the + * transaction. It will be OK to release the buffer in this case, + * because inodes on disk are never destroyed and we will be locking the + * new in-core inode before putting it in the cache where other + * processes can find it. Thus we don't have to worry about the inode + * being changed just because we released the buffer. + */ + out_brelse: + xfs_trans_brelse(tp, bp); + return error; +} diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_inode.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_inode.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_inode.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_inode.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,2180 +0,0 @@ -/* - * Copyright (c) 2000-2006 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -kmem_zone_t *xfs_ifork_zone; -kmem_zone_t *xfs_inode_zone; - -STATIC int xfs_iformat_local(xfs_inode_t *, xfs_dinode_t *, int, int); -STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int); -STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int); - -#ifdef DEBUG -/* - * Make sure that the extents in the given memory buffer - * are valid. - */ -STATIC void -xfs_validate_extents( - xfs_ifork_t *ifp, - int nrecs, - xfs_exntfmt_t fmt) -{ - xfs_bmbt_irec_t irec; - xfs_bmbt_rec_host_t rec; - int i; - - for (i = 0; i < nrecs; i++) { - xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); - rec.l0 = get_unaligned(&ep->l0); - rec.l1 = get_unaligned(&ep->l1); - xfs_bmbt_get_all(&rec, &irec); - if (fmt == XFS_EXTFMT_NOSTATE) - ASSERT(irec.br_state == XFS_EXT_NORM); - } -} -#else /* DEBUG */ -#define xfs_validate_extents(ifp, nrecs, fmt) -#endif /* DEBUG */ - -/* - * Check that none of the inode's in the buffer have a next - * unlinked field of 0. - */ -#if defined(DEBUG) -void -xfs_inobp_check( - xfs_mount_t *mp, - xfs_buf_t *bp) -{ - int i; - int j; - xfs_dinode_t *dip; - - j = mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog; - - for (i = 0; i < j; i++) { - dip = (xfs_dinode_t *)xfs_buf_offset(bp, - i * mp->m_sb.sb_inodesize); - if (!dip->di_next_unlinked) { - xfs_fs_cmn_err(CE_ALERT, mp, - "Detected a bogus zero next_unlinked field in incore inode buffer 0x%p. About to pop an ASSERT.", - bp); - ASSERT(dip->di_next_unlinked); - } - } -} -#endif - -/* - * Find the buffer associated with the given inode map - * We do basic validation checks on the buffer once it has been - * retrieved from disk. - */ -int -xfs_imap_to_bp( - xfs_mount_t *mp, - xfs_trans_t *tp, - struct xfs_imap *imap, - xfs_buf_t **bpp, - uint buf_flags, - uint iget_flags) -{ - int error; - int i; - int ni; - xfs_buf_t *bp; - - error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno, - (int)imap->im_len, buf_flags, &bp); - if (error) { - if (error != EAGAIN) { - cmn_err(CE_WARN, - "xfs_imap_to_bp: xfs_trans_read_buf()returned " - "an error %d on %s. Returning error.", - error, mp->m_fsname); - } else { - ASSERT(buf_flags & XBF_TRYLOCK); - } - return error; - } - - /* - * Validate the magic number and version of every inode in the buffer - * (if DEBUG kernel) or the first inode in the buffer, otherwise. - */ -#ifdef DEBUG - ni = BBTOB(imap->im_len) >> mp->m_sb.sb_inodelog; -#else /* usual case */ - ni = 1; -#endif - - for (i = 0; i < ni; i++) { - int di_ok; - xfs_dinode_t *dip; - - dip = (xfs_dinode_t *)xfs_buf_offset(bp, - (i << mp->m_sb.sb_inodelog)); - di_ok = be16_to_cpu(dip->di_magic) == XFS_DINODE_MAGIC && - XFS_DINODE_GOOD_VERSION(dip->di_version); - if (unlikely(XFS_TEST_ERROR(!di_ok, mp, - XFS_ERRTAG_ITOBP_INOTOBP, - XFS_RANDOM_ITOBP_INOTOBP))) { - if (iget_flags & XFS_IGET_UNTRUSTED) { - xfs_trans_brelse(tp, bp); - return XFS_ERROR(EINVAL); - } - XFS_CORRUPTION_ERROR("xfs_imap_to_bp", - XFS_ERRLEVEL_HIGH, mp, dip); -#ifdef DEBUG - cmn_err(CE_PANIC, - "Device %s - bad inode magic/vsn " - "daddr %lld #%d (magic=%x)", - XFS_BUFTARG_NAME(mp->m_ddev_targp), - (unsigned long long)imap->im_blkno, i, - be16_to_cpu(dip->di_magic)); -#endif - xfs_trans_brelse(tp, bp); - return XFS_ERROR(EFSCORRUPTED); - } - } - - xfs_inobp_check(mp, bp); - - /* - * Mark the buffer as an inode buffer now that it looks good - */ - XFS_BUF_SET_VTYPE(bp, B_FS_INO); - - *bpp = bp; - return 0; -} - -/* - * This routine is called to map an inode number within a file - * system to the buffer containing the on-disk version of the - * inode. It returns a pointer to the buffer containing the - * on-disk inode in the bpp parameter, and in the dip parameter - * it returns a pointer to the on-disk inode within that buffer. - * - * If a non-zero error is returned, then the contents of bpp and - * dipp are undefined. - * - * Use xfs_imap() to determine the size and location of the - * buffer to read from disk. - */ -int -xfs_inotobp( - xfs_mount_t *mp, - xfs_trans_t *tp, - xfs_ino_t ino, - xfs_dinode_t **dipp, - xfs_buf_t **bpp, - int *offset, - uint imap_flags) -{ - struct xfs_imap imap; - xfs_buf_t *bp; - int error; - - imap.im_blkno = 0; - error = xfs_imap(mp, tp, ino, &imap, imap_flags); - if (error) - return error; - - error = xfs_imap_to_bp(mp, tp, &imap, &bp, XBF_LOCK, imap_flags); - if (error) - return error; - - *dipp = (xfs_dinode_t *)xfs_buf_offset(bp, imap.im_boffset); - *bpp = bp; - *offset = imap.im_boffset; - return 0; -} - - -/* - * This routine is called to map an inode to the buffer containing - * the on-disk version of the inode. It returns a pointer to the - * buffer containing the on-disk inode in the bpp parameter, and in - * the dip parameter it returns a pointer to the on-disk inode within - * that buffer. - * - * If a non-zero error is returned, then the contents of bpp and - * dipp are undefined. - * - * The inode is expected to already been mapped to its buffer and read - * in once, thus we can use the mapping information stored in the inode - * rather than calling xfs_imap(). This allows us to avoid the overhead - * of looking at the inode btree for small block file systems - * (see xfs_imap()). - */ -int -xfs_itobp( - xfs_mount_t *mp, - xfs_trans_t *tp, - xfs_inode_t *ip, - xfs_dinode_t **dipp, - xfs_buf_t **bpp, - uint buf_flags) -{ - xfs_buf_t *bp; - int error; - - ASSERT(ip->i_imap.im_blkno != 0); - - error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp, buf_flags, 0); - if (error) - return error; - - if (!bp) { - ASSERT(buf_flags & XBF_TRYLOCK); - ASSERT(tp == NULL); - *bpp = NULL; - return EAGAIN; - } - - *dipp = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset); - *bpp = bp; - return 0; -} - -/* - * Move inode type and inode format specific information from the - * on-disk inode to the in-core inode. For fifos, devs, and sockets - * this means set if_rdev to the proper value. For files, directories, - * and symlinks this means to bring in the in-line data or extent - * pointers. For a file in B-tree format, only the root is immediately - * brought in-core. The rest will be in-lined in if_extents when it - * is first referenced (see xfs_iread_extents()). - */ -int -xfs_iformat( - xfs_inode_t *ip, - xfs_dinode_t *dip) -{ - xfs_attr_shortform_t *atp; - int size; - int error; - xfs_fsize_t di_size; - ip->i_df.if_ext_max = - XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); - error = 0; - - if (unlikely(be32_to_cpu(dip->di_nextents) + - be16_to_cpu(dip->di_anextents) > - be64_to_cpu(dip->di_nblocks))) { - xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.", - (unsigned long long)ip->i_ino, - (int)(be32_to_cpu(dip->di_nextents) + - be16_to_cpu(dip->di_anextents)), - (unsigned long long) - be64_to_cpu(dip->di_nblocks)); - XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW, - ip->i_mount, dip); - return XFS_ERROR(EFSCORRUPTED); - } - - if (unlikely(dip->di_forkoff > ip->i_mount->m_sb.sb_inodesize)) { - xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt dinode %Lu, forkoff = 0x%x.", - (unsigned long long)ip->i_ino, - dip->di_forkoff); - XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW, - ip->i_mount, dip); - return XFS_ERROR(EFSCORRUPTED); - } - - if (unlikely((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) && - !ip->i_mount->m_rtdev)) { - xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt dinode %Lu, has realtime flag set.", - ip->i_ino); - XFS_CORRUPTION_ERROR("xfs_iformat(realtime)", - XFS_ERRLEVEL_LOW, ip->i_mount, dip); - return XFS_ERROR(EFSCORRUPTED); - } - - switch (ip->i_d.di_mode & S_IFMT) { - case S_IFIFO: - case S_IFCHR: - case S_IFBLK: - case S_IFSOCK: - if (unlikely(dip->di_format != XFS_DINODE_FMT_DEV)) { - XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW, - ip->i_mount, dip); - return XFS_ERROR(EFSCORRUPTED); - } - ip->i_d.di_size = 0; - ip->i_size = 0; - ip->i_df.if_u2.if_rdev = xfs_dinode_get_rdev(dip); - break; - - case S_IFREG: - case S_IFLNK: - case S_IFDIR: - switch (dip->di_format) { - case XFS_DINODE_FMT_LOCAL: - /* - * no local regular files yet - */ - if (unlikely((be16_to_cpu(dip->di_mode) & S_IFMT) == S_IFREG)) { - xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt inode %Lu " - "(local format for regular file).", - (unsigned long long) ip->i_ino); - XFS_CORRUPTION_ERROR("xfs_iformat(4)", - XFS_ERRLEVEL_LOW, - ip->i_mount, dip); - return XFS_ERROR(EFSCORRUPTED); - } - - di_size = be64_to_cpu(dip->di_size); - if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) { - xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt inode %Lu " - "(bad size %Ld for local inode).", - (unsigned long long) ip->i_ino, - (long long) di_size); - XFS_CORRUPTION_ERROR("xfs_iformat(5)", - XFS_ERRLEVEL_LOW, - ip->i_mount, dip); - return XFS_ERROR(EFSCORRUPTED); - } - - size = (int)di_size; - error = xfs_iformat_local(ip, dip, XFS_DATA_FORK, size); - break; - case XFS_DINODE_FMT_EXTENTS: - error = xfs_iformat_extents(ip, dip, XFS_DATA_FORK); - break; - case XFS_DINODE_FMT_BTREE: - error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK); - break; - default: - XFS_ERROR_REPORT("xfs_iformat(6)", XFS_ERRLEVEL_LOW, - ip->i_mount); - return XFS_ERROR(EFSCORRUPTED); - } - break; - - default: - XFS_ERROR_REPORT("xfs_iformat(7)", XFS_ERRLEVEL_LOW, ip->i_mount); - return XFS_ERROR(EFSCORRUPTED); - } - if (error) { - return error; - } - if (!XFS_DFORK_Q(dip)) - return 0; - ASSERT(ip->i_afp == NULL); - ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP | KM_NOFS); - ip->i_afp->if_ext_max = - XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); - switch (dip->di_aformat) { - case XFS_DINODE_FMT_LOCAL: - atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); - size = be16_to_cpu(atp->hdr.totsize); - - if (unlikely(size < sizeof(struct xfs_attr_sf_hdr))) { - xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt inode %Lu " - "(bad attr fork size %Ld).", - (unsigned long long) ip->i_ino, - (long long) size); - XFS_CORRUPTION_ERROR("xfs_iformat(8)", - XFS_ERRLEVEL_LOW, - ip->i_mount, dip); - return XFS_ERROR(EFSCORRUPTED); - } - - error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, size); - break; - case XFS_DINODE_FMT_EXTENTS: - error = xfs_iformat_extents(ip, dip, XFS_ATTR_FORK); - break; - case XFS_DINODE_FMT_BTREE: - error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK); - break; - default: - error = XFS_ERROR(EFSCORRUPTED); - break; - } - if (error) { - kmem_zone_free(xfs_ifork_zone, ip->i_afp); - ip->i_afp = NULL; - xfs_idestroy_fork(ip, XFS_DATA_FORK); - } - return error; -} - -/* - * The file is in-lined in the on-disk inode. - * If it fits into if_inline_data, then copy - * it there, otherwise allocate a buffer for it - * and copy the data there. Either way, set - * if_data to point at the data. - * If we allocate a buffer for the data, make - * sure that its size is a multiple of 4 and - * record the real size in i_real_bytes. - */ -STATIC int -xfs_iformat_local( - xfs_inode_t *ip, - xfs_dinode_t *dip, - int whichfork, - int size) -{ - xfs_ifork_t *ifp; - int real_size; - - /* - * If the size is unreasonable, then something - * is wrong and we just bail out rather than crash in - * kmem_alloc() or memcpy() below. - */ - if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) { - xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt inode %Lu " - "(bad size %d for local fork, size = %d).", - (unsigned long long) ip->i_ino, size, - XFS_DFORK_SIZE(dip, ip->i_mount, whichfork)); - XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW, - ip->i_mount, dip); - return XFS_ERROR(EFSCORRUPTED); - } - ifp = XFS_IFORK_PTR(ip, whichfork); - real_size = 0; - if (size == 0) - ifp->if_u1.if_data = NULL; - else if (size <= sizeof(ifp->if_u2.if_inline_data)) - ifp->if_u1.if_data = ifp->if_u2.if_inline_data; - else { - real_size = roundup(size, 4); - ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP | KM_NOFS); - } - ifp->if_bytes = size; - ifp->if_real_bytes = real_size; - if (size) - memcpy(ifp->if_u1.if_data, XFS_DFORK_PTR(dip, whichfork), size); - ifp->if_flags &= ~XFS_IFEXTENTS; - ifp->if_flags |= XFS_IFINLINE; - return 0; -} - -/* - * The file consists of a set of extents all - * of which fit into the on-disk inode. - * If there are few enough extents to fit into - * the if_inline_ext, then copy them there. - * Otherwise allocate a buffer for them and copy - * them into it. Either way, set if_extents - * to point at the extents. - */ -STATIC int -xfs_iformat_extents( - xfs_inode_t *ip, - xfs_dinode_t *dip, - int whichfork) -{ - xfs_bmbt_rec_t *dp; - xfs_ifork_t *ifp; - int nex; - int size; - int i; - - ifp = XFS_IFORK_PTR(ip, whichfork); - nex = XFS_DFORK_NEXTENTS(dip, whichfork); - size = nex * (uint)sizeof(xfs_bmbt_rec_t); - - /* - * If the number of extents is unreasonable, then something - * is wrong and we just bail out rather than crash in - * kmem_alloc() or memcpy() below. - */ - if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) { - xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt inode %Lu ((a)extents = %d).", - (unsigned long long) ip->i_ino, nex); - XFS_CORRUPTION_ERROR("xfs_iformat_extents(1)", XFS_ERRLEVEL_LOW, - ip->i_mount, dip); - return XFS_ERROR(EFSCORRUPTED); - } - - ifp->if_real_bytes = 0; - if (nex == 0) - ifp->if_u1.if_extents = NULL; - else if (nex <= XFS_INLINE_EXTS) - ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; - else - xfs_iext_add(ifp, 0, nex); - - ifp->if_bytes = size; - if (size) { - dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork); - xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip)); - for (i = 0; i < nex; i++, dp++) { - xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); - ep->l0 = get_unaligned_be64(&dp->l0); - ep->l1 = get_unaligned_be64(&dp->l1); - } - XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork); - if (whichfork != XFS_DATA_FORK || - XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE) - if (unlikely(xfs_check_nostate_extents( - ifp, 0, nex))) { - XFS_ERROR_REPORT("xfs_iformat_extents(2)", - XFS_ERRLEVEL_LOW, - ip->i_mount); - return XFS_ERROR(EFSCORRUPTED); - } - } - ifp->if_flags |= XFS_IFEXTENTS; - return 0; -} - -/* - * The file has too many extents to fit into - * the inode, so they are in B-tree format. - * Allocate a buffer for the root of the B-tree - * and copy the root into it. The i_extents - * field will remain NULL until all of the - * extents are read in (when they are needed). - */ -STATIC int -xfs_iformat_btree( - xfs_inode_t *ip, - xfs_dinode_t *dip, - int whichfork) -{ - xfs_bmdr_block_t *dfp; - xfs_ifork_t *ifp; - /* REFERENCED */ - int nrecs; - int size; - - ifp = XFS_IFORK_PTR(ip, whichfork); - dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); - size = XFS_BMAP_BROOT_SPACE(dfp); - nrecs = be16_to_cpu(dfp->bb_numrecs); - - /* - * blow out if -- fork has less extents than can fit in - * fork (fork shouldn't be a btree format), root btree - * block has more records than can fit into the fork, - * or the number of extents is greater than the number of - * blocks. - */ - if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max - || XFS_BMDR_SPACE_CALC(nrecs) > - XFS_DFORK_SIZE(dip, ip->i_mount, whichfork) - || XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) { - xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt inode %Lu (btree).", - (unsigned long long) ip->i_ino); - XFS_ERROR_REPORT("xfs_iformat_btree", XFS_ERRLEVEL_LOW, - ip->i_mount); - return XFS_ERROR(EFSCORRUPTED); - } - - ifp->if_broot_bytes = size; - ifp->if_broot = kmem_alloc(size, KM_SLEEP | KM_NOFS); - ASSERT(ifp->if_broot != NULL); - /* - * Copy and convert from the on-disk structure - * to the in-memory structure. - */ - xfs_bmdr_to_bmbt(ip->i_mount, dfp, - XFS_DFORK_SIZE(dip, ip->i_mount, whichfork), - ifp->if_broot, size); - ifp->if_flags &= ~XFS_IFEXTENTS; - ifp->if_flags |= XFS_IFBROOT; - - return 0; -} - -void -xfs_dinode_from_disk( - xfs_icdinode_t *to, - xfs_dinode_t *from) -{ - to->di_magic = be16_to_cpu(from->di_magic); - to->di_mode = be16_to_cpu(from->di_mode); - to->di_version = from ->di_version; - to->di_format = from->di_format; - to->di_onlink = be16_to_cpu(from->di_onlink); - to->di_uid = be32_to_cpu(from->di_uid); - to->di_gid = be32_to_cpu(from->di_gid); - to->di_nlink = be32_to_cpu(from->di_nlink); - to->di_projid_lo = be16_to_cpu(from->di_projid_lo); - to->di_projid_hi = be16_to_cpu(from->di_projid_hi); - memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); - to->di_flushiter = be16_to_cpu(from->di_flushiter); - to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec); - to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec); - to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec); - to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec); - to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec); - to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec); - to->di_size = be64_to_cpu(from->di_size); - to->di_nblocks = be64_to_cpu(from->di_nblocks); - to->di_extsize = be32_to_cpu(from->di_extsize); - to->di_nextents = be32_to_cpu(from->di_nextents); - to->di_anextents = be16_to_cpu(from->di_anextents); - to->di_forkoff = from->di_forkoff; - to->di_aformat = from->di_aformat; - to->di_dmevmask = be32_to_cpu(from->di_dmevmask); - to->di_dmstate = be16_to_cpu(from->di_dmstate); - to->di_flags = be16_to_cpu(from->di_flags); - to->di_gen = be32_to_cpu(from->di_gen); -} - -void -xfs_dinode_to_disk( - xfs_dinode_t *to, - xfs_icdinode_t *from) -{ - to->di_magic = cpu_to_be16(from->di_magic); - to->di_mode = cpu_to_be16(from->di_mode); - to->di_version = from ->di_version; - to->di_format = from->di_format; - to->di_onlink = cpu_to_be16(from->di_onlink); - to->di_uid = cpu_to_be32(from->di_uid); - to->di_gid = cpu_to_be32(from->di_gid); - to->di_nlink = cpu_to_be32(from->di_nlink); - to->di_projid_lo = cpu_to_be16(from->di_projid_lo); - to->di_projid_hi = cpu_to_be16(from->di_projid_hi); - memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); - to->di_flushiter = cpu_to_be16(from->di_flushiter); - to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec); - to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec); - to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec); - to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec); - to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec); - to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec); - to->di_size = cpu_to_be64(from->di_size); - to->di_nblocks = cpu_to_be64(from->di_nblocks); - to->di_extsize = cpu_to_be32(from->di_extsize); - to->di_nextents = cpu_to_be32(from->di_nextents); - to->di_anextents = cpu_to_be16(from->di_anextents); - to->di_forkoff = from->di_forkoff; - to->di_aformat = from->di_aformat; - to->di_dmevmask = cpu_to_be32(from->di_dmevmask); - to->di_dmstate = cpu_to_be16(from->di_dmstate); - to->di_flags = cpu_to_be16(from->di_flags); - to->di_gen = cpu_to_be32(from->di_gen); -} - -/* - * Read in extents from a btree-format inode. - * Allocate and fill in if_extents. Real work is done in xfs_bmap.c. - */ -int -xfs_iread_extents( - xfs_trans_t *tp, - xfs_inode_t *ip, - int whichfork) -{ - int error; - xfs_ifork_t *ifp; - xfs_extnum_t nextents; - - if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) { - XFS_ERROR_REPORT("xfs_iread_extents", XFS_ERRLEVEL_LOW, - ip->i_mount); - return XFS_ERROR(EFSCORRUPTED); - } - nextents = XFS_IFORK_NEXTENTS(ip, whichfork); - ifp = XFS_IFORK_PTR(ip, whichfork); - - /* - * We know that the size is valid (it's checked in iformat_btree) - */ - ifp->if_lastex = NULLEXTNUM; - ifp->if_bytes = ifp->if_real_bytes = 0; - ifp->if_flags |= XFS_IFEXTENTS; - xfs_iext_add(ifp, 0, nextents); - error = xfs_bmap_read_extents(tp, ip, whichfork); - if (error) { - xfs_iext_destroy(ifp); - ifp->if_flags &= ~XFS_IFEXTENTS; - return error; - } - xfs_validate_extents(ifp, nextents, XFS_EXTFMT_INODE(ip)); - return 0; -} - -/* - * Reallocate the space for if_broot based on the number of records - * being added or deleted as indicated in rec_diff. Move the records - * and pointers in if_broot to fit the new size. When shrinking this - * will eliminate holes between the records and pointers created by - * the caller. When growing this will create holes to be filled in - * by the caller. - * - * The caller must not request to add more records than would fit in - * the on-disk inode root. If the if_broot is currently NULL, then - * if we adding records one will be allocated. The caller must also - * not request that the number of records go below zero, although - * it can go to zero. - * - * ip -- the inode whose if_broot area is changing - * ext_diff -- the change in the number of records, positive or negative, - * requested for the if_broot array. - */ -void -xfs_iroot_realloc( - xfs_inode_t *ip, - int rec_diff, - int whichfork) -{ - struct xfs_mount *mp = ip->i_mount; - int cur_max; - xfs_ifork_t *ifp; - struct xfs_btree_block *new_broot; - int new_max; - size_t new_size; - char *np; - char *op; - - /* - * Handle the degenerate case quietly. - */ - if (rec_diff == 0) { - return; - } - - ifp = XFS_IFORK_PTR(ip, whichfork); - if (rec_diff > 0) { - /* - * If there wasn't any memory allocated before, just - * allocate it now and get out. - */ - if (ifp->if_broot_bytes == 0) { - new_size = (size_t)XFS_BMAP_BROOT_SPACE_CALC(rec_diff); - ifp->if_broot = kmem_alloc(new_size, KM_SLEEP | KM_NOFS); - ifp->if_broot_bytes = (int)new_size; - return; - } - - /* - * If there is already an existing if_broot, then we need - * to realloc() it and shift the pointers to their new - * location. The records don't change location because - * they are kept butted up against the btree block header. - */ - cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0); - new_max = cur_max + rec_diff; - new_size = (size_t)XFS_BMAP_BROOT_SPACE_CALC(new_max); - ifp->if_broot = kmem_realloc(ifp->if_broot, new_size, - (size_t)XFS_BMAP_BROOT_SPACE_CALC(cur_max), /* old size */ - KM_SLEEP | KM_NOFS); - op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, - ifp->if_broot_bytes); - np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, - (int)new_size); - ifp->if_broot_bytes = (int)new_size; - ASSERT(ifp->if_broot_bytes <= - XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ); - memmove(np, op, cur_max * (uint)sizeof(xfs_dfsbno_t)); - return; - } - - /* - * rec_diff is less than 0. In this case, we are shrinking the - * if_broot buffer. It must already exist. If we go to zero - * records, just get rid of the root and clear the status bit. - */ - ASSERT((ifp->if_broot != NULL) && (ifp->if_broot_bytes > 0)); - cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0); - new_max = cur_max + rec_diff; - ASSERT(new_max >= 0); - if (new_max > 0) - new_size = (size_t)XFS_BMAP_BROOT_SPACE_CALC(new_max); - else - new_size = 0; - if (new_size > 0) { - new_broot = kmem_alloc(new_size, KM_SLEEP | KM_NOFS); - /* - * First copy over the btree block header. - */ - memcpy(new_broot, ifp->if_broot, XFS_BTREE_LBLOCK_LEN); - } else { - new_broot = NULL; - ifp->if_flags &= ~XFS_IFBROOT; - } - - /* - * Only copy the records and pointers if there are any. - */ - if (new_max > 0) { - /* - * First copy the records. - */ - op = (char *)XFS_BMBT_REC_ADDR(mp, ifp->if_broot, 1); - np = (char *)XFS_BMBT_REC_ADDR(mp, new_broot, 1); - memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t)); - - /* - * Then copy the pointers. - */ - op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, - ifp->if_broot_bytes); - np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, new_broot, 1, - (int)new_size); - memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t)); - } - kmem_free(ifp->if_broot); - ifp->if_broot = new_broot; - ifp->if_broot_bytes = (int)new_size; - ASSERT(ifp->if_broot_bytes <= - XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ); - return; -} - - -/* - * This is called when the amount of space needed for if_data - * is increased or decreased. The change in size is indicated by - * the number of bytes that need to be added or deleted in the - * byte_diff parameter. - * - * If the amount of space needed has decreased below the size of the - * inline buffer, then switch to using the inline buffer. Otherwise, - * use kmem_realloc() or kmem_alloc() to adjust the size of the buffer - * to what is needed. - * - * ip -- the inode whose if_data area is changing - * byte_diff -- the change in the number of bytes, positive or negative, - * requested for the if_data array. - */ -void -xfs_idata_realloc( - xfs_inode_t *ip, - int byte_diff, - int whichfork) -{ - xfs_ifork_t *ifp; - int new_size; - int real_size; - - if (byte_diff == 0) { - return; - } - - ifp = XFS_IFORK_PTR(ip, whichfork); - new_size = (int)ifp->if_bytes + byte_diff; - ASSERT(new_size >= 0); - - if (new_size == 0) { - if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) { - kmem_free(ifp->if_u1.if_data); - } - ifp->if_u1.if_data = NULL; - real_size = 0; - } else if (new_size <= sizeof(ifp->if_u2.if_inline_data)) { - /* - * If the valid extents/data can fit in if_inline_ext/data, - * copy them from the malloc'd vector and free it. - */ - if (ifp->if_u1.if_data == NULL) { - ifp->if_u1.if_data = ifp->if_u2.if_inline_data; - } else if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) { - ASSERT(ifp->if_real_bytes != 0); - memcpy(ifp->if_u2.if_inline_data, ifp->if_u1.if_data, - new_size); - kmem_free(ifp->if_u1.if_data); - ifp->if_u1.if_data = ifp->if_u2.if_inline_data; - } - real_size = 0; - } else { - /* - * Stuck with malloc/realloc. - * For inline data, the underlying buffer must be - * a multiple of 4 bytes in size so that it can be - * logged and stay on word boundaries. We enforce - * that here. - */ - real_size = roundup(new_size, 4); - if (ifp->if_u1.if_data == NULL) { - ASSERT(ifp->if_real_bytes == 0); - ifp->if_u1.if_data = kmem_alloc(real_size, - KM_SLEEP | KM_NOFS); - } else if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) { - /* - * Only do the realloc if the underlying size - * is really changing. - */ - if (ifp->if_real_bytes != real_size) { - ifp->if_u1.if_data = - kmem_realloc(ifp->if_u1.if_data, - real_size, - ifp->if_real_bytes, - KM_SLEEP | KM_NOFS); - } - } else { - ASSERT(ifp->if_real_bytes == 0); - ifp->if_u1.if_data = kmem_alloc(real_size, - KM_SLEEP | KM_NOFS); - memcpy(ifp->if_u1.if_data, ifp->if_u2.if_inline_data, - ifp->if_bytes); - } - } - ifp->if_real_bytes = real_size; - ifp->if_bytes = new_size; - ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); -} - -void -xfs_idestroy_fork( - xfs_inode_t *ip, - int whichfork) -{ - xfs_ifork_t *ifp; - - ifp = XFS_IFORK_PTR(ip, whichfork); - if (ifp->if_broot != NULL) { - kmem_free(ifp->if_broot); - ifp->if_broot = NULL; - } - - /* - * If the format is local, then we can't have an extents - * array so just look for an inline data array. If we're - * not local then we may or may not have an extents list, - * so check and free it up if we do. - */ - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { - if ((ifp->if_u1.if_data != ifp->if_u2.if_inline_data) && - (ifp->if_u1.if_data != NULL)) { - ASSERT(ifp->if_real_bytes != 0); - kmem_free(ifp->if_u1.if_data); - ifp->if_u1.if_data = NULL; - ifp->if_real_bytes = 0; - } - } else if ((ifp->if_flags & XFS_IFEXTENTS) && - ((ifp->if_flags & XFS_IFEXTIREC) || - ((ifp->if_u1.if_extents != NULL) && - (ifp->if_u1.if_extents != ifp->if_u2.if_inline_ext)))) { - ASSERT(ifp->if_real_bytes != 0); - xfs_iext_destroy(ifp); - } - ASSERT(ifp->if_u1.if_extents == NULL || - ifp->if_u1.if_extents == ifp->if_u2.if_inline_ext); - ASSERT(ifp->if_real_bytes == 0); - if (whichfork == XFS_ATTR_FORK) { - kmem_zone_free(xfs_ifork_zone, ip->i_afp); - ip->i_afp = NULL; - } -} - -/* - * xfs_iextents_copy() - * - * This is called to copy the REAL extents (as opposed to the delayed - * allocation extents) from the inode into the given buffer. It - * returns the number of bytes copied into the buffer. - * - * If there are no delayed allocation extents, then we can just - * memcpy() the extents into the buffer. Otherwise, we need to - * examine each extent in turn and skip those which are delayed. - */ -int -xfs_iextents_copy( - xfs_inode_t *ip, - xfs_bmbt_rec_t *dp, - int whichfork) -{ - int copied; - int i; - xfs_ifork_t *ifp; - int nrecs; - xfs_fsblock_t start_block; - - ifp = XFS_IFORK_PTR(ip, whichfork); - ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); - ASSERT(ifp->if_bytes > 0); - - nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - XFS_BMAP_TRACE_EXLIST(ip, nrecs, whichfork); - ASSERT(nrecs > 0); - - /* - * There are some delayed allocation extents in the - * inode, so copy the extents one at a time and skip - * the delayed ones. There must be at least one - * non-delayed extent. - */ - copied = 0; - for (i = 0; i < nrecs; i++) { - xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); - start_block = xfs_bmbt_get_startblock(ep); - if (isnullstartblock(start_block)) { - /* - * It's a delayed allocation extent, so skip it. - */ - continue; - } - - /* Translate to on disk format */ - put_unaligned_be64(ep->l0, &dp->l0); - put_unaligned_be64(ep->l1, &dp->l1); - dp++; - copied++; - } - ASSERT(copied != 0); - xfs_validate_extents(ifp, copied, XFS_EXTFMT_INODE(ip)); - - return (copied * (uint)sizeof(xfs_bmbt_rec_t)); -} - -/* - * Each of the following cases stores data into the same region - * of the on-disk inode, so only one of them can be valid at - * any given time. While it is possible to have conflicting formats - * and log flags, e.g. having XFS_ILOG_?DATA set when the fork is - * in EXTENTS format, this can only happen when the fork has - * changed formats after being modified but before being flushed. - * In these cases, the format always takes precedence, because the - * format indicates the current state of the fork. - */ -/*ARGSUSED*/ -void -xfs_iflush_fork( - xfs_inode_t *ip, - xfs_dinode_t *dip, - xfs_inode_log_item_t *iip, - int whichfork, - xfs_buf_t *bp) -{ - char *cp; - xfs_ifork_t *ifp; - xfs_mount_t *mp; -#ifdef XFS_TRANS_DEBUG - int first; -#endif - static const short brootflag[2] = - { XFS_ILOG_DBROOT, XFS_ILOG_ABROOT }; - static const short dataflag[2] = - { XFS_ILOG_DDATA, XFS_ILOG_ADATA }; - static const short extflag[2] = - { XFS_ILOG_DEXT, XFS_ILOG_AEXT }; - - if (!iip) - return; - ifp = XFS_IFORK_PTR(ip, whichfork); - /* - * This can happen if we gave up in iformat in an error path, - * for the attribute fork. - */ - if (!ifp) { - ASSERT(whichfork == XFS_ATTR_FORK); - return; - } - cp = XFS_DFORK_PTR(dip, whichfork); - mp = ip->i_mount; - switch (XFS_IFORK_FORMAT(ip, whichfork)) { - case XFS_DINODE_FMT_LOCAL: - if ((iip->ili_format.ilf_fields & dataflag[whichfork]) && - (ifp->if_bytes > 0)) { - ASSERT(ifp->if_u1.if_data != NULL); - ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); - memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes); - } - break; - - case XFS_DINODE_FMT_EXTENTS: - ASSERT((ifp->if_flags & XFS_IFEXTENTS) || - !(iip->ili_format.ilf_fields & extflag[whichfork])); - ASSERT((xfs_iext_get_ext(ifp, 0) != NULL) || - (ifp->if_bytes == 0)); - ASSERT((xfs_iext_get_ext(ifp, 0) == NULL) || - (ifp->if_bytes > 0)); - if ((iip->ili_format.ilf_fields & extflag[whichfork]) && - (ifp->if_bytes > 0)) { - ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); - (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp, - whichfork); - } - break; - - case XFS_DINODE_FMT_BTREE: - if ((iip->ili_format.ilf_fields & brootflag[whichfork]) && - (ifp->if_broot_bytes > 0)) { - ASSERT(ifp->if_broot != NULL); - ASSERT(ifp->if_broot_bytes <= - (XFS_IFORK_SIZE(ip, whichfork) + - XFS_BROOT_SIZE_ADJ)); - xfs_bmbt_to_bmdr(mp, ifp->if_broot, ifp->if_broot_bytes, - (xfs_bmdr_block_t *)cp, - XFS_DFORK_SIZE(dip, mp, whichfork)); - } - break; - - case XFS_DINODE_FMT_DEV: - if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) { - ASSERT(whichfork == XFS_DATA_FORK); - xfs_dinode_put_rdev(dip, ip->i_df.if_u2.if_rdev); - } - break; - - case XFS_DINODE_FMT_UUID: - if (iip->ili_format.ilf_fields & XFS_ILOG_UUID) { - ASSERT(whichfork == XFS_DATA_FORK); - memcpy(XFS_DFORK_DPTR(dip), - &ip->i_df.if_u2.if_uuid, - sizeof(uuid_t)); - } - break; - - default: - ASSERT(0); - break; - } -} - -/* - * Return a pointer to the extent record at file index idx. - */ -xfs_bmbt_rec_host_t * -xfs_iext_get_ext( - xfs_ifork_t *ifp, /* inode fork pointer */ - xfs_extnum_t idx) /* index of target extent */ -{ - ASSERT(idx >= 0); - if ((ifp->if_flags & XFS_IFEXTIREC) && (idx == 0)) { - return ifp->if_u1.if_ext_irec->er_extbuf; - } else if (ifp->if_flags & XFS_IFEXTIREC) { - xfs_ext_irec_t *erp; /* irec pointer */ - int erp_idx = 0; /* irec index */ - xfs_extnum_t page_idx = idx; /* ext index in target list */ - - erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0); - return &erp->er_extbuf[page_idx]; - } else if (ifp->if_bytes) { - return &ifp->if_u1.if_extents[idx]; - } else { - return NULL; - } -} - -/* - * Insert new item(s) into the extent records for incore inode - * fork 'ifp'. 'count' new items are inserted at index 'idx'. - */ -void -xfs_iext_insert( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* starting index of new items */ - xfs_extnum_t count, /* number of inserted items */ - xfs_bmbt_irec_t *new, /* items to insert */ - int state) /* type of extent conversion */ -{ - xfs_ifork_t *ifp = (state & BMAP_ATTRFORK) ? ip->i_afp : &ip->i_df; - xfs_extnum_t i; /* extent record index */ - - trace_xfs_iext_insert(ip, idx, new, state, _RET_IP_); - - ASSERT(ifp->if_flags & XFS_IFEXTENTS); - xfs_iext_add(ifp, idx, count); - for (i = idx; i < idx + count; i++, new++) - xfs_bmbt_set_all(xfs_iext_get_ext(ifp, i), new); -} - -/* - * This is called when the amount of space required for incore file - * extents needs to be increased. The ext_diff parameter stores the - * number of new extents being added and the idx parameter contains - * the extent index where the new extents will be added. If the new - * extents are being appended, then we just need to (re)allocate and - * initialize the space. Otherwise, if the new extents are being - * inserted into the middle of the existing entries, a bit more work - * is required to make room for the new extents to be inserted. The - * caller is responsible for filling in the new extent entries upon - * return. - */ -void -xfs_iext_add( - xfs_ifork_t *ifp, /* inode fork pointer */ - xfs_extnum_t idx, /* index to begin adding exts */ - int ext_diff) /* number of extents to add */ -{ - int byte_diff; /* new bytes being added */ - int new_size; /* size of extents after adding */ - xfs_extnum_t nextents; /* number of extents in file */ - - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - ASSERT((idx >= 0) && (idx <= nextents)); - byte_diff = ext_diff * sizeof(xfs_bmbt_rec_t); - new_size = ifp->if_bytes + byte_diff; - /* - * If the new number of extents (nextents + ext_diff) - * fits inside the inode, then continue to use the inline - * extent buffer. - */ - if (nextents + ext_diff <= XFS_INLINE_EXTS) { - if (idx < nextents) { - memmove(&ifp->if_u2.if_inline_ext[idx + ext_diff], - &ifp->if_u2.if_inline_ext[idx], - (nextents - idx) * sizeof(xfs_bmbt_rec_t)); - memset(&ifp->if_u2.if_inline_ext[idx], 0, byte_diff); - } - ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; - ifp->if_real_bytes = 0; - ifp->if_lastex = nextents + ext_diff; - } - /* - * Otherwise use a linear (direct) extent list. - * If the extents are currently inside the inode, - * xfs_iext_realloc_direct will switch us from - * inline to direct extent allocation mode. - */ - else if (nextents + ext_diff <= XFS_LINEAR_EXTS) { - xfs_iext_realloc_direct(ifp, new_size); - if (idx < nextents) { - memmove(&ifp->if_u1.if_extents[idx + ext_diff], - &ifp->if_u1.if_extents[idx], - (nextents - idx) * sizeof(xfs_bmbt_rec_t)); - memset(&ifp->if_u1.if_extents[idx], 0, byte_diff); - } - } - /* Indirection array */ - else { - xfs_ext_irec_t *erp; - int erp_idx = 0; - int page_idx = idx; - - ASSERT(nextents + ext_diff > XFS_LINEAR_EXTS); - if (ifp->if_flags & XFS_IFEXTIREC) { - erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 1); - } else { - xfs_iext_irec_init(ifp); - ASSERT(ifp->if_flags & XFS_IFEXTIREC); - erp = ifp->if_u1.if_ext_irec; - } - /* Extents fit in target extent page */ - if (erp && erp->er_extcount + ext_diff <= XFS_LINEAR_EXTS) { - if (page_idx < erp->er_extcount) { - memmove(&erp->er_extbuf[page_idx + ext_diff], - &erp->er_extbuf[page_idx], - (erp->er_extcount - page_idx) * - sizeof(xfs_bmbt_rec_t)); - memset(&erp->er_extbuf[page_idx], 0, byte_diff); - } - erp->er_extcount += ext_diff; - xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff); - } - /* Insert a new extent page */ - else if (erp) { - xfs_iext_add_indirect_multi(ifp, - erp_idx, page_idx, ext_diff); - } - /* - * If extent(s) are being appended to the last page in - * the indirection array and the new extent(s) don't fit - * in the page, then erp is NULL and erp_idx is set to - * the next index needed in the indirection array. - */ - else { - int count = ext_diff; - - while (count) { - erp = xfs_iext_irec_new(ifp, erp_idx); - erp->er_extcount = count; - count -= MIN(count, (int)XFS_LINEAR_EXTS); - if (count) { - erp_idx++; - } - } - } - } - ifp->if_bytes = new_size; -} - -/* - * This is called when incore extents are being added to the indirection - * array and the new extents do not fit in the target extent list. The - * erp_idx parameter contains the irec index for the target extent list - * in the indirection array, and the idx parameter contains the extent - * index within the list. The number of extents being added is stored - * in the count parameter. - * - * |-------| |-------| - * | | | | idx - number of extents before idx - * | idx | | count | - * | | | | count - number of extents being inserted at idx - * |-------| |-------| - * | count | | nex2 | nex2 - number of extents after idx + count - * |-------| |-------| - */ -void -xfs_iext_add_indirect_multi( - xfs_ifork_t *ifp, /* inode fork pointer */ - int erp_idx, /* target extent irec index */ - xfs_extnum_t idx, /* index within target list */ - int count) /* new extents being added */ -{ - int byte_diff; /* new bytes being added */ - xfs_ext_irec_t *erp; /* pointer to irec entry */ - xfs_extnum_t ext_diff; /* number of extents to add */ - xfs_extnum_t ext_cnt; /* new extents still needed */ - xfs_extnum_t nex2; /* extents after idx + count */ - xfs_bmbt_rec_t *nex2_ep = NULL; /* temp list for nex2 extents */ - int nlists; /* number of irec's (lists) */ - - ASSERT(ifp->if_flags & XFS_IFEXTIREC); - erp = &ifp->if_u1.if_ext_irec[erp_idx]; - nex2 = erp->er_extcount - idx; - nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; - - /* - * Save second part of target extent list - * (all extents past */ - if (nex2) { - byte_diff = nex2 * sizeof(xfs_bmbt_rec_t); - nex2_ep = (xfs_bmbt_rec_t *) kmem_alloc(byte_diff, KM_NOFS); - memmove(nex2_ep, &erp->er_extbuf[idx], byte_diff); - erp->er_extcount -= nex2; - xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -nex2); - memset(&erp->er_extbuf[idx], 0, byte_diff); - } - - /* - * Add the new extents to the end of the target - * list, then allocate new irec record(s) and - * extent buffer(s) as needed to store the rest - * of the new extents. - */ - ext_cnt = count; - ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS - erp->er_extcount); - if (ext_diff) { - erp->er_extcount += ext_diff; - xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff); - ext_cnt -= ext_diff; - } - while (ext_cnt) { - erp_idx++; - erp = xfs_iext_irec_new(ifp, erp_idx); - ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS); - erp->er_extcount = ext_diff; - xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff); - ext_cnt -= ext_diff; - } - - /* Add nex2 extents back to indirection array */ - if (nex2) { - xfs_extnum_t ext_avail; - int i; - - byte_diff = nex2 * sizeof(xfs_bmbt_rec_t); - ext_avail = XFS_LINEAR_EXTS - erp->er_extcount; - i = 0; - /* - * If nex2 extents fit in the current page, append - * nex2_ep after the new extents. - */ - if (nex2 <= ext_avail) { - i = erp->er_extcount; - } - /* - * Otherwise, check if space is available in the - * next page. - */ - else if ((erp_idx < nlists - 1) && - (nex2 <= (ext_avail = XFS_LINEAR_EXTS - - ifp->if_u1.if_ext_irec[erp_idx+1].er_extcount))) { - erp_idx++; - erp++; - /* Create a hole for nex2 extents */ - memmove(&erp->er_extbuf[nex2], erp->er_extbuf, - erp->er_extcount * sizeof(xfs_bmbt_rec_t)); - } - /* - * Final choice, create a new extent page for - * nex2 extents. - */ - else { - erp_idx++; - erp = xfs_iext_irec_new(ifp, erp_idx); - } - memmove(&erp->er_extbuf[i], nex2_ep, byte_diff); - kmem_free(nex2_ep); - erp->er_extcount += nex2; - xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, nex2); - } -} - -/* - * This is called when the amount of space required for incore file - * extents needs to be decreased. The ext_diff parameter stores the - * number of extents to be removed and the idx parameter contains - * the extent index where the extents will be removed from. - * - * If the amount of space needed has decreased below the linear - * limit, XFS_IEXT_BUFSZ, then switch to using the contiguous - * extent array. Otherwise, use kmem_realloc() to adjust the - * size to what is needed. - */ -void -xfs_iext_remove( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* index to begin removing exts */ - int ext_diff, /* number of extents to remove */ - int state) /* type of extent conversion */ -{ - xfs_ifork_t *ifp = (state & BMAP_ATTRFORK) ? ip->i_afp : &ip->i_df; - xfs_extnum_t nextents; /* number of extents in file */ - int new_size; /* size of extents after removal */ - - trace_xfs_iext_remove(ip, idx, state, _RET_IP_); - - ASSERT(ext_diff > 0); - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - new_size = (nextents - ext_diff) * sizeof(xfs_bmbt_rec_t); - - if (new_size == 0) { - xfs_iext_destroy(ifp); - } else if (ifp->if_flags & XFS_IFEXTIREC) { - xfs_iext_remove_indirect(ifp, idx, ext_diff); - } else if (ifp->if_real_bytes) { - xfs_iext_remove_direct(ifp, idx, ext_diff); - } else { - xfs_iext_remove_inline(ifp, idx, ext_diff); - } - ifp->if_bytes = new_size; -} - -/* - * This removes ext_diff extents from the inline buffer, beginning - * at extent index idx. - */ -void -xfs_iext_remove_inline( - xfs_ifork_t *ifp, /* inode fork pointer */ - xfs_extnum_t idx, /* index to begin removing exts */ - int ext_diff) /* number of extents to remove */ -{ - int nextents; /* number of extents in file */ - - ASSERT(!(ifp->if_flags & XFS_IFEXTIREC)); - ASSERT(idx < XFS_INLINE_EXTS); - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - ASSERT(((nextents - ext_diff) > 0) && - (nextents - ext_diff) < XFS_INLINE_EXTS); - - if (idx + ext_diff < nextents) { - memmove(&ifp->if_u2.if_inline_ext[idx], - &ifp->if_u2.if_inline_ext[idx + ext_diff], - (nextents - (idx + ext_diff)) * - sizeof(xfs_bmbt_rec_t)); - memset(&ifp->if_u2.if_inline_ext[nextents - ext_diff], - 0, ext_diff * sizeof(xfs_bmbt_rec_t)); - } else { - memset(&ifp->if_u2.if_inline_ext[idx], 0, - ext_diff * sizeof(xfs_bmbt_rec_t)); - } -} - -/* - * This removes ext_diff extents from a linear (direct) extent list, - * beginning at extent index idx. If the extents are being removed - * from the end of the list (ie. truncate) then we just need to re- - * allocate the list to remove the extra space. Otherwise, if the - * extents are being removed from the middle of the existing extent - * entries, then we first need to move the extent records beginning - * at idx + ext_diff up in the list to overwrite the records being - * removed, then remove the extra space via kmem_realloc. - */ -void -xfs_iext_remove_direct( - xfs_ifork_t *ifp, /* inode fork pointer */ - xfs_extnum_t idx, /* index to begin removing exts */ - int ext_diff) /* number of extents to remove */ -{ - xfs_extnum_t nextents; /* number of extents in file */ - int new_size; /* size of extents after removal */ - - ASSERT(!(ifp->if_flags & XFS_IFEXTIREC)); - new_size = ifp->if_bytes - - (ext_diff * sizeof(xfs_bmbt_rec_t)); - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - - if (new_size == 0) { - xfs_iext_destroy(ifp); - return; - } - /* Move extents up in the list (if needed) */ - if (idx + ext_diff < nextents) { - memmove(&ifp->if_u1.if_extents[idx], - &ifp->if_u1.if_extents[idx + ext_diff], - (nextents - (idx + ext_diff)) * - sizeof(xfs_bmbt_rec_t)); - } - memset(&ifp->if_u1.if_extents[nextents - ext_diff], - 0, ext_diff * sizeof(xfs_bmbt_rec_t)); - /* - * Reallocate the direct extent list. If the extents - * will fit inside the inode then xfs_iext_realloc_direct - * will switch from direct to inline extent allocation - * mode for us. - */ - xfs_iext_realloc_direct(ifp, new_size); - ifp->if_bytes = new_size; -} - -/* - * This is called when incore extents are being removed from the - * indirection array and the extents being removed span multiple extent - * buffers. The idx parameter contains the file extent index where we - * want to begin removing extents, and the count parameter contains - * how many extents need to be removed. - * - * |-------| |-------| - * | nex1 | | | nex1 - number of extents before idx - * |-------| | count | - * | | | | count - number of extents being removed at idx - * | count | |-------| - * | | | nex2 | nex2 - number of extents after idx + count - * |-------| |-------| - */ -void -xfs_iext_remove_indirect( - xfs_ifork_t *ifp, /* inode fork pointer */ - xfs_extnum_t idx, /* index to begin removing extents */ - int count) /* number of extents to remove */ -{ - xfs_ext_irec_t *erp; /* indirection array pointer */ - int erp_idx = 0; /* indirection array index */ - xfs_extnum_t ext_cnt; /* extents left to remove */ - xfs_extnum_t ext_diff; /* extents to remove in current list */ - xfs_extnum_t nex1; /* number of extents before idx */ - xfs_extnum_t nex2; /* extents after idx + count */ - int page_idx = idx; /* index in target extent list */ - - ASSERT(ifp->if_flags & XFS_IFEXTIREC); - erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0); - ASSERT(erp != NULL); - nex1 = page_idx; - ext_cnt = count; - while (ext_cnt) { - nex2 = MAX((erp->er_extcount - (nex1 + ext_cnt)), 0); - ext_diff = MIN(ext_cnt, (erp->er_extcount - nex1)); - /* - * Check for deletion of entire list; - * xfs_iext_irec_remove() updates extent offsets. - */ - if (ext_diff == erp->er_extcount) { - xfs_iext_irec_remove(ifp, erp_idx); - ext_cnt -= ext_diff; - nex1 = 0; - if (ext_cnt) { - ASSERT(erp_idx < ifp->if_real_bytes / - XFS_IEXT_BUFSZ); - erp = &ifp->if_u1.if_ext_irec[erp_idx]; - nex1 = 0; - continue; - } else { - break; - } - } - /* Move extents up (if needed) */ - if (nex2) { - memmove(&erp->er_extbuf[nex1], - &erp->er_extbuf[nex1 + ext_diff], - nex2 * sizeof(xfs_bmbt_rec_t)); - } - /* Zero out rest of page */ - memset(&erp->er_extbuf[nex1 + nex2], 0, (XFS_IEXT_BUFSZ - - ((nex1 + nex2) * sizeof(xfs_bmbt_rec_t)))); - /* Update remaining counters */ - erp->er_extcount -= ext_diff; - xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -ext_diff); - ext_cnt -= ext_diff; - nex1 = 0; - erp_idx++; - erp++; - } - ifp->if_bytes -= count * sizeof(xfs_bmbt_rec_t); - xfs_iext_irec_compact(ifp); -} - -/* - * Create, destroy, or resize a linear (direct) block of extents. - */ -void -xfs_iext_realloc_direct( - xfs_ifork_t *ifp, /* inode fork pointer */ - int new_size) /* new size of extents */ -{ - int rnew_size; /* real new size of extents */ - - rnew_size = new_size; - - ASSERT(!(ifp->if_flags & XFS_IFEXTIREC) || - ((new_size >= 0) && (new_size <= XFS_IEXT_BUFSZ) && - (new_size != ifp->if_real_bytes))); - - /* Free extent records */ - if (new_size == 0) { - xfs_iext_destroy(ifp); - } - /* Resize direct extent list and zero any new bytes */ - else if (ifp->if_real_bytes) { - /* Check if extents will fit inside the inode */ - if (new_size <= XFS_INLINE_EXTS * sizeof(xfs_bmbt_rec_t)) { - xfs_iext_direct_to_inline(ifp, new_size / - (uint)sizeof(xfs_bmbt_rec_t)); - ifp->if_bytes = new_size; - return; - } - if (!is_power_of_2(new_size)){ - rnew_size = roundup_pow_of_two(new_size); - } - if (rnew_size != ifp->if_real_bytes) { - ifp->if_u1.if_extents = - kmem_realloc(ifp->if_u1.if_extents, - rnew_size, - ifp->if_real_bytes, KM_NOFS); - } - if (rnew_size > ifp->if_real_bytes) { - memset(&ifp->if_u1.if_extents[ifp->if_bytes / - (uint)sizeof(xfs_bmbt_rec_t)], 0, - rnew_size - ifp->if_real_bytes); - } - } - /* - * Switch from the inline extent buffer to a direct - * extent list. Be sure to include the inline extent - * bytes in new_size. - */ - else { - new_size += ifp->if_bytes; - if (!is_power_of_2(new_size)) { - rnew_size = roundup_pow_of_two(new_size); - } - xfs_iext_inline_to_direct(ifp, rnew_size); - } - ifp->if_real_bytes = rnew_size; - ifp->if_bytes = new_size; -} - -/* - * Switch from linear (direct) extent records to inline buffer. - */ -void -xfs_iext_direct_to_inline( - xfs_ifork_t *ifp, /* inode fork pointer */ - xfs_extnum_t nextents) /* number of extents in file */ -{ - ASSERT(ifp->if_flags & XFS_IFEXTENTS); - ASSERT(nextents <= XFS_INLINE_EXTS); - /* - * The inline buffer was zeroed when we switched - * from inline to direct extent allocation mode, - * so we don't need to clear it here. - */ - memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents, - nextents * sizeof(xfs_bmbt_rec_t)); - kmem_free(ifp->if_u1.if_extents); - ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; - ifp->if_real_bytes = 0; -} - -/* - * Switch from inline buffer to linear (direct) extent records. - * new_size should already be rounded up to the next power of 2 - * by the caller (when appropriate), so use new_size as it is. - * However, since new_size may be rounded up, we can't update - * if_bytes here. It is the caller's responsibility to update - * if_bytes upon return. - */ -void -xfs_iext_inline_to_direct( - xfs_ifork_t *ifp, /* inode fork pointer */ - int new_size) /* number of extents in file */ -{ - ifp->if_u1.if_extents = kmem_alloc(new_size, KM_NOFS); - memset(ifp->if_u1.if_extents, 0, new_size); - if (ifp->if_bytes) { - memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext, - ifp->if_bytes); - memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS * - sizeof(xfs_bmbt_rec_t)); - } - ifp->if_real_bytes = new_size; -} - -/* - * Resize an extent indirection array to new_size bytes. - */ -STATIC void -xfs_iext_realloc_indirect( - xfs_ifork_t *ifp, /* inode fork pointer */ - int new_size) /* new indirection array size */ -{ - int nlists; /* number of irec's (ex lists) */ - int size; /* current indirection array size */ - - ASSERT(ifp->if_flags & XFS_IFEXTIREC); - nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; - size = nlists * sizeof(xfs_ext_irec_t); - ASSERT(ifp->if_real_bytes); - ASSERT((new_size >= 0) && (new_size != size)); - if (new_size == 0) { - xfs_iext_destroy(ifp); - } else { - ifp->if_u1.if_ext_irec = (xfs_ext_irec_t *) - kmem_realloc(ifp->if_u1.if_ext_irec, - new_size, size, KM_NOFS); - } -} - -/* - * Switch from indirection array to linear (direct) extent allocations. - */ -STATIC void -xfs_iext_indirect_to_direct( - xfs_ifork_t *ifp) /* inode fork pointer */ -{ - xfs_bmbt_rec_host_t *ep; /* extent record pointer */ - xfs_extnum_t nextents; /* number of extents in file */ - int size; /* size of file extents */ - - ASSERT(ifp->if_flags & XFS_IFEXTIREC); - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - ASSERT(nextents <= XFS_LINEAR_EXTS); - size = nextents * sizeof(xfs_bmbt_rec_t); - - xfs_iext_irec_compact_pages(ifp); - ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ); - - ep = ifp->if_u1.if_ext_irec->er_extbuf; - kmem_free(ifp->if_u1.if_ext_irec); - ifp->if_flags &= ~XFS_IFEXTIREC; - ifp->if_u1.if_extents = ep; - ifp->if_bytes = size; - if (nextents < XFS_LINEAR_EXTS) { - xfs_iext_realloc_direct(ifp, size); - } -} - -/* - * Free incore file extents. - */ -void -xfs_iext_destroy( - xfs_ifork_t *ifp) /* inode fork pointer */ -{ - if (ifp->if_flags & XFS_IFEXTIREC) { - int erp_idx; - int nlists; - - nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; - for (erp_idx = nlists - 1; erp_idx >= 0 ; erp_idx--) { - xfs_iext_irec_remove(ifp, erp_idx); - } - ifp->if_flags &= ~XFS_IFEXTIREC; - } else if (ifp->if_real_bytes) { - kmem_free(ifp->if_u1.if_extents); - } else if (ifp->if_bytes) { - memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS * - sizeof(xfs_bmbt_rec_t)); - } - ifp->if_u1.if_extents = NULL; - ifp->if_real_bytes = 0; - ifp->if_bytes = 0; -} - -/* - * Return a pointer to the extent record for file system block bno. - */ -xfs_bmbt_rec_host_t * /* pointer to found extent record */ -xfs_iext_bno_to_ext( - xfs_ifork_t *ifp, /* inode fork pointer */ - xfs_fileoff_t bno, /* block number to search for */ - xfs_extnum_t *idxp) /* index of target extent */ -{ - xfs_bmbt_rec_host_t *base; /* pointer to first extent */ - xfs_filblks_t blockcount = 0; /* number of blocks in extent */ - xfs_bmbt_rec_host_t *ep = NULL; /* pointer to target extent */ - xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ - int high; /* upper boundary in search */ - xfs_extnum_t idx = 0; /* index of target extent */ - int low; /* lower boundary in search */ - xfs_extnum_t nextents; /* number of file extents */ - xfs_fileoff_t startoff = 0; /* start offset of extent */ - - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - if (nextents == 0) { - *idxp = 0; - return NULL; - } - low = 0; - if (ifp->if_flags & XFS_IFEXTIREC) { - /* Find target extent list */ - int erp_idx = 0; - erp = xfs_iext_bno_to_irec(ifp, bno, &erp_idx); - base = erp->er_extbuf; - high = erp->er_extcount - 1; - } else { - base = ifp->if_u1.if_extents; - high = nextents - 1; - } - /* Binary search extent records */ - while (low <= high) { - idx = (low + high) >> 1; - ep = base + idx; - startoff = xfs_bmbt_get_startoff(ep); - blockcount = xfs_bmbt_get_blockcount(ep); - if (bno < startoff) { - high = idx - 1; - } else if (bno >= startoff + blockcount) { - low = idx + 1; - } else { - /* Convert back to file-based extent index */ - if (ifp->if_flags & XFS_IFEXTIREC) { - idx += erp->er_extoff; - } - *idxp = idx; - return ep; - } - } - /* Convert back to file-based extent index */ - if (ifp->if_flags & XFS_IFEXTIREC) { - idx += erp->er_extoff; - } - if (bno >= startoff + blockcount) { - if (++idx == nextents) { - ep = NULL; - } else { - ep = xfs_iext_get_ext(ifp, idx); - } - } - *idxp = idx; - return ep; -} - -/* - * Return a pointer to the indirection array entry containing the - * extent record for filesystem block bno. Store the index of the - * target irec in *erp_idxp. - */ -xfs_ext_irec_t * /* pointer to found extent record */ -xfs_iext_bno_to_irec( - xfs_ifork_t *ifp, /* inode fork pointer */ - xfs_fileoff_t bno, /* block number to search for */ - int *erp_idxp) /* irec index of target ext list */ -{ - xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ - xfs_ext_irec_t *erp_next; /* next indirection array entry */ - int erp_idx; /* indirection array index */ - int nlists; /* number of extent irec's (lists) */ - int high; /* binary search upper limit */ - int low; /* binary search lower limit */ - - ASSERT(ifp->if_flags & XFS_IFEXTIREC); - nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; - erp_idx = 0; - low = 0; - high = nlists - 1; - while (low <= high) { - erp_idx = (low + high) >> 1; - erp = &ifp->if_u1.if_ext_irec[erp_idx]; - erp_next = erp_idx < nlists - 1 ? erp + 1 : NULL; - if (bno < xfs_bmbt_get_startoff(erp->er_extbuf)) { - high = erp_idx - 1; - } else if (erp_next && bno >= - xfs_bmbt_get_startoff(erp_next->er_extbuf)) { - low = erp_idx + 1; - } else { - break; - } - } - *erp_idxp = erp_idx; - return erp; -} - -/* - * Return a pointer to the indirection array entry containing the - * extent record at file extent index *idxp. Store the index of the - * target irec in *erp_idxp and store the page index of the target - * extent record in *idxp. - */ -xfs_ext_irec_t * -xfs_iext_idx_to_irec( - xfs_ifork_t *ifp, /* inode fork pointer */ - xfs_extnum_t *idxp, /* extent index (file -> page) */ - int *erp_idxp, /* pointer to target irec */ - int realloc) /* new bytes were just added */ -{ - xfs_ext_irec_t *prev; /* pointer to previous irec */ - xfs_ext_irec_t *erp = NULL; /* pointer to current irec */ - int erp_idx; /* indirection array index */ - int nlists; /* number of irec's (ex lists) */ - int high; /* binary search upper limit */ - int low; /* binary search lower limit */ - xfs_extnum_t page_idx = *idxp; /* extent index in target list */ - - ASSERT(ifp->if_flags & XFS_IFEXTIREC); - ASSERT(page_idx >= 0 && page_idx <= - ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)); - nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; - erp_idx = 0; - low = 0; - high = nlists - 1; - - /* Binary search extent irec's */ - while (low <= high) { - erp_idx = (low + high) >> 1; - erp = &ifp->if_u1.if_ext_irec[erp_idx]; - prev = erp_idx > 0 ? erp - 1 : NULL; - if (page_idx < erp->er_extoff || (page_idx == erp->er_extoff && - realloc && prev && prev->er_extcount < XFS_LINEAR_EXTS)) { - high = erp_idx - 1; - } else if (page_idx > erp->er_extoff + erp->er_extcount || - (page_idx == erp->er_extoff + erp->er_extcount && - !realloc)) { - low = erp_idx + 1; - } else if (page_idx == erp->er_extoff + erp->er_extcount && - erp->er_extcount == XFS_LINEAR_EXTS) { - ASSERT(realloc); - page_idx = 0; - erp_idx++; - erp = erp_idx < nlists ? erp + 1 : NULL; - break; - } else { - page_idx -= erp->er_extoff; - break; - } - } - *idxp = page_idx; - *erp_idxp = erp_idx; - return(erp); -} - -/* - * Allocate and initialize an indirection array once the space needed - * for incore extents increases above XFS_IEXT_BUFSZ. - */ -void -xfs_iext_irec_init( - xfs_ifork_t *ifp) /* inode fork pointer */ -{ - xfs_ext_irec_t *erp; /* indirection array pointer */ - xfs_extnum_t nextents; /* number of extents in file */ - - ASSERT(!(ifp->if_flags & XFS_IFEXTIREC)); - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - ASSERT(nextents <= XFS_LINEAR_EXTS); - - erp = kmem_alloc(sizeof(xfs_ext_irec_t), KM_NOFS); - - if (nextents == 0) { - ifp->if_u1.if_extents = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS); - } else if (!ifp->if_real_bytes) { - xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ); - } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) { - xfs_iext_realloc_direct(ifp, XFS_IEXT_BUFSZ); - } - erp->er_extbuf = ifp->if_u1.if_extents; - erp->er_extcount = nextents; - erp->er_extoff = 0; - - ifp->if_flags |= XFS_IFEXTIREC; - ifp->if_real_bytes = XFS_IEXT_BUFSZ; - ifp->if_bytes = nextents * sizeof(xfs_bmbt_rec_t); - ifp->if_u1.if_ext_irec = erp; - - return; -} - -/* - * Allocate and initialize a new entry in the indirection array. - */ -xfs_ext_irec_t * -xfs_iext_irec_new( - xfs_ifork_t *ifp, /* inode fork pointer */ - int erp_idx) /* index for new irec */ -{ - xfs_ext_irec_t *erp; /* indirection array pointer */ - int i; /* loop counter */ - int nlists; /* number of irec's (ex lists) */ - - ASSERT(ifp->if_flags & XFS_IFEXTIREC); - nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; - - /* Resize indirection array */ - xfs_iext_realloc_indirect(ifp, ++nlists * - sizeof(xfs_ext_irec_t)); - /* - * Move records down in the array so the - * new page can use erp_idx. - */ - erp = ifp->if_u1.if_ext_irec; - for (i = nlists - 1; i > erp_idx; i--) { - memmove(&erp[i], &erp[i-1], sizeof(xfs_ext_irec_t)); - } - ASSERT(i == erp_idx); - - /* Initialize new extent record */ - erp = ifp->if_u1.if_ext_irec; - erp[erp_idx].er_extbuf = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS); - ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; - memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ); - erp[erp_idx].er_extcount = 0; - erp[erp_idx].er_extoff = erp_idx > 0 ? - erp[erp_idx-1].er_extoff + erp[erp_idx-1].er_extcount : 0; - return (&erp[erp_idx]); -} - -/* - * Remove a record from the indirection array. - */ -void -xfs_iext_irec_remove( - xfs_ifork_t *ifp, /* inode fork pointer */ - int erp_idx) /* irec index to remove */ -{ - xfs_ext_irec_t *erp; /* indirection array pointer */ - int i; /* loop counter */ - int nlists; /* number of irec's (ex lists) */ - - ASSERT(ifp->if_flags & XFS_IFEXTIREC); - nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; - erp = &ifp->if_u1.if_ext_irec[erp_idx]; - if (erp->er_extbuf) { - xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, - -erp->er_extcount); - kmem_free(erp->er_extbuf); - } - /* Compact extent records */ - erp = ifp->if_u1.if_ext_irec; - for (i = erp_idx; i < nlists - 1; i++) { - memmove(&erp[i], &erp[i+1], sizeof(xfs_ext_irec_t)); - } - /* - * Manually free the last extent record from the indirection - * array. A call to xfs_iext_realloc_indirect() with a size - * of zero would result in a call to xfs_iext_destroy() which - * would in turn call this function again, creating a nasty - * infinite loop. - */ - if (--nlists) { - xfs_iext_realloc_indirect(ifp, - nlists * sizeof(xfs_ext_irec_t)); - } else { - kmem_free(ifp->if_u1.if_ext_irec); - } - ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; -} - -/* - * This is called to clean up large amounts of unused memory allocated - * by the indirection array. Before compacting anything though, verify - * that the indirection array is still needed and switch back to the - * linear extent list (or even the inline buffer) if possible. The - * compaction policy is as follows: - * - * Full Compaction: Extents fit into a single page (or inline buffer) - * Partial Compaction: Extents occupy less than 50% of allocated space - * No Compaction: Extents occupy at least 50% of allocated space - */ -void -xfs_iext_irec_compact( - xfs_ifork_t *ifp) /* inode fork pointer */ -{ - xfs_extnum_t nextents; /* number of extents in file */ - int nlists; /* number of irec's (ex lists) */ - - ASSERT(ifp->if_flags & XFS_IFEXTIREC); - nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - - if (nextents == 0) { - xfs_iext_destroy(ifp); - } else if (nextents <= XFS_INLINE_EXTS) { - xfs_iext_indirect_to_direct(ifp); - xfs_iext_direct_to_inline(ifp, nextents); - } else if (nextents <= XFS_LINEAR_EXTS) { - xfs_iext_indirect_to_direct(ifp); - } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 1) { - xfs_iext_irec_compact_pages(ifp); - } -} - -/* - * Combine extents from neighboring extent pages. - */ -void -xfs_iext_irec_compact_pages( - xfs_ifork_t *ifp) /* inode fork pointer */ -{ - xfs_ext_irec_t *erp, *erp_next;/* pointers to irec entries */ - int erp_idx = 0; /* indirection array index */ - int nlists; /* number of irec's (ex lists) */ - - ASSERT(ifp->if_flags & XFS_IFEXTIREC); - nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; - while (erp_idx < nlists - 1) { - erp = &ifp->if_u1.if_ext_irec[erp_idx]; - erp_next = erp + 1; - if (erp_next->er_extcount <= - (XFS_LINEAR_EXTS - erp->er_extcount)) { - memcpy(&erp->er_extbuf[erp->er_extcount], - erp_next->er_extbuf, erp_next->er_extcount * - sizeof(xfs_bmbt_rec_t)); - erp->er_extcount += erp_next->er_extcount; - /* - * Free page before removing extent record - * so er_extoffs don't get modified in - * xfs_iext_irec_remove. - */ - kmem_free(erp_next->er_extbuf); - erp_next->er_extbuf = NULL; - xfs_iext_irec_remove(ifp, erp_idx + 1); - nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; - } else { - erp_idx++; - } - } -} - -/* - * This is called to update the er_extoff field in the indirection - * array when extents have been added or removed from one of the - * extent lists. erp_idx contains the irec index to begin updating - * at and ext_diff contains the number of extents that were added - * or removed. - */ -void -xfs_iext_irec_update_extoffs( - xfs_ifork_t *ifp, /* inode fork pointer */ - int erp_idx, /* irec index to update */ - int ext_diff) /* number of new extents */ -{ - int i; /* loop counter */ - int nlists; /* number of irec's (ex lists */ - - ASSERT(ifp->if_flags & XFS_IFEXTIREC); - nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; - for (i = erp_idx; i < nlists; i++) { - ifp->if_u1.if_ext_irec[i].er_extoff += ext_diff; - } -} diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_inode_fork.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_inode_fork.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_inode_fork.c 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_inode_fork.c 2014-05-02 00:09:16.000000000 +0000 @@ -0,0 +1,1886 @@ +/* + * Copyright (c) 2000-2006 Silicon Graphics, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include + +kmem_zone_t *xfs_ifork_zone; + +STATIC int xfs_iformat_local(xfs_inode_t *, xfs_dinode_t *, int, int); +STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int); +STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int); + +#ifdef DEBUG +/* + * Make sure that the extents in the given memory buffer + * are valid. + */ +void +xfs_validate_extents( + xfs_ifork_t *ifp, + int nrecs, + xfs_exntfmt_t fmt) +{ + xfs_bmbt_irec_t irec; + xfs_bmbt_rec_host_t rec; + int i; + + for (i = 0; i < nrecs; i++) { + xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); + rec.l0 = get_unaligned(&ep->l0); + rec.l1 = get_unaligned(&ep->l1); + xfs_bmbt_get_all(&rec, &irec); + if (fmt == XFS_EXTFMT_NOSTATE) + ASSERT(irec.br_state == XFS_EXT_NORM); + } +} +#else /* DEBUG */ +#define xfs_validate_extents(ifp, nrecs, fmt) +#endif /* DEBUG */ + + +/* + * Move inode type and inode format specific information from the + * on-disk inode to the in-core inode. For fifos, devs, and sockets + * this means set if_rdev to the proper value. For files, directories, + * and symlinks this means to bring in the in-line data or extent + * pointers. For a file in B-tree format, only the root is immediately + * brought in-core. The rest will be in-lined in if_extents when it + * is first referenced (see xfs_iread_extents()). + */ +int +xfs_iformat_fork( + xfs_inode_t *ip, + xfs_dinode_t *dip) +{ + xfs_attr_shortform_t *atp; + int size; + int error = 0; + xfs_fsize_t di_size; + + if (unlikely(be32_to_cpu(dip->di_nextents) + + be16_to_cpu(dip->di_anextents) > + be64_to_cpu(dip->di_nblocks))) { + xfs_warn(ip->i_mount, + "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.", + (unsigned long long)ip->i_ino, + (int)(be32_to_cpu(dip->di_nextents) + + be16_to_cpu(dip->di_anextents)), + (unsigned long long) + be64_to_cpu(dip->di_nblocks)); + XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW, + ip->i_mount, dip); + return XFS_ERROR(EFSCORRUPTED); + } + + if (unlikely(dip->di_forkoff > ip->i_mount->m_sb.sb_inodesize)) { + xfs_warn(ip->i_mount, "corrupt dinode %Lu, forkoff = 0x%x.", + (unsigned long long)ip->i_ino, + dip->di_forkoff); + XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW, + ip->i_mount, dip); + return XFS_ERROR(EFSCORRUPTED); + } + + if (unlikely((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) && + !ip->i_mount->m_rtdev_targp)) { + xfs_warn(ip->i_mount, + "corrupt dinode %Lu, has realtime flag set.", + ip->i_ino); + XFS_CORRUPTION_ERROR("xfs_iformat(realtime)", + XFS_ERRLEVEL_LOW, ip->i_mount, dip); + return XFS_ERROR(EFSCORRUPTED); + } + + switch (ip->i_d.di_mode & S_IFMT) { + case S_IFIFO: + case S_IFCHR: + case S_IFBLK: + case S_IFSOCK: + if (unlikely(dip->di_format != XFS_DINODE_FMT_DEV)) { + XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW, + ip->i_mount, dip); + return XFS_ERROR(EFSCORRUPTED); + } + ip->i_d.di_size = 0; + ip->i_df.if_u2.if_rdev = xfs_dinode_get_rdev(dip); + break; + + case S_IFREG: + case S_IFLNK: + case S_IFDIR: + switch (dip->di_format) { + case XFS_DINODE_FMT_LOCAL: + /* + * no local regular files yet + */ + if (unlikely(S_ISREG(be16_to_cpu(dip->di_mode)))) { + xfs_warn(ip->i_mount, + "corrupt inode %Lu (local format for regular file).", + (unsigned long long) ip->i_ino); + XFS_CORRUPTION_ERROR("xfs_iformat(4)", + XFS_ERRLEVEL_LOW, + ip->i_mount, dip); + return XFS_ERROR(EFSCORRUPTED); + } + + di_size = be64_to_cpu(dip->di_size); + if (unlikely(di_size < 0 || + di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) { + xfs_warn(ip->i_mount, + "corrupt inode %Lu (bad size %Ld for local inode).", + (unsigned long long) ip->i_ino, + (long long) di_size); + XFS_CORRUPTION_ERROR("xfs_iformat(5)", + XFS_ERRLEVEL_LOW, + ip->i_mount, dip); + return XFS_ERROR(EFSCORRUPTED); + } + + size = (int)di_size; + error = xfs_iformat_local(ip, dip, XFS_DATA_FORK, size); + break; + case XFS_DINODE_FMT_EXTENTS: + error = xfs_iformat_extents(ip, dip, XFS_DATA_FORK); + break; + case XFS_DINODE_FMT_BTREE: + error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK); + break; + default: + XFS_ERROR_REPORT("xfs_iformat(6)", XFS_ERRLEVEL_LOW, + ip->i_mount); + return XFS_ERROR(EFSCORRUPTED); + } + break; + + default: + XFS_ERROR_REPORT("xfs_iformat(7)", XFS_ERRLEVEL_LOW, ip->i_mount); + return XFS_ERROR(EFSCORRUPTED); + } + if (error) { + return error; + } + if (!XFS_DFORK_Q(dip)) + return 0; + + ASSERT(ip->i_afp == NULL); + ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP | KM_NOFS); + + switch (dip->di_aformat) { + case XFS_DINODE_FMT_LOCAL: + atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); + size = be16_to_cpu(atp->hdr.totsize); + + if (unlikely(size < sizeof(struct xfs_attr_sf_hdr))) { + xfs_warn(ip->i_mount, + "corrupt inode %Lu (bad attr fork size %Ld).", + (unsigned long long) ip->i_ino, + (long long) size); + XFS_CORRUPTION_ERROR("xfs_iformat(8)", + XFS_ERRLEVEL_LOW, + ip->i_mount, dip); + return XFS_ERROR(EFSCORRUPTED); + } + + error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, size); + break; + case XFS_DINODE_FMT_EXTENTS: + error = xfs_iformat_extents(ip, dip, XFS_ATTR_FORK); + break; + case XFS_DINODE_FMT_BTREE: + error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK); + break; + default: + error = XFS_ERROR(EFSCORRUPTED); + break; + } + if (error) { + kmem_zone_free(xfs_ifork_zone, ip->i_afp); + ip->i_afp = NULL; + xfs_idestroy_fork(ip, XFS_DATA_FORK); + } + return error; +} + +/* + * The file is in-lined in the on-disk inode. + * If it fits into if_inline_data, then copy + * it there, otherwise allocate a buffer for it + * and copy the data there. Either way, set + * if_data to point at the data. + * If we allocate a buffer for the data, make + * sure that its size is a multiple of 4 and + * record the real size in i_real_bytes. + */ +STATIC int +xfs_iformat_local( + xfs_inode_t *ip, + xfs_dinode_t *dip, + int whichfork, + int size) +{ + xfs_ifork_t *ifp; + int real_size; + + /* + * If the size is unreasonable, then something + * is wrong and we just bail out rather than crash in + * kmem_alloc() or memcpy() below. + */ + if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) { + xfs_warn(ip->i_mount, + "corrupt inode %Lu (bad size %d for local fork, size = %d).", + (unsigned long long) ip->i_ino, size, + XFS_DFORK_SIZE(dip, ip->i_mount, whichfork)); + XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW, + ip->i_mount, dip); + return XFS_ERROR(EFSCORRUPTED); + } + ifp = XFS_IFORK_PTR(ip, whichfork); + real_size = 0; + if (size == 0) + ifp->if_u1.if_data = NULL; + else if (size <= sizeof(ifp->if_u2.if_inline_data)) + ifp->if_u1.if_data = ifp->if_u2.if_inline_data; + else { + real_size = roundup(size, 4); + ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP | KM_NOFS); + } + ifp->if_bytes = size; + ifp->if_real_bytes = real_size; + if (size) + memcpy(ifp->if_u1.if_data, XFS_DFORK_PTR(dip, whichfork), size); + ifp->if_flags &= ~XFS_IFEXTENTS; + ifp->if_flags |= XFS_IFINLINE; + return 0; +} + +/* + * The file consists of a set of extents all + * of which fit into the on-disk inode. + * If there are few enough extents to fit into + * the if_inline_ext, then copy them there. + * Otherwise allocate a buffer for them and copy + * them into it. Either way, set if_extents + * to point at the extents. + */ +STATIC int +xfs_iformat_extents( + xfs_inode_t *ip, + xfs_dinode_t *dip, + int whichfork) +{ + xfs_bmbt_rec_t *dp; + xfs_ifork_t *ifp; + int nex; + int size; + int i; + + ifp = XFS_IFORK_PTR(ip, whichfork); + nex = XFS_DFORK_NEXTENTS(dip, whichfork); + size = nex * (uint)sizeof(xfs_bmbt_rec_t); + + /* + * If the number of extents is unreasonable, then something + * is wrong and we just bail out rather than crash in + * kmem_alloc() or memcpy() below. + */ + if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) { + xfs_warn(ip->i_mount, "corrupt inode %Lu ((a)extents = %d).", + (unsigned long long) ip->i_ino, nex); + XFS_CORRUPTION_ERROR("xfs_iformat_extents(1)", XFS_ERRLEVEL_LOW, + ip->i_mount, dip); + return XFS_ERROR(EFSCORRUPTED); + } + + ifp->if_real_bytes = 0; + if (nex == 0) + ifp->if_u1.if_extents = NULL; + else if (nex <= XFS_INLINE_EXTS) + ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; + else + xfs_iext_add(ifp, 0, nex); + + ifp->if_bytes = size; + if (size) { + dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork); + xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip)); + for (i = 0; i < nex; i++, dp++) { + xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); + ep->l0 = get_unaligned_be64(&dp->l0); + ep->l1 = get_unaligned_be64(&dp->l1); + } + XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork); + if (whichfork != XFS_DATA_FORK || + XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE) + if (unlikely(xfs_check_nostate_extents( + ifp, 0, nex))) { + XFS_ERROR_REPORT("xfs_iformat_extents(2)", + XFS_ERRLEVEL_LOW, + ip->i_mount); + return XFS_ERROR(EFSCORRUPTED); + } + } + ifp->if_flags |= XFS_IFEXTENTS; + return 0; +} + +/* + * The file has too many extents to fit into + * the inode, so they are in B-tree format. + * Allocate a buffer for the root of the B-tree + * and copy the root into it. The i_extents + * field will remain NULL until all of the + * extents are read in (when they are needed). + */ +STATIC int +xfs_iformat_btree( + xfs_inode_t *ip, + xfs_dinode_t *dip, + int whichfork) +{ + struct xfs_mount *mp = ip->i_mount; + xfs_bmdr_block_t *dfp; + xfs_ifork_t *ifp; + /* REFERENCED */ + int nrecs; + int size; + + ifp = XFS_IFORK_PTR(ip, whichfork); + dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); + size = XFS_BMAP_BROOT_SPACE(mp, dfp); + nrecs = be16_to_cpu(dfp->bb_numrecs); + + /* + * blow out if -- fork has less extents than can fit in + * fork (fork shouldn't be a btree format), root btree + * block has more records than can fit into the fork, + * or the number of extents is greater than the number of + * blocks. + */ + if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <= + XFS_IFORK_MAXEXT(ip, whichfork) || + XFS_BMDR_SPACE_CALC(nrecs) > + XFS_DFORK_SIZE(dip, mp, whichfork) || + XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) { + xfs_warn(mp, "corrupt inode %Lu (btree).", + (unsigned long long) ip->i_ino); + XFS_CORRUPTION_ERROR("xfs_iformat_btree", XFS_ERRLEVEL_LOW, + mp, dip); + return XFS_ERROR(EFSCORRUPTED); + } + + ifp->if_broot_bytes = size; + ifp->if_broot = kmem_alloc(size, KM_SLEEP | KM_NOFS); + ASSERT(ifp->if_broot != NULL); + /* + * Copy and convert from the on-disk structure + * to the in-memory structure. + */ + xfs_bmdr_to_bmbt(ip, dfp, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork), + ifp->if_broot, size); + ifp->if_flags &= ~XFS_IFEXTENTS; + ifp->if_flags |= XFS_IFBROOT; + + return 0; +} + +/* + * Read in extents from a btree-format inode. + * Allocate and fill in if_extents. Real work is done in xfs_bmap.c. + */ +int +xfs_iread_extents( + xfs_trans_t *tp, + xfs_inode_t *ip, + int whichfork) +{ + int error; + xfs_ifork_t *ifp; + xfs_extnum_t nextents; + + if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) { + XFS_ERROR_REPORT("xfs_iread_extents", XFS_ERRLEVEL_LOW, + ip->i_mount); + return XFS_ERROR(EFSCORRUPTED); + } + nextents = XFS_IFORK_NEXTENTS(ip, whichfork); + ifp = XFS_IFORK_PTR(ip, whichfork); + + /* + * We know that the size is valid (it's checked in iformat_btree) + */ + ifp->if_bytes = ifp->if_real_bytes = 0; + ifp->if_flags |= XFS_IFEXTENTS; + xfs_iext_add(ifp, 0, nextents); + error = xfs_bmap_read_extents(tp, ip, whichfork); + if (error) { + xfs_iext_destroy(ifp); + ifp->if_flags &= ~XFS_IFEXTENTS; + return error; + } + xfs_validate_extents(ifp, nextents, XFS_EXTFMT_INODE(ip)); + return 0; +} +/* + * Reallocate the space for if_broot based on the number of records + * being added or deleted as indicated in rec_diff. Move the records + * and pointers in if_broot to fit the new size. When shrinking this + * will eliminate holes between the records and pointers created by + * the caller. When growing this will create holes to be filled in + * by the caller. + * + * The caller must not request to add more records than would fit in + * the on-disk inode root. If the if_broot is currently NULL, then + * if we are adding records, one will be allocated. The caller must also + * not request that the number of records go below zero, although + * it can go to zero. + * + * ip -- the inode whose if_broot area is changing + * ext_diff -- the change in the number of records, positive or negative, + * requested for the if_broot array. + */ +void +xfs_iroot_realloc( + xfs_inode_t *ip, + int rec_diff, + int whichfork) +{ + struct xfs_mount *mp = ip->i_mount; + int cur_max; + xfs_ifork_t *ifp; + struct xfs_btree_block *new_broot; + int new_max; + size_t new_size; + char *np; + char *op; + + /* + * Handle the degenerate case quietly. + */ + if (rec_diff == 0) { + return; + } + + ifp = XFS_IFORK_PTR(ip, whichfork); + if (rec_diff > 0) { + /* + * If there wasn't any memory allocated before, just + * allocate it now and get out. + */ + if (ifp->if_broot_bytes == 0) { + new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, rec_diff); + ifp->if_broot = kmem_alloc(new_size, KM_SLEEP | KM_NOFS); + ifp->if_broot_bytes = (int)new_size; + return; + } + + /* + * If there is already an existing if_broot, then we need + * to realloc() it and shift the pointers to their new + * location. The records don't change location because + * they are kept butted up against the btree block header. + */ + cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0); + new_max = cur_max + rec_diff; + new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max); + ifp->if_broot = kmem_realloc(ifp->if_broot, new_size, + XFS_BMAP_BROOT_SPACE_CALC(mp, cur_max), + KM_SLEEP | KM_NOFS); + op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, + ifp->if_broot_bytes); + np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, + (int)new_size); + ifp->if_broot_bytes = (int)new_size; + ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <= + XFS_IFORK_SIZE(ip, whichfork)); + memmove(np, op, cur_max * (uint)sizeof(xfs_dfsbno_t)); + return; + } + + /* + * rec_diff is less than 0. In this case, we are shrinking the + * if_broot buffer. It must already exist. If we go to zero + * records, just get rid of the root and clear the status bit. + */ + ASSERT((ifp->if_broot != NULL) && (ifp->if_broot_bytes > 0)); + cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0); + new_max = cur_max + rec_diff; + ASSERT(new_max >= 0); + if (new_max > 0) + new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max); + else + new_size = 0; + if (new_size > 0) { + new_broot = kmem_alloc(new_size, KM_SLEEP | KM_NOFS); + /* + * First copy over the btree block header. + */ + memcpy(new_broot, ifp->if_broot, + XFS_BMBT_BLOCK_LEN(ip->i_mount)); + } else { + new_broot = NULL; + ifp->if_flags &= ~XFS_IFBROOT; + } + + /* + * Only copy the records and pointers if there are any. + */ + if (new_max > 0) { + /* + * First copy the records. + */ + op = (char *)XFS_BMBT_REC_ADDR(mp, ifp->if_broot, 1); + np = (char *)XFS_BMBT_REC_ADDR(mp, new_broot, 1); + memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t)); + + /* + * Then copy the pointers. + */ + op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, + ifp->if_broot_bytes); + np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, new_broot, 1, + (int)new_size); + memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t)); + } + kmem_free(ifp->if_broot); + ifp->if_broot = new_broot; + ifp->if_broot_bytes = (int)new_size; + if (ifp->if_broot) + ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <= + XFS_IFORK_SIZE(ip, whichfork)); + return; +} + + +/* + * This is called when the amount of space needed for if_data + * is increased or decreased. The change in size is indicated by + * the number of bytes that need to be added or deleted in the + * byte_diff parameter. + * + * If the amount of space needed has decreased below the size of the + * inline buffer, then switch to using the inline buffer. Otherwise, + * use kmem_realloc() or kmem_alloc() to adjust the size of the buffer + * to what is needed. + * + * ip -- the inode whose if_data area is changing + * byte_diff -- the change in the number of bytes, positive or negative, + * requested for the if_data array. + */ +void +xfs_idata_realloc( + xfs_inode_t *ip, + int byte_diff, + int whichfork) +{ + xfs_ifork_t *ifp; + int new_size; + int real_size; + + if (byte_diff == 0) { + return; + } + + ifp = XFS_IFORK_PTR(ip, whichfork); + new_size = (int)ifp->if_bytes + byte_diff; + ASSERT(new_size >= 0); + + if (new_size == 0) { + if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) { + kmem_free(ifp->if_u1.if_data); + } + ifp->if_u1.if_data = NULL; + real_size = 0; + } else if (new_size <= sizeof(ifp->if_u2.if_inline_data)) { + /* + * If the valid extents/data can fit in if_inline_ext/data, + * copy them from the malloc'd vector and free it. + */ + if (ifp->if_u1.if_data == NULL) { + ifp->if_u1.if_data = ifp->if_u2.if_inline_data; + } else if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) { + ASSERT(ifp->if_real_bytes != 0); + memcpy(ifp->if_u2.if_inline_data, ifp->if_u1.if_data, + new_size); + kmem_free(ifp->if_u1.if_data); + ifp->if_u1.if_data = ifp->if_u2.if_inline_data; + } + real_size = 0; + } else { + /* + * Stuck with malloc/realloc. + * For inline data, the underlying buffer must be + * a multiple of 4 bytes in size so that it can be + * logged and stay on word boundaries. We enforce + * that here. + */ + real_size = roundup(new_size, 4); + if (ifp->if_u1.if_data == NULL) { + ASSERT(ifp->if_real_bytes == 0); + ifp->if_u1.if_data = kmem_alloc(real_size, + KM_SLEEP | KM_NOFS); + } else if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) { + /* + * Only do the realloc if the underlying size + * is really changing. + */ + if (ifp->if_real_bytes != real_size) { + ifp->if_u1.if_data = + kmem_realloc(ifp->if_u1.if_data, + real_size, + ifp->if_real_bytes, + KM_SLEEP | KM_NOFS); + } + } else { + ASSERT(ifp->if_real_bytes == 0); + ifp->if_u1.if_data = kmem_alloc(real_size, + KM_SLEEP | KM_NOFS); + memcpy(ifp->if_u1.if_data, ifp->if_u2.if_inline_data, + ifp->if_bytes); + } + } + ifp->if_real_bytes = real_size; + ifp->if_bytes = new_size; + ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); +} + +void +xfs_idestroy_fork( + xfs_inode_t *ip, + int whichfork) +{ + xfs_ifork_t *ifp; + + ifp = XFS_IFORK_PTR(ip, whichfork); + if (ifp->if_broot != NULL) { + kmem_free(ifp->if_broot); + ifp->if_broot = NULL; + } + + /* + * If the format is local, then we can't have an extents + * array so just look for an inline data array. If we're + * not local then we may or may not have an extents list, + * so check and free it up if we do. + */ + if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { + if ((ifp->if_u1.if_data != ifp->if_u2.if_inline_data) && + (ifp->if_u1.if_data != NULL)) { + ASSERT(ifp->if_real_bytes != 0); + kmem_free(ifp->if_u1.if_data); + ifp->if_u1.if_data = NULL; + ifp->if_real_bytes = 0; + } + } else if ((ifp->if_flags & XFS_IFEXTENTS) && + ((ifp->if_flags & XFS_IFEXTIREC) || + ((ifp->if_u1.if_extents != NULL) && + (ifp->if_u1.if_extents != ifp->if_u2.if_inline_ext)))) { + ASSERT(ifp->if_real_bytes != 0); + xfs_iext_destroy(ifp); + } + ASSERT(ifp->if_u1.if_extents == NULL || + ifp->if_u1.if_extents == ifp->if_u2.if_inline_ext); + ASSERT(ifp->if_real_bytes == 0); + if (whichfork == XFS_ATTR_FORK) { + kmem_zone_free(xfs_ifork_zone, ip->i_afp); + ip->i_afp = NULL; + } +} + +/* + * xfs_iextents_copy() + * + * This is called to copy the REAL extents (as opposed to the delayed + * allocation extents) from the inode into the given buffer. It + * returns the number of bytes copied into the buffer. + * + * If there are no delayed allocation extents, then we can just + * memcpy() the extents into the buffer. Otherwise, we need to + * examine each extent in turn and skip those which are delayed. + */ +int +xfs_iextents_copy( + xfs_inode_t *ip, + xfs_bmbt_rec_t *dp, + int whichfork) +{ + int copied; + int i; + xfs_ifork_t *ifp; + int nrecs; + xfs_fsblock_t start_block; + + ifp = XFS_IFORK_PTR(ip, whichfork); + ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); + ASSERT(ifp->if_bytes > 0); + + nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + XFS_BMAP_TRACE_EXLIST(ip, nrecs, whichfork); + ASSERT(nrecs > 0); + + /* + * There are some delayed allocation extents in the + * inode, so copy the extents one at a time and skip + * the delayed ones. There must be at least one + * non-delayed extent. + */ + copied = 0; + for (i = 0; i < nrecs; i++) { + xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); + start_block = xfs_bmbt_get_startblock(ep); + if (isnullstartblock(start_block)) { + /* + * It's a delayed allocation extent, so skip it. + */ + continue; + } + + /* Translate to on disk format */ + put_unaligned_be64(ep->l0, &dp->l0); + put_unaligned_be64(ep->l1, &dp->l1); + dp++; + copied++; + } + ASSERT(copied != 0); + xfs_validate_extents(ifp, copied, XFS_EXTFMT_INODE(ip)); + + return (copied * (uint)sizeof(xfs_bmbt_rec_t)); +} + +/* + * Each of the following cases stores data into the same region + * of the on-disk inode, so only one of them can be valid at + * any given time. While it is possible to have conflicting formats + * and log flags, e.g. having XFS_ILOG_?DATA set when the fork is + * in EXTENTS format, this can only happen when the fork has + * changed formats after being modified but before being flushed. + * In these cases, the format always takes precedence, because the + * format indicates the current state of the fork. + */ +void +xfs_iflush_fork( + xfs_inode_t *ip, + xfs_dinode_t *dip, + xfs_inode_log_item_t *iip, + int whichfork, + xfs_buf_t *bp) +{ + char *cp; + xfs_ifork_t *ifp; + xfs_mount_t *mp; + static const short brootflag[2] = + { XFS_ILOG_DBROOT, XFS_ILOG_ABROOT }; + static const short dataflag[2] = + { XFS_ILOG_DDATA, XFS_ILOG_ADATA }; + static const short extflag[2] = + { XFS_ILOG_DEXT, XFS_ILOG_AEXT }; + + if (!iip) + return; + ifp = XFS_IFORK_PTR(ip, whichfork); + /* + * This can happen if we gave up in iformat in an error path, + * for the attribute fork. + */ + if (!ifp) { + ASSERT(whichfork == XFS_ATTR_FORK); + return; + } + cp = XFS_DFORK_PTR(dip, whichfork); + mp = ip->i_mount; + switch (XFS_IFORK_FORMAT(ip, whichfork)) { + case XFS_DINODE_FMT_LOCAL: + if ((iip->ili_fields & dataflag[whichfork]) && + (ifp->if_bytes > 0)) { + ASSERT(ifp->if_u1.if_data != NULL); + ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); + memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes); + } + break; + + case XFS_DINODE_FMT_EXTENTS: + ASSERT((ifp->if_flags & XFS_IFEXTENTS) || + !(iip->ili_fields & extflag[whichfork])); + if ((iip->ili_fields & extflag[whichfork]) && + (ifp->if_bytes > 0)) { + ASSERT(xfs_iext_get_ext(ifp, 0)); + ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); + (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp, + whichfork); + } + break; + + case XFS_DINODE_FMT_BTREE: + if ((iip->ili_fields & brootflag[whichfork]) && + (ifp->if_broot_bytes > 0)) { + ASSERT(ifp->if_broot != NULL); + ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <= + XFS_IFORK_SIZE(ip, whichfork)); + xfs_bmbt_to_bmdr(mp, ifp->if_broot, ifp->if_broot_bytes, + (xfs_bmdr_block_t *)cp, + XFS_DFORK_SIZE(dip, mp, whichfork)); + } + break; + + case XFS_DINODE_FMT_DEV: + if (iip->ili_fields & XFS_ILOG_DEV) { + ASSERT(whichfork == XFS_DATA_FORK); + xfs_dinode_put_rdev(dip, ip->i_df.if_u2.if_rdev); + } + break; + + case XFS_DINODE_FMT_UUID: + if (iip->ili_fields & XFS_ILOG_UUID) { + ASSERT(whichfork == XFS_DATA_FORK); + memcpy(XFS_DFORK_DPTR(dip), + &ip->i_df.if_u2.if_uuid, + sizeof(uuid_t)); + } + break; + + default: + ASSERT(0); + break; + } +} + +/* + * Return a pointer to the extent record at file index idx. + */ +xfs_bmbt_rec_host_t * +xfs_iext_get_ext( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_extnum_t idx) /* index of target extent */ +{ + ASSERT(idx >= 0); + ASSERT(idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)); + + if ((ifp->if_flags & XFS_IFEXTIREC) && (idx == 0)) { + return ifp->if_u1.if_ext_irec->er_extbuf; + } else if (ifp->if_flags & XFS_IFEXTIREC) { + xfs_ext_irec_t *erp; /* irec pointer */ + int erp_idx = 0; /* irec index */ + xfs_extnum_t page_idx = idx; /* ext index in target list */ + + erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0); + return &erp->er_extbuf[page_idx]; + } else if (ifp->if_bytes) { + return &ifp->if_u1.if_extents[idx]; + } else { + return NULL; + } +} + +/* + * Insert new item(s) into the extent records for incore inode + * fork 'ifp'. 'count' new items are inserted at index 'idx'. + */ +void +xfs_iext_insert( + xfs_inode_t *ip, /* incore inode pointer */ + xfs_extnum_t idx, /* starting index of new items */ + xfs_extnum_t count, /* number of inserted items */ + xfs_bmbt_irec_t *new, /* items to insert */ + int state) /* type of extent conversion */ +{ + xfs_ifork_t *ifp = (state & BMAP_ATTRFORK) ? ip->i_afp : &ip->i_df; + xfs_extnum_t i; /* extent record index */ + + trace_xfs_iext_insert(ip, idx, new, state, _RET_IP_); + + ASSERT(ifp->if_flags & XFS_IFEXTENTS); + xfs_iext_add(ifp, idx, count); + for (i = idx; i < idx + count; i++, new++) + xfs_bmbt_set_all(xfs_iext_get_ext(ifp, i), new); +} + +/* + * This is called when the amount of space required for incore file + * extents needs to be increased. The ext_diff parameter stores the + * number of new extents being added and the idx parameter contains + * the extent index where the new extents will be added. If the new + * extents are being appended, then we just need to (re)allocate and + * initialize the space. Otherwise, if the new extents are being + * inserted into the middle of the existing entries, a bit more work + * is required to make room for the new extents to be inserted. The + * caller is responsible for filling in the new extent entries upon + * return. + */ +void +xfs_iext_add( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_extnum_t idx, /* index to begin adding exts */ + int ext_diff) /* number of extents to add */ +{ + int byte_diff; /* new bytes being added */ + int new_size; /* size of extents after adding */ + xfs_extnum_t nextents; /* number of extents in file */ + + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + ASSERT((idx >= 0) && (idx <= nextents)); + byte_diff = ext_diff * sizeof(xfs_bmbt_rec_t); + new_size = ifp->if_bytes + byte_diff; + /* + * If the new number of extents (nextents + ext_diff) + * fits inside the inode, then continue to use the inline + * extent buffer. + */ + if (nextents + ext_diff <= XFS_INLINE_EXTS) { + if (idx < nextents) { + memmove(&ifp->if_u2.if_inline_ext[idx + ext_diff], + &ifp->if_u2.if_inline_ext[idx], + (nextents - idx) * sizeof(xfs_bmbt_rec_t)); + memset(&ifp->if_u2.if_inline_ext[idx], 0, byte_diff); + } + ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; + ifp->if_real_bytes = 0; + } + /* + * Otherwise use a linear (direct) extent list. + * If the extents are currently inside the inode, + * xfs_iext_realloc_direct will switch us from + * inline to direct extent allocation mode. + */ + else if (nextents + ext_diff <= XFS_LINEAR_EXTS) { + xfs_iext_realloc_direct(ifp, new_size); + if (idx < nextents) { + memmove(&ifp->if_u1.if_extents[idx + ext_diff], + &ifp->if_u1.if_extents[idx], + (nextents - idx) * sizeof(xfs_bmbt_rec_t)); + memset(&ifp->if_u1.if_extents[idx], 0, byte_diff); + } + } + /* Indirection array */ + else { + xfs_ext_irec_t *erp; + int erp_idx = 0; + int page_idx = idx; + + ASSERT(nextents + ext_diff > XFS_LINEAR_EXTS); + if (ifp->if_flags & XFS_IFEXTIREC) { + erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 1); + } else { + xfs_iext_irec_init(ifp); + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + erp = ifp->if_u1.if_ext_irec; + } + /* Extents fit in target extent page */ + if (erp && erp->er_extcount + ext_diff <= XFS_LINEAR_EXTS) { + if (page_idx < erp->er_extcount) { + memmove(&erp->er_extbuf[page_idx + ext_diff], + &erp->er_extbuf[page_idx], + (erp->er_extcount - page_idx) * + sizeof(xfs_bmbt_rec_t)); + memset(&erp->er_extbuf[page_idx], 0, byte_diff); + } + erp->er_extcount += ext_diff; + xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff); + } + /* Insert a new extent page */ + else if (erp) { + xfs_iext_add_indirect_multi(ifp, + erp_idx, page_idx, ext_diff); + } + /* + * If extent(s) are being appended to the last page in + * the indirection array and the new extent(s) don't fit + * in the page, then erp is NULL and erp_idx is set to + * the next index needed in the indirection array. + */ + else { + int count = ext_diff; + + while (count) { + erp = xfs_iext_irec_new(ifp, erp_idx); + erp->er_extcount = count; + count -= MIN(count, (int)XFS_LINEAR_EXTS); + if (count) { + erp_idx++; + } + } + } + } + ifp->if_bytes = new_size; +} + +/* + * This is called when incore extents are being added to the indirection + * array and the new extents do not fit in the target extent list. The + * erp_idx parameter contains the irec index for the target extent list + * in the indirection array, and the idx parameter contains the extent + * index within the list. The number of extents being added is stored + * in the count parameter. + * + * |-------| |-------| + * | | | | idx - number of extents before idx + * | idx | | count | + * | | | | count - number of extents being inserted at idx + * |-------| |-------| + * | count | | nex2 | nex2 - number of extents after idx + count + * |-------| |-------| + */ +void +xfs_iext_add_indirect_multi( + xfs_ifork_t *ifp, /* inode fork pointer */ + int erp_idx, /* target extent irec index */ + xfs_extnum_t idx, /* index within target list */ + int count) /* new extents being added */ +{ + int byte_diff; /* new bytes being added */ + xfs_ext_irec_t *erp; /* pointer to irec entry */ + xfs_extnum_t ext_diff; /* number of extents to add */ + xfs_extnum_t ext_cnt; /* new extents still needed */ + xfs_extnum_t nex2; /* extents after idx + count */ + xfs_bmbt_rec_t *nex2_ep = NULL; /* temp list for nex2 extents */ + int nlists; /* number of irec's (lists) */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + erp = &ifp->if_u1.if_ext_irec[erp_idx]; + nex2 = erp->er_extcount - idx; + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + + /* + * Save second part of target extent list + * (all extents past */ + if (nex2) { + byte_diff = nex2 * sizeof(xfs_bmbt_rec_t); + nex2_ep = (xfs_bmbt_rec_t *) kmem_alloc(byte_diff, KM_NOFS); + memmove(nex2_ep, &erp->er_extbuf[idx], byte_diff); + erp->er_extcount -= nex2; + xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -nex2); + memset(&erp->er_extbuf[idx], 0, byte_diff); + } + + /* + * Add the new extents to the end of the target + * list, then allocate new irec record(s) and + * extent buffer(s) as needed to store the rest + * of the new extents. + */ + ext_cnt = count; + ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS - erp->er_extcount); + if (ext_diff) { + erp->er_extcount += ext_diff; + xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff); + ext_cnt -= ext_diff; + } + while (ext_cnt) { + erp_idx++; + erp = xfs_iext_irec_new(ifp, erp_idx); + ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS); + erp->er_extcount = ext_diff; + xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff); + ext_cnt -= ext_diff; + } + + /* Add nex2 extents back to indirection array */ + if (nex2) { + xfs_extnum_t ext_avail; + int i; + + byte_diff = nex2 * sizeof(xfs_bmbt_rec_t); + ext_avail = XFS_LINEAR_EXTS - erp->er_extcount; + i = 0; + /* + * If nex2 extents fit in the current page, append + * nex2_ep after the new extents. + */ + if (nex2 <= ext_avail) { + i = erp->er_extcount; + } + /* + * Otherwise, check if space is available in the + * next page. + */ + else if ((erp_idx < nlists - 1) && + (nex2 <= (ext_avail = XFS_LINEAR_EXTS - + ifp->if_u1.if_ext_irec[erp_idx+1].er_extcount))) { + erp_idx++; + erp++; + /* Create a hole for nex2 extents */ + memmove(&erp->er_extbuf[nex2], erp->er_extbuf, + erp->er_extcount * sizeof(xfs_bmbt_rec_t)); + } + /* + * Final choice, create a new extent page for + * nex2 extents. + */ + else { + erp_idx++; + erp = xfs_iext_irec_new(ifp, erp_idx); + } + memmove(&erp->er_extbuf[i], nex2_ep, byte_diff); + kmem_free(nex2_ep); + erp->er_extcount += nex2; + xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, nex2); + } +} + +/* + * This is called when the amount of space required for incore file + * extents needs to be decreased. The ext_diff parameter stores the + * number of extents to be removed and the idx parameter contains + * the extent index where the extents will be removed from. + * + * If the amount of space needed has decreased below the linear + * limit, XFS_IEXT_BUFSZ, then switch to using the contiguous + * extent array. Otherwise, use kmem_realloc() to adjust the + * size to what is needed. + */ +void +xfs_iext_remove( + xfs_inode_t *ip, /* incore inode pointer */ + xfs_extnum_t idx, /* index to begin removing exts */ + int ext_diff, /* number of extents to remove */ + int state) /* type of extent conversion */ +{ + xfs_ifork_t *ifp = (state & BMAP_ATTRFORK) ? ip->i_afp : &ip->i_df; + xfs_extnum_t nextents; /* number of extents in file */ + int new_size; /* size of extents after removal */ + + trace_xfs_iext_remove(ip, idx, state, _RET_IP_); + + ASSERT(ext_diff > 0); + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + new_size = (nextents - ext_diff) * sizeof(xfs_bmbt_rec_t); + + if (new_size == 0) { + xfs_iext_destroy(ifp); + } else if (ifp->if_flags & XFS_IFEXTIREC) { + xfs_iext_remove_indirect(ifp, idx, ext_diff); + } else if (ifp->if_real_bytes) { + xfs_iext_remove_direct(ifp, idx, ext_diff); + } else { + xfs_iext_remove_inline(ifp, idx, ext_diff); + } + ifp->if_bytes = new_size; +} + +/* + * This removes ext_diff extents from the inline buffer, beginning + * at extent index idx. + */ +void +xfs_iext_remove_inline( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_extnum_t idx, /* index to begin removing exts */ + int ext_diff) /* number of extents to remove */ +{ + int nextents; /* number of extents in file */ + + ASSERT(!(ifp->if_flags & XFS_IFEXTIREC)); + ASSERT(idx < XFS_INLINE_EXTS); + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + ASSERT(((nextents - ext_diff) > 0) && + (nextents - ext_diff) < XFS_INLINE_EXTS); + + if (idx + ext_diff < nextents) { + memmove(&ifp->if_u2.if_inline_ext[idx], + &ifp->if_u2.if_inline_ext[idx + ext_diff], + (nextents - (idx + ext_diff)) * + sizeof(xfs_bmbt_rec_t)); + memset(&ifp->if_u2.if_inline_ext[nextents - ext_diff], + 0, ext_diff * sizeof(xfs_bmbt_rec_t)); + } else { + memset(&ifp->if_u2.if_inline_ext[idx], 0, + ext_diff * sizeof(xfs_bmbt_rec_t)); + } +} + +/* + * This removes ext_diff extents from a linear (direct) extent list, + * beginning at extent index idx. If the extents are being removed + * from the end of the list (ie. truncate) then we just need to re- + * allocate the list to remove the extra space. Otherwise, if the + * extents are being removed from the middle of the existing extent + * entries, then we first need to move the extent records beginning + * at idx + ext_diff up in the list to overwrite the records being + * removed, then remove the extra space via kmem_realloc. + */ +void +xfs_iext_remove_direct( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_extnum_t idx, /* index to begin removing exts */ + int ext_diff) /* number of extents to remove */ +{ + xfs_extnum_t nextents; /* number of extents in file */ + int new_size; /* size of extents after removal */ + + ASSERT(!(ifp->if_flags & XFS_IFEXTIREC)); + new_size = ifp->if_bytes - + (ext_diff * sizeof(xfs_bmbt_rec_t)); + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + + if (new_size == 0) { + xfs_iext_destroy(ifp); + return; + } + /* Move extents up in the list (if needed) */ + if (idx + ext_diff < nextents) { + memmove(&ifp->if_u1.if_extents[idx], + &ifp->if_u1.if_extents[idx + ext_diff], + (nextents - (idx + ext_diff)) * + sizeof(xfs_bmbt_rec_t)); + } + memset(&ifp->if_u1.if_extents[nextents - ext_diff], + 0, ext_diff * sizeof(xfs_bmbt_rec_t)); + /* + * Reallocate the direct extent list. If the extents + * will fit inside the inode then xfs_iext_realloc_direct + * will switch from direct to inline extent allocation + * mode for us. + */ + xfs_iext_realloc_direct(ifp, new_size); + ifp->if_bytes = new_size; +} + +/* + * This is called when incore extents are being removed from the + * indirection array and the extents being removed span multiple extent + * buffers. The idx parameter contains the file extent index where we + * want to begin removing extents, and the count parameter contains + * how many extents need to be removed. + * + * |-------| |-------| + * | nex1 | | | nex1 - number of extents before idx + * |-------| | count | + * | | | | count - number of extents being removed at idx + * | count | |-------| + * | | | nex2 | nex2 - number of extents after idx + count + * |-------| |-------| + */ +void +xfs_iext_remove_indirect( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_extnum_t idx, /* index to begin removing extents */ + int count) /* number of extents to remove */ +{ + xfs_ext_irec_t *erp; /* indirection array pointer */ + int erp_idx = 0; /* indirection array index */ + xfs_extnum_t ext_cnt; /* extents left to remove */ + xfs_extnum_t ext_diff; /* extents to remove in current list */ + xfs_extnum_t nex1; /* number of extents before idx */ + xfs_extnum_t nex2; /* extents after idx + count */ + int page_idx = idx; /* index in target extent list */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0); + ASSERT(erp != NULL); + nex1 = page_idx; + ext_cnt = count; + while (ext_cnt) { + nex2 = MAX((erp->er_extcount - (nex1 + ext_cnt)), 0); + ext_diff = MIN(ext_cnt, (erp->er_extcount - nex1)); + /* + * Check for deletion of entire list; + * xfs_iext_irec_remove() updates extent offsets. + */ + if (ext_diff == erp->er_extcount) { + xfs_iext_irec_remove(ifp, erp_idx); + ext_cnt -= ext_diff; + nex1 = 0; + if (ext_cnt) { + ASSERT(erp_idx < ifp->if_real_bytes / + XFS_IEXT_BUFSZ); + erp = &ifp->if_u1.if_ext_irec[erp_idx]; + nex1 = 0; + continue; + } else { + break; + } + } + /* Move extents up (if needed) */ + if (nex2) { + memmove(&erp->er_extbuf[nex1], + &erp->er_extbuf[nex1 + ext_diff], + nex2 * sizeof(xfs_bmbt_rec_t)); + } + /* Zero out rest of page */ + memset(&erp->er_extbuf[nex1 + nex2], 0, (XFS_IEXT_BUFSZ - + ((nex1 + nex2) * sizeof(xfs_bmbt_rec_t)))); + /* Update remaining counters */ + erp->er_extcount -= ext_diff; + xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -ext_diff); + ext_cnt -= ext_diff; + nex1 = 0; + erp_idx++; + erp++; + } + ifp->if_bytes -= count * sizeof(xfs_bmbt_rec_t); + xfs_iext_irec_compact(ifp); +} + +/* + * Create, destroy, or resize a linear (direct) block of extents. + */ +void +xfs_iext_realloc_direct( + xfs_ifork_t *ifp, /* inode fork pointer */ + int new_size) /* new size of extents after adding */ +{ + int rnew_size; /* real new size of extents */ + + rnew_size = new_size; + + ASSERT(!(ifp->if_flags & XFS_IFEXTIREC) || + ((new_size >= 0) && (new_size <= XFS_IEXT_BUFSZ) && + (new_size != ifp->if_real_bytes))); + + /* Free extent records */ + if (new_size == 0) { + xfs_iext_destroy(ifp); + } + /* Resize direct extent list and zero any new bytes */ + else if (ifp->if_real_bytes) { + /* Check if extents will fit inside the inode */ + if (new_size <= XFS_INLINE_EXTS * sizeof(xfs_bmbt_rec_t)) { + xfs_iext_direct_to_inline(ifp, new_size / + (uint)sizeof(xfs_bmbt_rec_t)); + ifp->if_bytes = new_size; + return; + } + if (!is_power_of_2(new_size)){ + rnew_size = roundup_pow_of_two(new_size); + } + if (rnew_size != ifp->if_real_bytes) { + ifp->if_u1.if_extents = + kmem_realloc(ifp->if_u1.if_extents, + rnew_size, + ifp->if_real_bytes, KM_NOFS); + } + if (rnew_size > ifp->if_real_bytes) { + memset(&ifp->if_u1.if_extents[ifp->if_bytes / + (uint)sizeof(xfs_bmbt_rec_t)], 0, + rnew_size - ifp->if_real_bytes); + } + } + /* Switch from the inline extent buffer to a direct extent list */ + else { + if (!is_power_of_2(new_size)) { + rnew_size = roundup_pow_of_two(new_size); + } + xfs_iext_inline_to_direct(ifp, rnew_size); + } + ifp->if_real_bytes = rnew_size; + ifp->if_bytes = new_size; +} + +/* + * Switch from linear (direct) extent records to inline buffer. + */ +void +xfs_iext_direct_to_inline( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_extnum_t nextents) /* number of extents in file */ +{ + ASSERT(ifp->if_flags & XFS_IFEXTENTS); + ASSERT(nextents <= XFS_INLINE_EXTS); + /* + * The inline buffer was zeroed when we switched + * from inline to direct extent allocation mode, + * so we don't need to clear it here. + */ + memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents, + nextents * sizeof(xfs_bmbt_rec_t)); + kmem_free(ifp->if_u1.if_extents); + ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; + ifp->if_real_bytes = 0; +} + +/* + * Switch from inline buffer to linear (direct) extent records. + * new_size should already be rounded up to the next power of 2 + * by the caller (when appropriate), so use new_size as it is. + * However, since new_size may be rounded up, we can't update + * if_bytes here. It is the caller's responsibility to update + * if_bytes upon return. + */ +void +xfs_iext_inline_to_direct( + xfs_ifork_t *ifp, /* inode fork pointer */ + int new_size) /* number of extents in file */ +{ + ifp->if_u1.if_extents = kmem_alloc(new_size, KM_NOFS); + memset(ifp->if_u1.if_extents, 0, new_size); + if (ifp->if_bytes) { + memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext, + ifp->if_bytes); + memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS * + sizeof(xfs_bmbt_rec_t)); + } + ifp->if_real_bytes = new_size; +} + +/* + * Resize an extent indirection array to new_size bytes. + */ +STATIC void +xfs_iext_realloc_indirect( + xfs_ifork_t *ifp, /* inode fork pointer */ + int new_size) /* new indirection array size */ +{ + int nlists; /* number of irec's (ex lists) */ + int size; /* current indirection array size */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + size = nlists * sizeof(xfs_ext_irec_t); + ASSERT(ifp->if_real_bytes); + ASSERT((new_size >= 0) && (new_size != size)); + if (new_size == 0) { + xfs_iext_destroy(ifp); + } else { + ifp->if_u1.if_ext_irec = (xfs_ext_irec_t *) + kmem_realloc(ifp->if_u1.if_ext_irec, + new_size, size, KM_NOFS); + } +} + +/* + * Switch from indirection array to linear (direct) extent allocations. + */ +STATIC void +xfs_iext_indirect_to_direct( + xfs_ifork_t *ifp) /* inode fork pointer */ +{ + xfs_bmbt_rec_host_t *ep; /* extent record pointer */ + xfs_extnum_t nextents; /* number of extents in file */ + int size; /* size of file extents */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + ASSERT(nextents <= XFS_LINEAR_EXTS); + size = nextents * sizeof(xfs_bmbt_rec_t); + + xfs_iext_irec_compact_pages(ifp); + ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ); + + ep = ifp->if_u1.if_ext_irec->er_extbuf; + kmem_free(ifp->if_u1.if_ext_irec); + ifp->if_flags &= ~XFS_IFEXTIREC; + ifp->if_u1.if_extents = ep; + ifp->if_bytes = size; + if (nextents < XFS_LINEAR_EXTS) { + xfs_iext_realloc_direct(ifp, size); + } +} + +/* + * Free incore file extents. + */ +void +xfs_iext_destroy( + xfs_ifork_t *ifp) /* inode fork pointer */ +{ + if (ifp->if_flags & XFS_IFEXTIREC) { + int erp_idx; + int nlists; + + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + for (erp_idx = nlists - 1; erp_idx >= 0 ; erp_idx--) { + xfs_iext_irec_remove(ifp, erp_idx); + } + ifp->if_flags &= ~XFS_IFEXTIREC; + } else if (ifp->if_real_bytes) { + kmem_free(ifp->if_u1.if_extents); + } else if (ifp->if_bytes) { + memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS * + sizeof(xfs_bmbt_rec_t)); + } + ifp->if_u1.if_extents = NULL; + ifp->if_real_bytes = 0; + ifp->if_bytes = 0; +} + +/* + * Return a pointer to the extent record for file system block bno. + */ +xfs_bmbt_rec_host_t * /* pointer to found extent record */ +xfs_iext_bno_to_ext( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_fileoff_t bno, /* block number to search for */ + xfs_extnum_t *idxp) /* index of target extent */ +{ + xfs_bmbt_rec_host_t *base; /* pointer to first extent */ + xfs_filblks_t blockcount = 0; /* number of blocks in extent */ + xfs_bmbt_rec_host_t *ep = NULL; /* pointer to target extent */ + xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ + int high; /* upper boundary in search */ + xfs_extnum_t idx = 0; /* index of target extent */ + int low; /* lower boundary in search */ + xfs_extnum_t nextents; /* number of file extents */ + xfs_fileoff_t startoff = 0; /* start offset of extent */ + + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + if (nextents == 0) { + *idxp = 0; + return NULL; + } + low = 0; + if (ifp->if_flags & XFS_IFEXTIREC) { + /* Find target extent list */ + int erp_idx = 0; + erp = xfs_iext_bno_to_irec(ifp, bno, &erp_idx); + base = erp->er_extbuf; + high = erp->er_extcount - 1; + } else { + base = ifp->if_u1.if_extents; + high = nextents - 1; + } + /* Binary search extent records */ + while (low <= high) { + idx = (low + high) >> 1; + ep = base + idx; + startoff = xfs_bmbt_get_startoff(ep); + blockcount = xfs_bmbt_get_blockcount(ep); + if (bno < startoff) { + high = idx - 1; + } else if (bno >= startoff + blockcount) { + low = idx + 1; + } else { + /* Convert back to file-based extent index */ + if (ifp->if_flags & XFS_IFEXTIREC) { + idx += erp->er_extoff; + } + *idxp = idx; + return ep; + } + } + /* Convert back to file-based extent index */ + if (ifp->if_flags & XFS_IFEXTIREC) { + idx += erp->er_extoff; + } + if (bno >= startoff + blockcount) { + if (++idx == nextents) { + ep = NULL; + } else { + ep = xfs_iext_get_ext(ifp, idx); + } + } + *idxp = idx; + return ep; +} + +/* + * Return a pointer to the indirection array entry containing the + * extent record for filesystem block bno. Store the index of the + * target irec in *erp_idxp. + */ +xfs_ext_irec_t * /* pointer to found extent record */ +xfs_iext_bno_to_irec( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_fileoff_t bno, /* block number to search for */ + int *erp_idxp) /* irec index of target ext list */ +{ + xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ + xfs_ext_irec_t *erp_next; /* next indirection array entry */ + int erp_idx; /* indirection array index */ + int nlists; /* number of extent irec's (lists) */ + int high; /* binary search upper limit */ + int low; /* binary search lower limit */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + erp_idx = 0; + low = 0; + high = nlists - 1; + while (low <= high) { + erp_idx = (low + high) >> 1; + erp = &ifp->if_u1.if_ext_irec[erp_idx]; + erp_next = erp_idx < nlists - 1 ? erp + 1 : NULL; + if (bno < xfs_bmbt_get_startoff(erp->er_extbuf)) { + high = erp_idx - 1; + } else if (erp_next && bno >= + xfs_bmbt_get_startoff(erp_next->er_extbuf)) { + low = erp_idx + 1; + } else { + break; + } + } + *erp_idxp = erp_idx; + return erp; +} + +/* + * Return a pointer to the indirection array entry containing the + * extent record at file extent index *idxp. Store the index of the + * target irec in *erp_idxp and store the page index of the target + * extent record in *idxp. + */ +xfs_ext_irec_t * +xfs_iext_idx_to_irec( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_extnum_t *idxp, /* extent index (file -> page) */ + int *erp_idxp, /* pointer to target irec */ + int realloc) /* new bytes were just added */ +{ + xfs_ext_irec_t *prev; /* pointer to previous irec */ + xfs_ext_irec_t *erp = NULL; /* pointer to current irec */ + int erp_idx; /* indirection array index */ + int nlists; /* number of irec's (ex lists) */ + int high; /* binary search upper limit */ + int low; /* binary search lower limit */ + xfs_extnum_t page_idx = *idxp; /* extent index in target list */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + ASSERT(page_idx >= 0); + ASSERT(page_idx <= ifp->if_bytes / sizeof(xfs_bmbt_rec_t)); + ASSERT(page_idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t) || realloc); + + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + erp_idx = 0; + low = 0; + high = nlists - 1; + + /* Binary search extent irec's */ + while (low <= high) { + erp_idx = (low + high) >> 1; + erp = &ifp->if_u1.if_ext_irec[erp_idx]; + prev = erp_idx > 0 ? erp - 1 : NULL; + if (page_idx < erp->er_extoff || (page_idx == erp->er_extoff && + realloc && prev && prev->er_extcount < XFS_LINEAR_EXTS)) { + high = erp_idx - 1; + } else if (page_idx > erp->er_extoff + erp->er_extcount || + (page_idx == erp->er_extoff + erp->er_extcount && + !realloc)) { + low = erp_idx + 1; + } else if (page_idx == erp->er_extoff + erp->er_extcount && + erp->er_extcount == XFS_LINEAR_EXTS) { + ASSERT(realloc); + page_idx = 0; + erp_idx++; + erp = erp_idx < nlists ? erp + 1 : NULL; + break; + } else { + page_idx -= erp->er_extoff; + break; + } + } + *idxp = page_idx; + *erp_idxp = erp_idx; + return(erp); +} + +/* + * Allocate and initialize an indirection array once the space needed + * for incore extents increases above XFS_IEXT_BUFSZ. + */ +void +xfs_iext_irec_init( + xfs_ifork_t *ifp) /* inode fork pointer */ +{ + xfs_ext_irec_t *erp; /* indirection array pointer */ + xfs_extnum_t nextents; /* number of extents in file */ + + ASSERT(!(ifp->if_flags & XFS_IFEXTIREC)); + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + ASSERT(nextents <= XFS_LINEAR_EXTS); + + erp = kmem_alloc(sizeof(xfs_ext_irec_t), KM_NOFS); + + if (nextents == 0) { + ifp->if_u1.if_extents = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS); + } else if (!ifp->if_real_bytes) { + xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ); + } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) { + xfs_iext_realloc_direct(ifp, XFS_IEXT_BUFSZ); + } + erp->er_extbuf = ifp->if_u1.if_extents; + erp->er_extcount = nextents; + erp->er_extoff = 0; + + ifp->if_flags |= XFS_IFEXTIREC; + ifp->if_real_bytes = XFS_IEXT_BUFSZ; + ifp->if_bytes = nextents * sizeof(xfs_bmbt_rec_t); + ifp->if_u1.if_ext_irec = erp; + + return; +} + +/* + * Allocate and initialize a new entry in the indirection array. + */ +xfs_ext_irec_t * +xfs_iext_irec_new( + xfs_ifork_t *ifp, /* inode fork pointer */ + int erp_idx) /* index for new irec */ +{ + xfs_ext_irec_t *erp; /* indirection array pointer */ + int i; /* loop counter */ + int nlists; /* number of irec's (ex lists) */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + + /* Resize indirection array */ + xfs_iext_realloc_indirect(ifp, ++nlists * + sizeof(xfs_ext_irec_t)); + /* + * Move records down in the array so the + * new page can use erp_idx. + */ + erp = ifp->if_u1.if_ext_irec; + for (i = nlists - 1; i > erp_idx; i--) { + memmove(&erp[i], &erp[i-1], sizeof(xfs_ext_irec_t)); + } + ASSERT(i == erp_idx); + + /* Initialize new extent record */ + erp = ifp->if_u1.if_ext_irec; + erp[erp_idx].er_extbuf = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS); + ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; + memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ); + erp[erp_idx].er_extcount = 0; + erp[erp_idx].er_extoff = erp_idx > 0 ? + erp[erp_idx-1].er_extoff + erp[erp_idx-1].er_extcount : 0; + return (&erp[erp_idx]); +} + +/* + * Remove a record from the indirection array. + */ +void +xfs_iext_irec_remove( + xfs_ifork_t *ifp, /* inode fork pointer */ + int erp_idx) /* irec index to remove */ +{ + xfs_ext_irec_t *erp; /* indirection array pointer */ + int i; /* loop counter */ + int nlists; /* number of irec's (ex lists) */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + erp = &ifp->if_u1.if_ext_irec[erp_idx]; + if (erp->er_extbuf) { + xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, + -erp->er_extcount); + kmem_free(erp->er_extbuf); + } + /* Compact extent records */ + erp = ifp->if_u1.if_ext_irec; + for (i = erp_idx; i < nlists - 1; i++) { + memmove(&erp[i], &erp[i+1], sizeof(xfs_ext_irec_t)); + } + /* + * Manually free the last extent record from the indirection + * array. A call to xfs_iext_realloc_indirect() with a size + * of zero would result in a call to xfs_iext_destroy() which + * would in turn call this function again, creating a nasty + * infinite loop. + */ + if (--nlists) { + xfs_iext_realloc_indirect(ifp, + nlists * sizeof(xfs_ext_irec_t)); + } else { + kmem_free(ifp->if_u1.if_ext_irec); + } + ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; +} + +/* + * This is called to clean up large amounts of unused memory allocated + * by the indirection array. Before compacting anything though, verify + * that the indirection array is still needed and switch back to the + * linear extent list (or even the inline buffer) if possible. The + * compaction policy is as follows: + * + * Full Compaction: Extents fit into a single page (or inline buffer) + * Partial Compaction: Extents occupy less than 50% of allocated space + * No Compaction: Extents occupy at least 50% of allocated space + */ +void +xfs_iext_irec_compact( + xfs_ifork_t *ifp) /* inode fork pointer */ +{ + xfs_extnum_t nextents; /* number of extents in file */ + int nlists; /* number of irec's (ex lists) */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + + if (nextents == 0) { + xfs_iext_destroy(ifp); + } else if (nextents <= XFS_INLINE_EXTS) { + xfs_iext_indirect_to_direct(ifp); + xfs_iext_direct_to_inline(ifp, nextents); + } else if (nextents <= XFS_LINEAR_EXTS) { + xfs_iext_indirect_to_direct(ifp); + } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 1) { + xfs_iext_irec_compact_pages(ifp); + } +} + +/* + * Combine extents from neighboring extent pages. + */ +void +xfs_iext_irec_compact_pages( + xfs_ifork_t *ifp) /* inode fork pointer */ +{ + xfs_ext_irec_t *erp, *erp_next;/* pointers to irec entries */ + int erp_idx = 0; /* indirection array index */ + int nlists; /* number of irec's (ex lists) */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + while (erp_idx < nlists - 1) { + erp = &ifp->if_u1.if_ext_irec[erp_idx]; + erp_next = erp + 1; + if (erp_next->er_extcount <= + (XFS_LINEAR_EXTS - erp->er_extcount)) { + memcpy(&erp->er_extbuf[erp->er_extcount], + erp_next->er_extbuf, erp_next->er_extcount * + sizeof(xfs_bmbt_rec_t)); + erp->er_extcount += erp_next->er_extcount; + /* + * Free page before removing extent record + * so er_extoffs don't get modified in + * xfs_iext_irec_remove. + */ + kmem_free(erp_next->er_extbuf); + erp_next->er_extbuf = NULL; + xfs_iext_irec_remove(ifp, erp_idx + 1); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + } else { + erp_idx++; + } + } +} + +/* + * This is called to update the er_extoff field in the indirection + * array when extents have been added or removed from one of the + * extent lists. erp_idx contains the irec index to begin updating + * at and ext_diff contains the number of extents that were added + * or removed. + */ +void +xfs_iext_irec_update_extoffs( + xfs_ifork_t *ifp, /* inode fork pointer */ + int erp_idx, /* irec index to update */ + int ext_diff) /* number of new extents */ +{ + int i; /* loop counter */ + int nlists; /* number of irec's (ex lists */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + for (i = erp_idx; i < nlists; i++) { + ifp->if_u1.if_ext_irec[i].er_extoff += ext_diff; + } +} diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_log_rlimit.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_log_rlimit.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_log_rlimit.c 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_log_rlimit.c 2013-10-10 21:07:17.000000000 +0000 @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013 Jie Liu. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include + +/* + * Calculate the maximum length in bytes that would be required for a local + * attribute value as large attributes out of line are not logged. + */ +STATIC int +xfs_log_calc_max_attrsetm_res( + struct xfs_mount *mp) +{ + int size; + int nblks; + + size = xfs_attr_leaf_entsize_local_max(mp->m_sb.sb_blocksize) - + MAXNAMELEN - 1; + nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); + nblks += XFS_B_TO_FSB(mp, size); + nblks += XFS_NEXTENTADD_SPACE_RES(mp, size, XFS_ATTR_FORK); + + return M_RES(mp)->tr_attrsetm.tr_logres + + M_RES(mp)->tr_attrsetrt.tr_logres * nblks; +} + +/* + * Iterate over the log space reservation table to figure out and return + * the maximum one in terms of the pre-calculated values which were done + * at mount time. + */ +STATIC void +xfs_log_get_max_trans_res( + struct xfs_mount *mp, + struct xfs_trans_res *max_resp) +{ + struct xfs_trans_res *resp; + struct xfs_trans_res *end_resp; + int log_space = 0; + int attr_space; + + attr_space = xfs_log_calc_max_attrsetm_res(mp); + + resp = (struct xfs_trans_res *)M_RES(mp); + end_resp = (struct xfs_trans_res *)(M_RES(mp) + 1); + for (; resp < end_resp; resp++) { + int tmp = resp->tr_logcount > 1 ? + resp->tr_logres * resp->tr_logcount : + resp->tr_logres; + if (log_space < tmp) { + log_space = tmp; + *max_resp = *resp; /* struct copy */ + } + } + + if (attr_space > log_space) { + *max_resp = M_RES(mp)->tr_attrsetm; /* struct copy */ + max_resp->tr_logres = attr_space; + } +} + +/* + * Calculate the minimum valid log size for the given superblock configuration. + * Used to calculate the minimum log size at mkfs time, and to determine if + * the log is large enough or not at mount time. Returns the minimum size in + * filesystem block size units. + */ +int +xfs_log_calc_minimum_size( + struct xfs_mount *mp) +{ + struct xfs_trans_res tres = {0}; + int max_logres; + int min_logblks = 0; + int lsunit = 0; + + xfs_log_get_max_trans_res(mp, &tres); + + max_logres = xfs_log_calc_unit_res(mp, tres.tr_logres); + if (tres.tr_logcount > 1) + max_logres *= tres.tr_logcount; + + if (xfs_sb_version_haslogv2(&mp->m_sb) && mp->m_sb.sb_logsunit > 1) + lsunit = BTOBB(mp->m_sb.sb_logsunit); + + /* + * Two factors should be taken into account for calculating the minimum + * log space. + * 1) The fundamental limitation is that no single transaction can be + * larger than half size of the log. + * + * From mkfs.xfs, this is considered by the XFS_MIN_LOG_FACTOR + * define, which is set to 3. That means we can definitely fit + * maximally sized 2 transactions in the log. We'll use this same + * value here. + * + * 2) If the lsunit option is specified, a transaction requires 2 LSU + * for the reservation because there are two log writes that can + * require padding - the transaction data and the commit record which + * are written separately and both can require padding to the LSU. + * Consider that we can have an active CIL reservation holding 2*LSU, + * but the CIL is not over a push threshold, in this case, if we + * don't have enough log space for at one new transaction, which + * includes another 2*LSU in the reservation, we will run into dead + * loop situation in log space grant procedure. i.e. + * xlog_grant_head_wait(). + * + * Hence the log size needs to be able to contain two maximally sized + * and padded transactions, which is (2 * (2 * LSU + maxlres)). + * + * Also, the log size should be a multiple of the log stripe unit, round + * it up to lsunit boundary if lsunit is specified. + */ + if (lsunit) { + min_logblks = roundup_64(BTOBB(max_logres), lsunit) + + 2 * lsunit; + } else + min_logblks = BTOBB(max_logres) + 2 * BBSIZE; + min_logblks *= XFS_MIN_LOG_FACTOR; + + return XFS_BB_TO_FSB(mp, min_logblks); +} diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_mount.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_mount.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_mount.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_mount.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,355 +0,0 @@ -/* - * Copyright (c) 2000-2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -static const struct { - short offset; - short type; /* 0 = integer - * 1 = binary / string (no translation) - */ -} xfs_sb_info[] = { - { offsetof(xfs_sb_t, sb_magicnum), 0 }, - { offsetof(xfs_sb_t, sb_blocksize), 0 }, - { offsetof(xfs_sb_t, sb_dblocks), 0 }, - { offsetof(xfs_sb_t, sb_rblocks), 0 }, - { offsetof(xfs_sb_t, sb_rextents), 0 }, - { offsetof(xfs_sb_t, sb_uuid), 1 }, - { offsetof(xfs_sb_t, sb_logstart), 0 }, - { offsetof(xfs_sb_t, sb_rootino), 0 }, - { offsetof(xfs_sb_t, sb_rbmino), 0 }, - { offsetof(xfs_sb_t, sb_rsumino), 0 }, - { offsetof(xfs_sb_t, sb_rextsize), 0 }, - { offsetof(xfs_sb_t, sb_agblocks), 0 }, - { offsetof(xfs_sb_t, sb_agcount), 0 }, - { offsetof(xfs_sb_t, sb_rbmblocks), 0 }, - { offsetof(xfs_sb_t, sb_logblocks), 0 }, - { offsetof(xfs_sb_t, sb_versionnum), 0 }, - { offsetof(xfs_sb_t, sb_sectsize), 0 }, - { offsetof(xfs_sb_t, sb_inodesize), 0 }, - { offsetof(xfs_sb_t, sb_inopblock), 0 }, - { offsetof(xfs_sb_t, sb_fname[0]), 1 }, - { offsetof(xfs_sb_t, sb_blocklog), 0 }, - { offsetof(xfs_sb_t, sb_sectlog), 0 }, - { offsetof(xfs_sb_t, sb_inodelog), 0 }, - { offsetof(xfs_sb_t, sb_inopblog), 0 }, - { offsetof(xfs_sb_t, sb_agblklog), 0 }, - { offsetof(xfs_sb_t, sb_rextslog), 0 }, - { offsetof(xfs_sb_t, sb_inprogress), 0 }, - { offsetof(xfs_sb_t, sb_imax_pct), 0 }, - { offsetof(xfs_sb_t, sb_icount), 0 }, - { offsetof(xfs_sb_t, sb_ifree), 0 }, - { offsetof(xfs_sb_t, sb_fdblocks), 0 }, - { offsetof(xfs_sb_t, sb_frextents), 0 }, - { offsetof(xfs_sb_t, sb_uquotino), 0 }, - { offsetof(xfs_sb_t, sb_gquotino), 0 }, - { offsetof(xfs_sb_t, sb_qflags), 0 }, - { offsetof(xfs_sb_t, sb_flags), 0 }, - { offsetof(xfs_sb_t, sb_shared_vn), 0 }, - { offsetof(xfs_sb_t, sb_inoalignmt), 0 }, - { offsetof(xfs_sb_t, sb_unit), 0 }, - { offsetof(xfs_sb_t, sb_width), 0 }, - { offsetof(xfs_sb_t, sb_dirblklog), 0 }, - { offsetof(xfs_sb_t, sb_logsectlog), 0 }, - { offsetof(xfs_sb_t, sb_logsectsize),0 }, - { offsetof(xfs_sb_t, sb_logsunit), 0 }, - { offsetof(xfs_sb_t, sb_features2), 0 }, - { offsetof(xfs_sb_t, sb_bad_features2), 0 }, - { sizeof(xfs_sb_t), 0 } -}; - -/* - * Reference counting access wrappers to the perag structures. - * Because we never free per-ag structures, the only thing we - * have to protect against changes is the tree structure itself. - */ -struct xfs_perag * -xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno) -{ - struct xfs_perag *pag; - int ref = 0; - - rcu_read_lock(); - pag = radix_tree_lookup(&mp->m_perag_tree, agno); - if (pag) { - ASSERT(atomic_read(&pag->pag_ref) >= 0); - ref = atomic_inc_return(&pag->pag_ref); - } - trace_xfs_perag_get(mp, agno, ref, _RET_IP_); - rcu_read_unlock(); - return pag; -} - -void -xfs_perag_put(struct xfs_perag *pag) -{ - int ref; - - ASSERT(atomic_read(&pag->pag_ref) > 0); - ref = atomic_dec_return(&pag->pag_ref); - trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_); -} - -void -xfs_sb_from_disk( - xfs_sb_t *to, - xfs_dsb_t *from) -{ - to->sb_magicnum = be32_to_cpu(from->sb_magicnum); - to->sb_blocksize = be32_to_cpu(from->sb_blocksize); - to->sb_dblocks = be64_to_cpu(from->sb_dblocks); - to->sb_rblocks = be64_to_cpu(from->sb_rblocks); - to->sb_rextents = be64_to_cpu(from->sb_rextents); - memcpy(&to->sb_uuid, &from->sb_uuid, sizeof(to->sb_uuid)); - to->sb_logstart = be64_to_cpu(from->sb_logstart); - to->sb_rootino = be64_to_cpu(from->sb_rootino); - to->sb_rbmino = be64_to_cpu(from->sb_rbmino); - to->sb_rsumino = be64_to_cpu(from->sb_rsumino); - to->sb_rextsize = be32_to_cpu(from->sb_rextsize); - to->sb_agblocks = be32_to_cpu(from->sb_agblocks); - to->sb_agcount = be32_to_cpu(from->sb_agcount); - to->sb_rbmblocks = be32_to_cpu(from->sb_rbmblocks); - to->sb_logblocks = be32_to_cpu(from->sb_logblocks); - to->sb_versionnum = be16_to_cpu(from->sb_versionnum); - to->sb_sectsize = be16_to_cpu(from->sb_sectsize); - to->sb_inodesize = be16_to_cpu(from->sb_inodesize); - to->sb_inopblock = be16_to_cpu(from->sb_inopblock); - memcpy(&to->sb_fname, &from->sb_fname, sizeof(to->sb_fname)); - to->sb_blocklog = from->sb_blocklog; - to->sb_sectlog = from->sb_sectlog; - to->sb_inodelog = from->sb_inodelog; - to->sb_inopblog = from->sb_inopblog; - to->sb_agblklog = from->sb_agblklog; - to->sb_rextslog = from->sb_rextslog; - to->sb_inprogress = from->sb_inprogress; - to->sb_imax_pct = from->sb_imax_pct; - to->sb_icount = be64_to_cpu(from->sb_icount); - to->sb_ifree = be64_to_cpu(from->sb_ifree); - to->sb_fdblocks = be64_to_cpu(from->sb_fdblocks); - to->sb_frextents = be64_to_cpu(from->sb_frextents); - to->sb_uquotino = be64_to_cpu(from->sb_uquotino); - to->sb_gquotino = be64_to_cpu(from->sb_gquotino); - to->sb_qflags = be16_to_cpu(from->sb_qflags); - to->sb_flags = from->sb_flags; - to->sb_shared_vn = from->sb_shared_vn; - to->sb_inoalignmt = be32_to_cpu(from->sb_inoalignmt); - to->sb_unit = be32_to_cpu(from->sb_unit); - to->sb_width = be32_to_cpu(from->sb_width); - to->sb_dirblklog = from->sb_dirblklog; - to->sb_logsectlog = from->sb_logsectlog; - to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize); - to->sb_logsunit = be32_to_cpu(from->sb_logsunit); - to->sb_features2 = be32_to_cpu(from->sb_features2); - to->sb_bad_features2 = be32_to_cpu(from->sb_bad_features2); -} - -/* - * Copy in core superblock to ondisk one. - * - * The fields argument is mask of superblock fields to copy. - */ -void -xfs_sb_to_disk( - xfs_dsb_t *to, - xfs_sb_t *from, - __int64_t fields) -{ - xfs_caddr_t to_ptr = (xfs_caddr_t)to; - xfs_caddr_t from_ptr = (xfs_caddr_t)from; - xfs_sb_field_t f; - int first; - int size; - - ASSERT(fields); - if (!fields) - return; - - while (fields) { - f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); - first = xfs_sb_info[f].offset; - size = xfs_sb_info[f + 1].offset - first; - - ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1); - - if (size == 1 || xfs_sb_info[f].type == 1) { - memcpy(to_ptr + first, from_ptr + first, size); - } else { - switch (size) { - case 2: - *(__be16 *)(to_ptr + first) = - cpu_to_be16(*(__u16 *)(from_ptr + first)); - break; - case 4: - *(__be32 *)(to_ptr + first) = - cpu_to_be32(*(__u32 *)(from_ptr + first)); - break; - case 8: - *(__be64 *)(to_ptr + first) = - cpu_to_be64(*(__u64 *)(from_ptr + first)); - break; - default: - ASSERT(0); - } - } - - fields &= ~(1LL << f); - } -} - -/* - * xfs_mount_common - * - * Mount initialization code establishing various mount - * fields from the superblock associated with the given - * mount structure - * - * Note: this requires user-space public scope for libxfs_mount - */ -void -xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp) -{ - mp->m_agfrotor = mp->m_agirotor = 0; - spin_lock_init(&mp->m_agirotor_lock); - mp->m_maxagi = mp->m_sb.sb_agcount; - mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG; - mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT; - mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT; - mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1; - mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog; - mp->m_blockmask = sbp->sb_blocksize - 1; - mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; - mp->m_blockwmask = mp->m_blockwsize - 1; - - mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1); - mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0); - mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2; - mp->m_alloc_mnr[1] = mp->m_alloc_mxr[1] / 2; - - mp->m_inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 1); - mp->m_inobt_mxr[1] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 0); - mp->m_inobt_mnr[0] = mp->m_inobt_mxr[0] / 2; - mp->m_inobt_mnr[1] = mp->m_inobt_mxr[1] / 2; - - mp->m_bmap_dmxr[0] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 1); - mp->m_bmap_dmxr[1] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 0); - mp->m_bmap_dmnr[0] = mp->m_bmap_dmxr[0] / 2; - mp->m_bmap_dmnr[1] = mp->m_bmap_dmxr[1] / 2; - - mp->m_bsize = XFS_FSB_TO_BB(mp, 1); - mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK, - sbp->sb_inopblock); - mp->m_ialloc_blks = mp->m_ialloc_inos >> sbp->sb_inopblog; -} - -/* - * xfs_initialize_perag_data - * - * Read in each per-ag structure so we can count up the number of - * allocated inodes, free inodes and used filesystem blocks as this - * information is no longer persistent in the superblock. Once we have - * this information, write it into the in-core superblock structure. - * - * Note: this requires user-space public scope for libxfs_mount - */ -int -xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount) -{ - xfs_agnumber_t index; - xfs_perag_t *pag; - xfs_sb_t *sbp = &mp->m_sb; - uint64_t ifree = 0; - uint64_t ialloc = 0; - uint64_t bfree = 0; - uint64_t bfreelst = 0; - uint64_t btree = 0; - int error; - - for (index = 0; index < agcount; index++) { - /* - * read the agf, then the agi. This gets us - * all the information we need and populates the - * per-ag structures for us. - */ - error = xfs_alloc_pagf_init(mp, NULL, index, 0); - if (error) - return error; - - error = xfs_ialloc_pagi_init(mp, NULL, index); - if (error) - return error; - pag = xfs_perag_get(mp, index); - ifree += pag->pagi_freecount; - ialloc += pag->pagi_count; - bfree += pag->pagf_freeblks; - bfreelst += pag->pagf_flcount; - btree += pag->pagf_btreeblks; - xfs_perag_put(pag); - } - /* - * Overwrite incore superblock counters with just-read data - */ - spin_lock(&mp->m_sb_lock); - sbp->sb_ifree = ifree; - sbp->sb_icount = ialloc; - sbp->sb_fdblocks = bfree + bfreelst + btree; - spin_unlock(&mp->m_sb_lock); - - /* Fixup the per-cpu counters as well. */ - xfs_icsb_reinit_counters(mp); - - return 0; -} - -/* - * xfs_mod_sb() can be used to copy arbitrary changes to the - * in-core superblock into the superblock buffer to be logged. - * It does not provide the higher level of locking that is - * needed to protect the in-core superblock from concurrent - * access. - */ -void -xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) -{ - xfs_buf_t *bp; - int first; - int last; - xfs_mount_t *mp; - xfs_sb_field_t f; - - ASSERT(fields); - if (!fields) - return; - mp = tp->t_mountp; - bp = xfs_trans_getsb(tp, mp, 0); - first = sizeof(xfs_sb_t); - last = 0; - - /* translate/copy */ - xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields); - - /* find modified range */ - f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields); - ASSERT((1LL << f) & XFS_SB_MOD_BITS); - last = xfs_sb_info[f + 1].offset - 1; - - f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); - ASSERT((1LL << f) & XFS_SB_MOD_BITS); - first = xfs_sb_info[f].offset; - - xfs_trans_log_buf(tp, bp, first, last); -} diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_rtalloc.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_rtalloc.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_rtalloc.c 2010-01-28 09:49:03.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_rtalloc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,789 +0,0 @@ -/* - * Copyright (c) 2000-2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -/* - * Prototypes for internal functions. - */ - - -STATIC int xfs_rtfind_back(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t, - xfs_rtblock_t, xfs_rtblock_t *); -STATIC int xfs_rtfind_forw(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t, - xfs_rtblock_t, xfs_rtblock_t *); -STATIC int xfs_rtmodify_range(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t, - xfs_extlen_t, int); -STATIC int xfs_rtmodify_summary(xfs_mount_t *, xfs_trans_t *, int, - xfs_rtblock_t, int, xfs_buf_t **, xfs_fsblock_t *); - -/* - * Internal functions. - */ - -/* - * Get a buffer for the bitmap or summary file block specified. - * The buffer is returned read and locked. - */ -STATIC int /* error */ -xfs_rtbuf_get( - xfs_mount_t *mp, /* file system mount structure */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t block, /* block number in bitmap or summary */ - int issum, /* is summary not bitmap */ - xfs_buf_t **bpp) /* output: buffer for the block */ -{ - xfs_buf_t *bp; /* block buffer, result */ - xfs_daddr_t d; /* disk addr of block */ - int error; /* error value */ - xfs_fsblock_t fsb; /* fs block number for block */ - xfs_inode_t *ip; /* bitmap or summary inode */ - - ip = issum ? mp->m_rsumip : mp->m_rbmip; - /* - * Map from the file offset (block) and inode number to the - * file system block. - */ - error = xfs_bmapi_single(tp, ip, XFS_DATA_FORK, &fsb, block); - if (error) { - return error; - } - ASSERT(fsb != NULLFSBLOCK); - /* - * Convert to disk address for buffer cache. - */ - d = XFS_FSB_TO_DADDR(mp, fsb); - /* - * Read the buffer. - */ - error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d, - mp->m_bsize, 0, &bp); - if (error) { - return error; - } - ASSERT(bp && !XFS_BUF_GETERROR(bp)); - *bpp = bp; - return 0; -} - -/* - * Searching backward from start to limit, find the first block whose - * allocated/free state is different from start's. - */ -STATIC int /* error */ -xfs_rtfind_back( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t start, /* starting block to look at */ - xfs_rtblock_t limit, /* last block to look at */ - xfs_rtblock_t *rtblock) /* out: start block found */ -{ - xfs_rtword_t *b; /* current word in buffer */ - int bit; /* bit number in the word */ - xfs_rtblock_t block; /* bitmap block number */ - xfs_buf_t *bp; /* buf for the block */ - xfs_rtword_t *bufp; /* starting word in buffer */ - int error; /* error value */ - xfs_rtblock_t firstbit; /* first useful bit in the word */ - xfs_rtblock_t i; /* current bit number rel. to start */ - xfs_rtblock_t len; /* length of inspected area */ - xfs_rtword_t mask; /* mask of relevant bits for value */ - xfs_rtword_t want; /* mask for "good" values */ - xfs_rtword_t wdiff; /* difference from wanted value */ - int word; /* word number in the buffer */ - - /* - * Compute and read in starting bitmap block for starting block. - */ - block = XFS_BITTOBLOCK(mp, start); - error = xfs_rtbuf_get(mp, tp, block, 0, &bp); - if (error) { - return error; - } - bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); - /* - * Get the first word's index & point to it. - */ - word = XFS_BITTOWORD(mp, start); - b = &bufp[word]; - bit = (int)(start & (XFS_NBWORD - 1)); - len = start - limit + 1; - /* - * Compute match value, based on the bit at start: if 1 (free) - * then all-ones, else all-zeroes. - */ - want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0; - /* - * If the starting position is not word-aligned, deal with the - * partial word. - */ - if (bit < XFS_NBWORD - 1) { - /* - * Calculate first (leftmost) bit number to look at, - * and mask for all the relevant bits in this word. - */ - firstbit = XFS_RTMAX((xfs_srtblock_t)(bit - len + 1), 0); - mask = (((xfs_rtword_t)1 << (bit - firstbit + 1)) - 1) << - firstbit; - /* - * Calculate the difference between the value there - * and what we're looking for. - */ - if ((wdiff = (*b ^ want) & mask)) { - /* - * Different. Mark where we are and return. - */ - xfs_trans_brelse(tp, bp); - i = bit - XFS_RTHIBIT(wdiff); - *rtblock = start - i + 1; - return 0; - } - i = bit - firstbit + 1; - /* - * Go on to previous block if that's where the previous word is - * and we need the previous word. - */ - if (--word == -1 && i < len) { - /* - * If done with this block, get the previous one. - */ - xfs_trans_brelse(tp, bp); - error = xfs_rtbuf_get(mp, tp, --block, 0, &bp); - if (error) { - return error; - } - bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); - word = XFS_BLOCKWMASK(mp); - b = &bufp[word]; - } else { - /* - * Go on to the previous word in the buffer. - */ - b--; - } - } else { - /* - * Starting on a word boundary, no partial word. - */ - i = 0; - } - /* - * Loop over whole words in buffers. When we use up one buffer - * we move on to the previous one. - */ - while (len - i >= XFS_NBWORD) { - /* - * Compute difference between actual and desired value. - */ - if ((wdiff = *b ^ want)) { - /* - * Different, mark where we are and return. - */ - xfs_trans_brelse(tp, bp); - i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); - *rtblock = start - i + 1; - return 0; - } - i += XFS_NBWORD; - /* - * Go on to previous block if that's where the previous word is - * and we need the previous word. - */ - if (--word == -1 && i < len) { - /* - * If done with this block, get the previous one. - */ - xfs_trans_brelse(tp, bp); - error = xfs_rtbuf_get(mp, tp, --block, 0, &bp); - if (error) { - return error; - } - bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); - word = XFS_BLOCKWMASK(mp); - b = &bufp[word]; - } else { - /* - * Go on to the previous word in the buffer. - */ - b--; - } - } - /* - * If not ending on a word boundary, deal with the last - * (partial) word. - */ - if (len - i) { - /* - * Calculate first (leftmost) bit number to look at, - * and mask for all the relevant bits in this word. - */ - firstbit = XFS_NBWORD - (len - i); - mask = (((xfs_rtword_t)1 << (len - i)) - 1) << firstbit; - /* - * Compute difference between actual and desired value. - */ - if ((wdiff = (*b ^ want) & mask)) { - /* - * Different, mark where we are and return. - */ - xfs_trans_brelse(tp, bp); - i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); - *rtblock = start - i + 1; - return 0; - } else - i = len; - } - /* - * No match, return that we scanned the whole area. - */ - xfs_trans_brelse(tp, bp); - *rtblock = start - i + 1; - return 0; -} - -/* - * Searching forward from start to limit, find the first block whose - * allocated/free state is different from start's. - */ -STATIC int /* error */ -xfs_rtfind_forw( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t start, /* starting block to look at */ - xfs_rtblock_t limit, /* last block to look at */ - xfs_rtblock_t *rtblock) /* out: start block found */ -{ - xfs_rtword_t *b; /* current word in buffer */ - int bit; /* bit number in the word */ - xfs_rtblock_t block; /* bitmap block number */ - xfs_buf_t *bp; /* buf for the block */ - xfs_rtword_t *bufp; /* starting word in buffer */ - int error; /* error value */ - xfs_rtblock_t i; /* current bit number rel. to start */ - xfs_rtblock_t lastbit; /* last useful bit in the word */ - xfs_rtblock_t len; /* length of inspected area */ - xfs_rtword_t mask; /* mask of relevant bits for value */ - xfs_rtword_t want; /* mask for "good" values */ - xfs_rtword_t wdiff; /* difference from wanted value */ - int word; /* word number in the buffer */ - - /* - * Compute and read in starting bitmap block for starting block. - */ - block = XFS_BITTOBLOCK(mp, start); - error = xfs_rtbuf_get(mp, tp, block, 0, &bp); - if (error) { - return error; - } - bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); - /* - * Get the first word's index & point to it. - */ - word = XFS_BITTOWORD(mp, start); - b = &bufp[word]; - bit = (int)(start & (XFS_NBWORD - 1)); - len = limit - start + 1; - /* - * Compute match value, based on the bit at start: if 1 (free) - * then all-ones, else all-zeroes. - */ - want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0; - /* - * If the starting position is not word-aligned, deal with the - * partial word. - */ - if (bit) { - /* - * Calculate last (rightmost) bit number to look at, - * and mask for all the relevant bits in this word. - */ - lastbit = XFS_RTMIN(bit + len, XFS_NBWORD); - mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit; - /* - * Calculate the difference between the value there - * and what we're looking for. - */ - if ((wdiff = (*b ^ want) & mask)) { - /* - * Different. Mark where we are and return. - */ - xfs_trans_brelse(tp, bp); - i = XFS_RTLOBIT(wdiff) - bit; - *rtblock = start + i - 1; - return 0; - } - i = lastbit - bit; - /* - * Go on to next block if that's where the next word is - * and we need the next word. - */ - if (++word == XFS_BLOCKWSIZE(mp) && i < len) { - /* - * If done with this block, get the previous one. - */ - xfs_trans_brelse(tp, bp); - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); - if (error) { - return error; - } - b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); - word = 0; - } else { - /* - * Go on to the previous word in the buffer. - */ - b++; - } - } else { - /* - * Starting on a word boundary, no partial word. - */ - i = 0; - } - /* - * Loop over whole words in buffers. When we use up one buffer - * we move on to the next one. - */ - while (len - i >= XFS_NBWORD) { - /* - * Compute difference between actual and desired value. - */ - if ((wdiff = *b ^ want)) { - /* - * Different, mark where we are and return. - */ - xfs_trans_brelse(tp, bp); - i += XFS_RTLOBIT(wdiff); - *rtblock = start + i - 1; - return 0; - } - i += XFS_NBWORD; - /* - * Go on to next block if that's where the next word is - * and we need the next word. - */ - if (++word == XFS_BLOCKWSIZE(mp) && i < len) { - /* - * If done with this block, get the next one. - */ - xfs_trans_brelse(tp, bp); - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); - if (error) { - return error; - } - b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); - word = 0; - } else { - /* - * Go on to the next word in the buffer. - */ - b++; - } - } - /* - * If not ending on a word boundary, deal with the last - * (partial) word. - */ - if ((lastbit = len - i)) { - /* - * Calculate mask for all the relevant bits in this word. - */ - mask = ((xfs_rtword_t)1 << lastbit) - 1; - /* - * Compute difference between actual and desired value. - */ - if ((wdiff = (*b ^ want) & mask)) { - /* - * Different, mark where we are and return. - */ - xfs_trans_brelse(tp, bp); - i += XFS_RTLOBIT(wdiff); - *rtblock = start + i - 1; - return 0; - } else - i = len; - } - /* - * No match, return that we scanned the whole area. - */ - xfs_trans_brelse(tp, bp); - *rtblock = start + i - 1; - return 0; -} - -/* - * Mark an extent specified by start and len freed. - * Updates all the summary information as well as the bitmap. - */ -STATIC int /* error */ -xfs_rtfree_range( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t start, /* starting block to free */ - xfs_extlen_t len, /* length to free */ - xfs_buf_t **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb) /* in/out: summary block number */ -{ - xfs_rtblock_t end; /* end of the freed extent */ - int error; /* error value */ - xfs_rtblock_t postblock; /* first block freed > end */ - xfs_rtblock_t preblock; /* first block freed < start */ - - end = start + len - 1; - /* - * Modify the bitmap to mark this extent freed. - */ - error = xfs_rtmodify_range(mp, tp, start, len, 1); - if (error) { - return error; - } - /* - * Assume we're freeing out of the middle of an allocated extent. - * We need to find the beginning and end of the extent so we can - * properly update the summary. - */ - error = xfs_rtfind_back(mp, tp, start, 0, &preblock); - if (error) { - return error; - } - /* - * Find the next allocated block (end of allocated extent). - */ - error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1, - &postblock); - if (error) - return error; - /* - * If there are blocks not being freed at the front of the - * old extent, add summary data for them to be allocated. - */ - if (preblock < start) { - error = xfs_rtmodify_summary(mp, tp, - XFS_RTBLOCKLOG(start - preblock), - XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb); - if (error) { - return error; - } - } - /* - * If there are blocks not being freed at the end of the - * old extent, add summary data for them to be allocated. - */ - if (postblock > end) { - error = xfs_rtmodify_summary(mp, tp, - XFS_RTBLOCKLOG(postblock - end), - XFS_BITTOBLOCK(mp, end + 1), -1, rbpp, rsb); - if (error) { - return error; - } - } - /* - * Increment the summary information corresponding to the entire - * (new) free extent. - */ - error = xfs_rtmodify_summary(mp, tp, - XFS_RTBLOCKLOG(postblock + 1 - preblock), - XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb); - return error; -} - -/* - * Set the given range of bitmap bits to the given value. - * Do whatever I/O and logging is required. - */ -STATIC int /* error */ -xfs_rtmodify_range( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t start, /* starting block to modify */ - xfs_extlen_t len, /* length of extent to modify */ - int val) /* 1 for free, 0 for allocated */ -{ - xfs_rtword_t *b; /* current word in buffer */ - int bit; /* bit number in the word */ - xfs_rtblock_t block; /* bitmap block number */ - xfs_buf_t *bp; /* buf for the block */ - xfs_rtword_t *bufp; /* starting word in buffer */ - int error; /* error value */ - xfs_rtword_t *first; /* first used word in the buffer */ - int i; /* current bit number rel. to start */ - int lastbit; /* last useful bit in word */ - xfs_rtword_t mask; /* mask o frelevant bits for value */ - int word; /* word number in the buffer */ - - /* - * Compute starting bitmap block number. - */ - block = XFS_BITTOBLOCK(mp, start); - /* - * Read the bitmap block, and point to its data. - */ - error = xfs_rtbuf_get(mp, tp, block, 0, &bp); - if (error) { - return error; - } - bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); - /* - * Compute the starting word's address, and starting bit. - */ - word = XFS_BITTOWORD(mp, start); - first = b = &bufp[word]; - bit = (int)(start & (XFS_NBWORD - 1)); - /* - * 0 (allocated) => all zeroes; 1 (free) => all ones. - */ - val = -val; - /* - * If not starting on a word boundary, deal with the first - * (partial) word. - */ - if (bit) { - /* - * Compute first bit not changed and mask of relevant bits. - */ - lastbit = XFS_RTMIN(bit + len, XFS_NBWORD); - mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit; - /* - * Set/clear the active bits. - */ - if (val) - *b |= mask; - else - *b &= ~mask; - i = lastbit - bit; - /* - * Go on to the next block if that's where the next word is - * and we need the next word. - */ - if (++word == XFS_BLOCKWSIZE(mp) && i < len) { - /* - * Log the changed part of this block. - * Get the next one. - */ - xfs_trans_log_buf(tp, bp, - (uint)((char *)first - (char *)bufp), - (uint)((char *)b - (char *)bufp)); - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); - if (error) { - return error; - } - first = b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); - word = 0; - } else { - /* - * Go on to the next word in the buffer - */ - b++; - } - } else { - /* - * Starting on a word boundary, no partial word. - */ - i = 0; - } - /* - * Loop over whole words in buffers. When we use up one buffer - * we move on to the next one. - */ - while (len - i >= XFS_NBWORD) { - /* - * Set the word value correctly. - */ - *b = val; - i += XFS_NBWORD; - /* - * Go on to the next block if that's where the next word is - * and we need the next word. - */ - if (++word == XFS_BLOCKWSIZE(mp) && i < len) { - /* - * Log the changed part of this block. - * Get the next one. - */ - xfs_trans_log_buf(tp, bp, - (uint)((char *)first - (char *)bufp), - (uint)((char *)b - (char *)bufp)); - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); - if (error) { - return error; - } - first = b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); - word = 0; - } else { - /* - * Go on to the next word in the buffer - */ - b++; - } - } - /* - * If not ending on a word boundary, deal with the last - * (partial) word. - */ - if ((lastbit = len - i)) { - /* - * Compute a mask of relevant bits. - */ - bit = 0; - mask = ((xfs_rtword_t)1 << lastbit) - 1; - /* - * Set/clear the active bits. - */ - if (val) - *b |= mask; - else - *b &= ~mask; - b++; - } - /* - * Log any remaining changed bytes. - */ - if (b > first) - xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp), - (uint)((char *)b - (char *)bufp - 1)); - return 0; -} - -/* - * Read and modify the summary information for a given extent size, - * bitmap block combination. - * Keeps track of a current summary block, so we don't keep reading - * it from the buffer cache. - */ -STATIC int /* error */ -xfs_rtmodify_summary( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - int log, /* log2 of extent size */ - xfs_rtblock_t bbno, /* bitmap block number */ - int delta, /* change to make to summary info */ - xfs_buf_t **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb) /* in/out: summary block number */ -{ - xfs_buf_t *bp; /* buffer for the summary block */ - int error; /* error value */ - xfs_fsblock_t sb; /* summary fsblock */ - int so; /* index into the summary file */ - xfs_suminfo_t *sp; /* pointer to returned data */ - - /* - * Compute entry number in the summary file. - */ - so = XFS_SUMOFFS(mp, log, bbno); - /* - * Compute the block number in the summary file. - */ - sb = XFS_SUMOFFSTOBLOCK(mp, so); - /* - * If we have an old buffer, and the block number matches, use that. - */ - if (rbpp && *rbpp && *rsb == sb) - bp = *rbpp; - /* - * Otherwise we have to get the buffer. - */ - else { - /* - * If there was an old one, get rid of it first. - */ - if (rbpp && *rbpp) - xfs_trans_brelse(tp, *rbpp); - error = xfs_rtbuf_get(mp, tp, sb, 1, &bp); - if (error) { - return error; - } - /* - * Remember this buffer and block for the next call. - */ - if (rbpp) { - *rbpp = bp; - *rsb = sb; - } - } - /* - * Point to the summary information, modify and log it. - */ - sp = XFS_SUMPTR(mp, bp, so); - *sp += delta; - xfs_trans_log_buf(tp, bp, (uint)((char *)sp - (char *)XFS_BUF_PTR(bp)), - (uint)((char *)sp - (char *)XFS_BUF_PTR(bp) + sizeof(*sp) - 1)); - return 0; -} - -/* - * Free an extent in the realtime subvolume. Length is expressed in - * realtime extents, as is the block number. - */ -int /* error */ -xfs_rtfree_extent( - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t bno, /* starting block number to free */ - xfs_extlen_t len) /* length of extent freed */ -{ - int error; /* error value */ - xfs_inode_t *ip; /* bitmap file inode */ - xfs_mount_t *mp; /* file system mount structure */ - xfs_fsblock_t sb; /* summary file block number */ - xfs_buf_t *sumbp; /* summary file block buffer */ - - mp = tp->t_mountp; - /* - * Synchronize by locking the bitmap inode. - */ - if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, - XFS_ILOCK_EXCL, &ip))) - return error; -#if defined(__KERNEL__) && defined(DEBUG) - /* - * Check to see that this whole range is currently allocated. - */ - { - int stat; /* result from checking range */ - - error = xfs_rtcheck_alloc_range(mp, tp, bno, len, &stat); - if (error) { - return error; - } - ASSERT(stat); - } -#endif - sumbp = NULL; - /* - * Free the range of realtime blocks. - */ - error = xfs_rtfree_range(mp, tp, bno, len, &sumbp, &sb); - if (error) { - return error; - } - /* - * Mark more blocks free in the superblock. - */ - xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, (long)len); - /* - * If we've now freed all the blocks, reset the file sequence - * number to 0. - */ - if (tp->t_frextents_delta + mp->m_sb.sb_frextents == - mp->m_sb.sb_rextents) { - if (!(ip->i_d.di_flags & XFS_DIFLAG_NEWRTBM)) - ip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM; - *(__uint64_t *)&ip->i_d.di_atime = 0; - xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - } - return 0; -} diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_rtbitmap.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_rtbitmap.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_rtbitmap.c 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_rtbitmap.c 2014-05-02 00:09:16.000000000 +0000 @@ -0,0 +1,951 @@ +/* + * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "xfs.h" + +/* + * Realtime allocator bitmap functions shared with userspace. + */ + +/* + * Get a buffer for the bitmap or summary file block specified. + * The buffer is returned read and locked. + */ +int +xfs_rtbuf_get( + xfs_mount_t *mp, /* file system mount structure */ + xfs_trans_t *tp, /* transaction pointer */ + xfs_rtblock_t block, /* block number in bitmap or summary */ + int issum, /* is summary not bitmap */ + xfs_buf_t **bpp) /* output: buffer for the block */ +{ + xfs_buf_t *bp; /* block buffer, result */ + xfs_inode_t *ip; /* bitmap or summary inode */ + xfs_bmbt_irec_t map; + int nmap = 1; + int error; /* error value */ + + ip = issum ? mp->m_rsumip : mp->m_rbmip; + + error = xfs_bmapi_read(ip, block, 1, &map, &nmap, XFS_DATA_FORK); + if (error) + return error; + + ASSERT(map.br_startblock != NULLFSBLOCK); + error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, + XFS_FSB_TO_DADDR(mp, map.br_startblock), + mp->m_bsize, 0, &bp, NULL); + if (error) + return error; + ASSERT(!xfs_buf_geterror(bp)); + *bpp = bp; + return 0; +} + +/* + * Searching backward from start to limit, find the first block whose + * allocated/free state is different from start's. + */ +int +xfs_rtfind_back( + xfs_mount_t *mp, /* file system mount point */ + xfs_trans_t *tp, /* transaction pointer */ + xfs_rtblock_t start, /* starting block to look at */ + xfs_rtblock_t limit, /* last block to look at */ + xfs_rtblock_t *rtblock) /* out: start block found */ +{ + xfs_rtword_t *b; /* current word in buffer */ + int bit; /* bit number in the word */ + xfs_rtblock_t block; /* bitmap block number */ + xfs_buf_t *bp; /* buf for the block */ + xfs_rtword_t *bufp; /* starting word in buffer */ + int error; /* error value */ + xfs_rtblock_t firstbit; /* first useful bit in the word */ + xfs_rtblock_t i; /* current bit number rel. to start */ + xfs_rtblock_t len; /* length of inspected area */ + xfs_rtword_t mask; /* mask of relevant bits for value */ + xfs_rtword_t want; /* mask for "good" values */ + xfs_rtword_t wdiff; /* difference from wanted value */ + int word; /* word number in the buffer */ + + /* + * Compute and read in starting bitmap block for starting block. + */ + block = XFS_BITTOBLOCK(mp, start); + error = xfs_rtbuf_get(mp, tp, block, 0, &bp); + if (error) { + return error; + } + bufp = bp->b_addr; + /* + * Get the first word's index & point to it. + */ + word = XFS_BITTOWORD(mp, start); + b = &bufp[word]; + bit = (int)(start & (XFS_NBWORD - 1)); + len = start - limit + 1; + /* + * Compute match value, based on the bit at start: if 1 (free) + * then all-ones, else all-zeroes. + */ + want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0; + /* + * If the starting position is not word-aligned, deal with the + * partial word. + */ + if (bit < XFS_NBWORD - 1) { + /* + * Calculate first (leftmost) bit number to look at, + * and mask for all the relevant bits in this word. + */ + firstbit = XFS_RTMAX((xfs_srtblock_t)(bit - len + 1), 0); + mask = (((xfs_rtword_t)1 << (bit - firstbit + 1)) - 1) << + firstbit; + /* + * Calculate the difference between the value there + * and what we're looking for. + */ + if ((wdiff = (*b ^ want) & mask)) { + /* + * Different. Mark where we are and return. + */ + xfs_trans_brelse(tp, bp); + i = bit - XFS_RTHIBIT(wdiff); + *rtblock = start - i + 1; + return 0; + } + i = bit - firstbit + 1; + /* + * Go on to previous block if that's where the previous word is + * and we need the previous word. + */ + if (--word == -1 && i < len) { + /* + * If done with this block, get the previous one. + */ + xfs_trans_brelse(tp, bp); + error = xfs_rtbuf_get(mp, tp, --block, 0, &bp); + if (error) { + return error; + } + bufp = bp->b_addr; + word = XFS_BLOCKWMASK(mp); + b = &bufp[word]; + } else { + /* + * Go on to the previous word in the buffer. + */ + b--; + } + } else { + /* + * Starting on a word boundary, no partial word. + */ + i = 0; + } + /* + * Loop over whole words in buffers. When we use up one buffer + * we move on to the previous one. + */ + while (len - i >= XFS_NBWORD) { + /* + * Compute difference between actual and desired value. + */ + if ((wdiff = *b ^ want)) { + /* + * Different, mark where we are and return. + */ + xfs_trans_brelse(tp, bp); + i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); + *rtblock = start - i + 1; + return 0; + } + i += XFS_NBWORD; + /* + * Go on to previous block if that's where the previous word is + * and we need the previous word. + */ + if (--word == -1 && i < len) { + /* + * If done with this block, get the previous one. + */ + xfs_trans_brelse(tp, bp); + error = xfs_rtbuf_get(mp, tp, --block, 0, &bp); + if (error) { + return error; + } + bufp = bp->b_addr; + word = XFS_BLOCKWMASK(mp); + b = &bufp[word]; + } else { + /* + * Go on to the previous word in the buffer. + */ + b--; + } + } + /* + * If not ending on a word boundary, deal with the last + * (partial) word. + */ + if (len - i) { + /* + * Calculate first (leftmost) bit number to look at, + * and mask for all the relevant bits in this word. + */ + firstbit = XFS_NBWORD - (len - i); + mask = (((xfs_rtword_t)1 << (len - i)) - 1) << firstbit; + /* + * Compute difference between actual and desired value. + */ + if ((wdiff = (*b ^ want) & mask)) { + /* + * Different, mark where we are and return. + */ + xfs_trans_brelse(tp, bp); + i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); + *rtblock = start - i + 1; + return 0; + } else + i = len; + } + /* + * No match, return that we scanned the whole area. + */ + xfs_trans_brelse(tp, bp); + *rtblock = start - i + 1; + return 0; +} + +/* + * Searching forward from start to limit, find the first block whose + * allocated/free state is different from start's. + */ +int +xfs_rtfind_forw( + xfs_mount_t *mp, /* file system mount point */ + xfs_trans_t *tp, /* transaction pointer */ + xfs_rtblock_t start, /* starting block to look at */ + xfs_rtblock_t limit, /* last block to look at */ + xfs_rtblock_t *rtblock) /* out: start block found */ +{ + xfs_rtword_t *b; /* current word in buffer */ + int bit; /* bit number in the word */ + xfs_rtblock_t block; /* bitmap block number */ + xfs_buf_t *bp; /* buf for the block */ + xfs_rtword_t *bufp; /* starting word in buffer */ + int error; /* error value */ + xfs_rtblock_t i; /* current bit number rel. to start */ + xfs_rtblock_t lastbit; /* last useful bit in the word */ + xfs_rtblock_t len; /* length of inspected area */ + xfs_rtword_t mask; /* mask of relevant bits for value */ + xfs_rtword_t want; /* mask for "good" values */ + xfs_rtword_t wdiff; /* difference from wanted value */ + int word; /* word number in the buffer */ + + /* + * Compute and read in starting bitmap block for starting block. + */ + block = XFS_BITTOBLOCK(mp, start); + error = xfs_rtbuf_get(mp, tp, block, 0, &bp); + if (error) { + return error; + } + bufp = bp->b_addr; + /* + * Get the first word's index & point to it. + */ + word = XFS_BITTOWORD(mp, start); + b = &bufp[word]; + bit = (int)(start & (XFS_NBWORD - 1)); + len = limit - start + 1; + /* + * Compute match value, based on the bit at start: if 1 (free) + * then all-ones, else all-zeroes. + */ + want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0; + /* + * If the starting position is not word-aligned, deal with the + * partial word. + */ + if (bit) { + /* + * Calculate last (rightmost) bit number to look at, + * and mask for all the relevant bits in this word. + */ + lastbit = XFS_RTMIN(bit + len, XFS_NBWORD); + mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit; + /* + * Calculate the difference between the value there + * and what we're looking for. + */ + if ((wdiff = (*b ^ want) & mask)) { + /* + * Different. Mark where we are and return. + */ + xfs_trans_brelse(tp, bp); + i = XFS_RTLOBIT(wdiff) - bit; + *rtblock = start + i - 1; + return 0; + } + i = lastbit - bit; + /* + * Go on to next block if that's where the next word is + * and we need the next word. + */ + if (++word == XFS_BLOCKWSIZE(mp) && i < len) { + /* + * If done with this block, get the previous one. + */ + xfs_trans_brelse(tp, bp); + error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); + if (error) { + return error; + } + b = bufp = bp->b_addr; + word = 0; + } else { + /* + * Go on to the previous word in the buffer. + */ + b++; + } + } else { + /* + * Starting on a word boundary, no partial word. + */ + i = 0; + } + /* + * Loop over whole words in buffers. When we use up one buffer + * we move on to the next one. + */ + while (len - i >= XFS_NBWORD) { + /* + * Compute difference between actual and desired value. + */ + if ((wdiff = *b ^ want)) { + /* + * Different, mark where we are and return. + */ + xfs_trans_brelse(tp, bp); + i += XFS_RTLOBIT(wdiff); + *rtblock = start + i - 1; + return 0; + } + i += XFS_NBWORD; + /* + * Go on to next block if that's where the next word is + * and we need the next word. + */ + if (++word == XFS_BLOCKWSIZE(mp) && i < len) { + /* + * If done with this block, get the next one. + */ + xfs_trans_brelse(tp, bp); + error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); + if (error) { + return error; + } + b = bufp = bp->b_addr; + word = 0; + } else { + /* + * Go on to the next word in the buffer. + */ + b++; + } + } + /* + * If not ending on a word boundary, deal with the last + * (partial) word. + */ + if ((lastbit = len - i)) { + /* + * Calculate mask for all the relevant bits in this word. + */ + mask = ((xfs_rtword_t)1 << lastbit) - 1; + /* + * Compute difference between actual and desired value. + */ + if ((wdiff = (*b ^ want) & mask)) { + /* + * Different, mark where we are and return. + */ + xfs_trans_brelse(tp, bp); + i += XFS_RTLOBIT(wdiff); + *rtblock = start + i - 1; + return 0; + } else + i = len; + } + /* + * No match, return that we scanned the whole area. + */ + xfs_trans_brelse(tp, bp); + *rtblock = start + i - 1; + return 0; +} + +/* + * Read and modify the summary information for a given extent size, + * bitmap block combination. + * Keeps track of a current summary block, so we don't keep reading + * it from the buffer cache. + */ +int +xfs_rtmodify_summary( + xfs_mount_t *mp, /* file system mount point */ + xfs_trans_t *tp, /* transaction pointer */ + int log, /* log2 of extent size */ + xfs_rtblock_t bbno, /* bitmap block number */ + int delta, /* change to make to summary info */ + xfs_buf_t **rbpp, /* in/out: summary block buffer */ + xfs_fsblock_t *rsb) /* in/out: summary block number */ +{ + xfs_buf_t *bp; /* buffer for the summary block */ + int error; /* error value */ + xfs_fsblock_t sb; /* summary fsblock */ + int so; /* index into the summary file */ + xfs_suminfo_t *sp; /* pointer to returned data */ + + /* + * Compute entry number in the summary file. + */ + so = XFS_SUMOFFS(mp, log, bbno); + /* + * Compute the block number in the summary file. + */ + sb = XFS_SUMOFFSTOBLOCK(mp, so); + /* + * If we have an old buffer, and the block number matches, use that. + */ + if (rbpp && *rbpp && *rsb == sb) + bp = *rbpp; + /* + * Otherwise we have to get the buffer. + */ + else { + /* + * If there was an old one, get rid of it first. + */ + if (rbpp && *rbpp) + xfs_trans_brelse(tp, *rbpp); + error = xfs_rtbuf_get(mp, tp, sb, 1, &bp); + if (error) { + return error; + } + /* + * Remember this buffer and block for the next call. + */ + if (rbpp) { + *rbpp = bp; + *rsb = sb; + } + } + /* + * Point to the summary information, modify and log it. + */ + sp = XFS_SUMPTR(mp, bp, so); + *sp += delta; + xfs_trans_log_buf(tp, bp, (uint)((char *)sp - (char *)bp->b_addr), + (uint)((char *)sp - (char *)bp->b_addr + sizeof(*sp) - 1)); + return 0; +} + +/* + * Set the given range of bitmap bits to the given value. + * Do whatever I/O and logging is required. + */ +int +xfs_rtmodify_range( + xfs_mount_t *mp, /* file system mount point */ + xfs_trans_t *tp, /* transaction pointer */ + xfs_rtblock_t start, /* starting block to modify */ + xfs_extlen_t len, /* length of extent to modify */ + int val) /* 1 for free, 0 for allocated */ +{ + xfs_rtword_t *b; /* current word in buffer */ + int bit; /* bit number in the word */ + xfs_rtblock_t block; /* bitmap block number */ + xfs_buf_t *bp; /* buf for the block */ + xfs_rtword_t *bufp; /* starting word in buffer */ + int error; /* error value */ + xfs_rtword_t *first; /* first used word in the buffer */ + int i; /* current bit number rel. to start */ + int lastbit; /* last useful bit in word */ + xfs_rtword_t mask; /* mask of relevant bits for value */ + int word; /* word number in the buffer */ + + /* + * Compute starting bitmap block number. + */ + block = XFS_BITTOBLOCK(mp, start); + /* + * Read the bitmap block, and point to its data. + */ + error = xfs_rtbuf_get(mp, tp, block, 0, &bp); + if (error) { + return error; + } + bufp = bp->b_addr; + /* + * Compute the starting word's address, and starting bit. + */ + word = XFS_BITTOWORD(mp, start); + first = b = &bufp[word]; + bit = (int)(start & (XFS_NBWORD - 1)); + /* + * 0 (allocated) => all zeroes; 1 (free) => all ones. + */ + val = -val; + /* + * If not starting on a word boundary, deal with the first + * (partial) word. + */ + if (bit) { + /* + * Compute first bit not changed and mask of relevant bits. + */ + lastbit = XFS_RTMIN(bit + len, XFS_NBWORD); + mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit; + /* + * Set/clear the active bits. + */ + if (val) + *b |= mask; + else + *b &= ~mask; + i = lastbit - bit; + /* + * Go on to the next block if that's where the next word is + * and we need the next word. + */ + if (++word == XFS_BLOCKWSIZE(mp) && i < len) { + /* + * Log the changed part of this block. + * Get the next one. + */ + xfs_trans_log_buf(tp, bp, + (uint)((char *)first - (char *)bufp), + (uint)((char *)b - (char *)bufp)); + error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); + if (error) { + return error; + } + first = b = bufp = bp->b_addr; + word = 0; + } else { + /* + * Go on to the next word in the buffer + */ + b++; + } + } else { + /* + * Starting on a word boundary, no partial word. + */ + i = 0; + } + /* + * Loop over whole words in buffers. When we use up one buffer + * we move on to the next one. + */ + while (len - i >= XFS_NBWORD) { + /* + * Set the word value correctly. + */ + *b = val; + i += XFS_NBWORD; + /* + * Go on to the next block if that's where the next word is + * and we need the next word. + */ + if (++word == XFS_BLOCKWSIZE(mp) && i < len) { + /* + * Log the changed part of this block. + * Get the next one. + */ + xfs_trans_log_buf(tp, bp, + (uint)((char *)first - (char *)bufp), + (uint)((char *)b - (char *)bufp)); + error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); + if (error) { + return error; + } + first = b = bufp = bp->b_addr; + word = 0; + } else { + /* + * Go on to the next word in the buffer + */ + b++; + } + } + /* + * If not ending on a word boundary, deal with the last + * (partial) word. + */ + if ((lastbit = len - i)) { + /* + * Compute a mask of relevant bits. + */ + bit = 0; + mask = ((xfs_rtword_t)1 << lastbit) - 1; + /* + * Set/clear the active bits. + */ + if (val) + *b |= mask; + else + *b &= ~mask; + b++; + } + /* + * Log any remaining changed bytes. + */ + if (b > first) + xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp), + (uint)((char *)b - (char *)bufp - 1)); + return 0; +} + +/* + * Mark an extent specified by start and len freed. + * Updates all the summary information as well as the bitmap. + */ +int +xfs_rtfree_range( + xfs_mount_t *mp, /* file system mount point */ + xfs_trans_t *tp, /* transaction pointer */ + xfs_rtblock_t start, /* starting block to free */ + xfs_extlen_t len, /* length to free */ + xfs_buf_t **rbpp, /* in/out: summary block buffer */ + xfs_fsblock_t *rsb) /* in/out: summary block number */ +{ + xfs_rtblock_t end; /* end of the freed extent */ + int error; /* error value */ + xfs_rtblock_t postblock; /* first block freed > end */ + xfs_rtblock_t preblock; /* first block freed < start */ + + end = start + len - 1; + /* + * Modify the bitmap to mark this extent freed. + */ + error = xfs_rtmodify_range(mp, tp, start, len, 1); + if (error) { + return error; + } + /* + * Assume we're freeing out of the middle of an allocated extent. + * We need to find the beginning and end of the extent so we can + * properly update the summary. + */ + error = xfs_rtfind_back(mp, tp, start, 0, &preblock); + if (error) { + return error; + } + /* + * Find the next allocated block (end of allocated extent). + */ + error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1, + &postblock); + if (error) + return error; + /* + * If there are blocks not being freed at the front of the + * old extent, add summary data for them to be allocated. + */ + if (preblock < start) { + error = xfs_rtmodify_summary(mp, tp, + XFS_RTBLOCKLOG(start - preblock), + XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb); + if (error) { + return error; + } + } + /* + * If there are blocks not being freed at the end of the + * old extent, add summary data for them to be allocated. + */ + if (postblock > end) { + error = xfs_rtmodify_summary(mp, tp, + XFS_RTBLOCKLOG(postblock - end), + XFS_BITTOBLOCK(mp, end + 1), -1, rbpp, rsb); + if (error) { + return error; + } + } + /* + * Increment the summary information corresponding to the entire + * (new) free extent. + */ + error = xfs_rtmodify_summary(mp, tp, + XFS_RTBLOCKLOG(postblock + 1 - preblock), + XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb); + return error; +} + +/* + * Check that the given range is either all allocated (val = 0) or + * all free (val = 1). + */ +int +xfs_rtcheck_range( + xfs_mount_t *mp, /* file system mount point */ + xfs_trans_t *tp, /* transaction pointer */ + xfs_rtblock_t start, /* starting block number of extent */ + xfs_extlen_t len, /* length of extent */ + int val, /* 1 for free, 0 for allocated */ + xfs_rtblock_t *new, /* out: first block not matching */ + int *stat) /* out: 1 for matches, 0 for not */ +{ + xfs_rtword_t *b; /* current word in buffer */ + int bit; /* bit number in the word */ + xfs_rtblock_t block; /* bitmap block number */ + xfs_buf_t *bp; /* buf for the block */ + xfs_rtword_t *bufp; /* starting word in buffer */ + int error; /* error value */ + xfs_rtblock_t i; /* current bit number rel. to start */ + xfs_rtblock_t lastbit; /* last useful bit in word */ + xfs_rtword_t mask; /* mask of relevant bits for value */ + xfs_rtword_t wdiff; /* difference from wanted value */ + int word; /* word number in the buffer */ + + /* + * Compute starting bitmap block number + */ + block = XFS_BITTOBLOCK(mp, start); + /* + * Read the bitmap block. + */ + error = xfs_rtbuf_get(mp, tp, block, 0, &bp); + if (error) { + return error; + } + bufp = bp->b_addr; + /* + * Compute the starting word's address, and starting bit. + */ + word = XFS_BITTOWORD(mp, start); + b = &bufp[word]; + bit = (int)(start & (XFS_NBWORD - 1)); + /* + * 0 (allocated) => all zero's; 1 (free) => all one's. + */ + val = -val; + /* + * If not starting on a word boundary, deal with the first + * (partial) word. + */ + if (bit) { + /* + * Compute first bit not examined. + */ + lastbit = XFS_RTMIN(bit + len, XFS_NBWORD); + /* + * Mask of relevant bits. + */ + mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit; + /* + * Compute difference between actual and desired value. + */ + if ((wdiff = (*b ^ val) & mask)) { + /* + * Different, compute first wrong bit and return. + */ + xfs_trans_brelse(tp, bp); + i = XFS_RTLOBIT(wdiff) - bit; + *new = start + i; + *stat = 0; + return 0; + } + i = lastbit - bit; + /* + * Go on to next block if that's where the next word is + * and we need the next word. + */ + if (++word == XFS_BLOCKWSIZE(mp) && i < len) { + /* + * If done with this block, get the next one. + */ + xfs_trans_brelse(tp, bp); + error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); + if (error) { + return error; + } + b = bufp = bp->b_addr; + word = 0; + } else { + /* + * Go on to the next word in the buffer. + */ + b++; + } + } else { + /* + * Starting on a word boundary, no partial word. + */ + i = 0; + } + /* + * Loop over whole words in buffers. When we use up one buffer + * we move on to the next one. + */ + while (len - i >= XFS_NBWORD) { + /* + * Compute difference between actual and desired value. + */ + if ((wdiff = *b ^ val)) { + /* + * Different, compute first wrong bit and return. + */ + xfs_trans_brelse(tp, bp); + i += XFS_RTLOBIT(wdiff); + *new = start + i; + *stat = 0; + return 0; + } + i += XFS_NBWORD; + /* + * Go on to next block if that's where the next word is + * and we need the next word. + */ + if (++word == XFS_BLOCKWSIZE(mp) && i < len) { + /* + * If done with this block, get the next one. + */ + xfs_trans_brelse(tp, bp); + error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); + if (error) { + return error; + } + b = bufp = bp->b_addr; + word = 0; + } else { + /* + * Go on to the next word in the buffer. + */ + b++; + } + } + /* + * If not ending on a word boundary, deal with the last + * (partial) word. + */ + if ((lastbit = len - i)) { + /* + * Mask of relevant bits. + */ + mask = ((xfs_rtword_t)1 << lastbit) - 1; + /* + * Compute difference between actual and desired value. + */ + if ((wdiff = (*b ^ val) & mask)) { + /* + * Different, compute first wrong bit and return. + */ + xfs_trans_brelse(tp, bp); + i += XFS_RTLOBIT(wdiff); + *new = start + i; + *stat = 0; + return 0; + } else + i = len; + } + /* + * Successful, return. + */ + xfs_trans_brelse(tp, bp); + *new = start + i; + *stat = 1; + return 0; +} + +#ifdef DEBUG +/* + * Check that the given extent (block range) is allocated already. + */ +STATIC int /* error */ +xfs_rtcheck_alloc_range( + xfs_mount_t *mp, /* file system mount point */ + xfs_trans_t *tp, /* transaction pointer */ + xfs_rtblock_t bno, /* starting block number of extent */ + xfs_extlen_t len) /* length of extent */ +{ + xfs_rtblock_t new; /* dummy for xfs_rtcheck_range */ + int stat; + int error; + + error = xfs_rtcheck_range(mp, tp, bno, len, 0, &new, &stat); + if (error) + return error; + ASSERT(stat); + return 0; +} +#else +#define xfs_rtcheck_alloc_range(m,t,b,l) (0) +#endif +/* + * Free an extent in the realtime subvolume. Length is expressed in + * realtime extents, as is the block number. + */ +int /* error */ +xfs_rtfree_extent( + xfs_trans_t *tp, /* transaction pointer */ + xfs_rtblock_t bno, /* starting block number to free */ + xfs_extlen_t len) /* length of extent freed */ +{ + int error; /* error value */ + xfs_mount_t *mp; /* file system mount structure */ + xfs_fsblock_t sb; /* summary file block number */ + xfs_buf_t *sumbp = NULL; /* summary file block buffer */ + + mp = tp->t_mountp; + + ASSERT(mp->m_rbmip->i_itemp != NULL); + ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL)); + + error = xfs_rtcheck_alloc_range(mp, tp, bno, len); + if (error) + return error; + + /* + * Free the range of realtime blocks. + */ + error = xfs_rtfree_range(mp, tp, bno, len, &sumbp, &sb); + if (error) { + return error; + } + /* + * Mark more blocks free in the superblock. + */ + xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, (long)len); + /* + * If we've now freed all the blocks, reset the file sequence + * number to 0. + */ + if (tp->t_frextents_delta + mp->m_sb.sb_frextents == + mp->m_sb.sb_rextents) { + if (!(mp->m_rbmip->i_d.di_flags & XFS_DIFLAG_NEWRTBM)) + mp->m_rbmip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM; + *(__uint64_t *)&mp->m_rbmip->i_d.di_atime = 0; + xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE); + } + return 0; +} + diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_sb.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_sb.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_sb.c 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_sb.c 2014-06-19 22:42:17.000000000 +0000 @@ -0,0 +1,790 @@ +/* + * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include + +/* + * Physical superblock buffer manipulations. Shared with libxfs in userspace. + */ + +static const struct { + short offset; + short type; /* 0 = integer + * 1 = binary / string (no translation) + */ +} xfs_sb_info[] = { + { offsetof(xfs_sb_t, sb_magicnum), 0 }, + { offsetof(xfs_sb_t, sb_blocksize), 0 }, + { offsetof(xfs_sb_t, sb_dblocks), 0 }, + { offsetof(xfs_sb_t, sb_rblocks), 0 }, + { offsetof(xfs_sb_t, sb_rextents), 0 }, + { offsetof(xfs_sb_t, sb_uuid), 1 }, + { offsetof(xfs_sb_t, sb_logstart), 0 }, + { offsetof(xfs_sb_t, sb_rootino), 0 }, + { offsetof(xfs_sb_t, sb_rbmino), 0 }, + { offsetof(xfs_sb_t, sb_rsumino), 0 }, + { offsetof(xfs_sb_t, sb_rextsize), 0 }, + { offsetof(xfs_sb_t, sb_agblocks), 0 }, + { offsetof(xfs_sb_t, sb_agcount), 0 }, + { offsetof(xfs_sb_t, sb_rbmblocks), 0 }, + { offsetof(xfs_sb_t, sb_logblocks), 0 }, + { offsetof(xfs_sb_t, sb_versionnum), 0 }, + { offsetof(xfs_sb_t, sb_sectsize), 0 }, + { offsetof(xfs_sb_t, sb_inodesize), 0 }, + { offsetof(xfs_sb_t, sb_inopblock), 0 }, + { offsetof(xfs_sb_t, sb_fname[0]), 1 }, + { offsetof(xfs_sb_t, sb_blocklog), 0 }, + { offsetof(xfs_sb_t, sb_sectlog), 0 }, + { offsetof(xfs_sb_t, sb_inodelog), 0 }, + { offsetof(xfs_sb_t, sb_inopblog), 0 }, + { offsetof(xfs_sb_t, sb_agblklog), 0 }, + { offsetof(xfs_sb_t, sb_rextslog), 0 }, + { offsetof(xfs_sb_t, sb_inprogress), 0 }, + { offsetof(xfs_sb_t, sb_imax_pct), 0 }, + { offsetof(xfs_sb_t, sb_icount), 0 }, + { offsetof(xfs_sb_t, sb_ifree), 0 }, + { offsetof(xfs_sb_t, sb_fdblocks), 0 }, + { offsetof(xfs_sb_t, sb_frextents), 0 }, + { offsetof(xfs_sb_t, sb_uquotino), 0 }, + { offsetof(xfs_sb_t, sb_gquotino), 0 }, + { offsetof(xfs_sb_t, sb_qflags), 0 }, + { offsetof(xfs_sb_t, sb_flags), 0 }, + { offsetof(xfs_sb_t, sb_shared_vn), 0 }, + { offsetof(xfs_sb_t, sb_inoalignmt), 0 }, + { offsetof(xfs_sb_t, sb_unit), 0 }, + { offsetof(xfs_sb_t, sb_width), 0 }, + { offsetof(xfs_sb_t, sb_dirblklog), 0 }, + { offsetof(xfs_sb_t, sb_logsectlog), 0 }, + { offsetof(xfs_sb_t, sb_logsectsize), 0 }, + { offsetof(xfs_sb_t, sb_logsunit), 0 }, + { offsetof(xfs_sb_t, sb_features2), 0 }, + { offsetof(xfs_sb_t, sb_bad_features2), 0 }, + { offsetof(xfs_sb_t, sb_features_compat), 0 }, + { offsetof(xfs_sb_t, sb_features_ro_compat), 0 }, + { offsetof(xfs_sb_t, sb_features_incompat), 0 }, + { offsetof(xfs_sb_t, sb_features_log_incompat), 0 }, + { offsetof(xfs_sb_t, sb_crc), 0 }, + { offsetof(xfs_sb_t, sb_pad), 0 }, + { offsetof(xfs_sb_t, sb_pquotino), 0 }, + { offsetof(xfs_sb_t, sb_lsn), 0 }, + { sizeof(xfs_sb_t), 0 } +}; + +/* + * Reference counting access wrappers to the perag structures. + * Because we never free per-ag structures, the only thing we + * have to protect against changes is the tree structure itself. + */ +struct xfs_perag * +xfs_perag_get( + struct xfs_mount *mp, + xfs_agnumber_t agno) +{ + struct xfs_perag *pag; + int ref = 0; + + rcu_read_lock(); + pag = radix_tree_lookup(&mp->m_perag_tree, agno); + if (pag) { + ASSERT(atomic_read(&pag->pag_ref) >= 0); + ref = atomic_inc_return(&pag->pag_ref); + } + rcu_read_unlock(); + trace_xfs_perag_get(mp, agno, ref, _RET_IP_); + return pag; +} + +/* + * search from @first to find the next perag with the given tag set. + */ +struct xfs_perag * +xfs_perag_get_tag( + struct xfs_mount *mp, + xfs_agnumber_t first, + int tag) +{ + struct xfs_perag *pag; + int found; + int ref; + + rcu_read_lock(); + found = radix_tree_gang_lookup_tag(&mp->m_perag_tree, + (void **)&pag, first, 1, tag); + if (found <= 0) { + rcu_read_unlock(); + return NULL; + } + ref = atomic_inc_return(&pag->pag_ref); + rcu_read_unlock(); + trace_xfs_perag_get_tag(mp, pag->pag_agno, ref, _RET_IP_); + return pag; +} + +void +xfs_perag_put( + struct xfs_perag *pag) +{ + int ref; + + ASSERT(atomic_read(&pag->pag_ref) > 0); + ref = atomic_dec_return(&pag->pag_ref); + trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_); +} + +/* + * Check the validity of the SB found. + */ +STATIC int +xfs_mount_validate_sb( + xfs_mount_t *mp, + xfs_sb_t *sbp, + bool check_inprogress, + bool check_version) +{ + + /* + * If the log device and data device have the + * same device number, the log is internal. + * Consequently, the sb_logstart should be non-zero. If + * we have a zero sb_logstart in this case, we may be trying to mount + * a volume filesystem in a non-volume manner. + */ + if (sbp->sb_magicnum != XFS_SB_MAGIC) { + xfs_warn(mp, "bad magic number"); + return XFS_ERROR(EWRONGFS); + } + + + if (!xfs_sb_good_version(sbp)) { + xfs_warn(mp, "bad version"); + return XFS_ERROR(EWRONGFS); + } + + /* + * Version 5 superblock feature mask validation. Reject combinations the + * kernel cannot support up front before checking anything else. For + * write validation, we don't need to check feature masks. + */ + if (check_version && XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) { + if (xfs_sb_has_compat_feature(sbp, + XFS_SB_FEAT_COMPAT_UNKNOWN)) { + xfs_warn(mp, +"Superblock has unknown compatible features (0x%x) enabled.\n" +"Using a more recent xfsprogs is recommended.", + (sbp->sb_features_compat & + XFS_SB_FEAT_COMPAT_UNKNOWN)); + } + + if (xfs_sb_has_ro_compat_feature(sbp, + XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) { + xfs_warn(mp, +"Superblock has unknown read-only compatible features (0x%x) enabled.\n" +"Using a more recent xfsprogs is recommended.", + (sbp->sb_features_ro_compat & + XFS_SB_FEAT_RO_COMPAT_UNKNOWN)); + } + if (xfs_sb_has_incompat_feature(sbp, + XFS_SB_FEAT_INCOMPAT_UNKNOWN)) { + xfs_warn(mp, +"Superblock has unknown incompatible features (0x%x) enabled.\n" +"Filesystem can not be safely operated on by this xfsprogs installation", + (sbp->sb_features_incompat & + XFS_SB_FEAT_INCOMPAT_UNKNOWN)); + return XFS_ERROR(EINVAL); + } + } + + if (xfs_sb_version_has_pquotino(sbp)) { + if (sbp->sb_qflags & (XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD)) { + xfs_notice(mp, + "Version 5 of Super block has XFS_OQUOTA bits."); + return XFS_ERROR(EFSCORRUPTED); + } + } else if (sbp->sb_qflags & (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD | + XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD)) { + xfs_notice(mp, +"Superblock earlier than Version 5 has XFS_[PQ]UOTA_{ENFD|CHKD} bits."); + return XFS_ERROR(EFSCORRUPTED); + } + + if (unlikely( + sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp)) { + xfs_warn(mp, + "filesystem is marked as having an external log; " + "specify logdev on the mount command line."); + return XFS_ERROR(EINVAL); + } + + if (unlikely( + sbp->sb_logstart != 0 && mp->m_logdev_targp != mp->m_ddev_targp)) { + xfs_warn(mp, + "filesystem is marked as having an internal log; " + "do not specify logdev on the mount command line."); + return XFS_ERROR(EINVAL); + } + + /* + * More sanity checking. Most of these were stolen directly from + * xfs_repair. + */ + if (unlikely( + sbp->sb_agcount <= 0 || + sbp->sb_sectsize < XFS_MIN_SECTORSIZE || + sbp->sb_sectsize > XFS_MAX_SECTORSIZE || + sbp->sb_sectlog < XFS_MIN_SECTORSIZE_LOG || + sbp->sb_sectlog > XFS_MAX_SECTORSIZE_LOG || + sbp->sb_sectsize != (1 << sbp->sb_sectlog) || + sbp->sb_blocksize < XFS_MIN_BLOCKSIZE || + sbp->sb_blocksize > XFS_MAX_BLOCKSIZE || + sbp->sb_blocklog < XFS_MIN_BLOCKSIZE_LOG || + sbp->sb_blocklog > XFS_MAX_BLOCKSIZE_LOG || + sbp->sb_blocksize != (1 << sbp->sb_blocklog) || + sbp->sb_inodesize < XFS_DINODE_MIN_SIZE || + sbp->sb_inodesize > XFS_DINODE_MAX_SIZE || + sbp->sb_inodelog < XFS_DINODE_MIN_LOG || + sbp->sb_inodelog > XFS_DINODE_MAX_LOG || + sbp->sb_inodesize != (1 << sbp->sb_inodelog) || + sbp->sb_inopblock != howmany(sbp->sb_blocksize,sbp->sb_inodesize) || + (sbp->sb_blocklog - sbp->sb_inodelog != sbp->sb_inopblog) || + (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) || + (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) || + (sbp->sb_imax_pct > 100 /* zero sb_imax_pct is valid */) || + sbp->sb_dblocks == 0 || + sbp->sb_dblocks > XFS_MAX_DBLOCKS(sbp) || + sbp->sb_dblocks < XFS_MIN_DBLOCKS(sbp))) { + xfs_notice(mp, "SB sanity check failed"); + return XFS_ERROR(EFSCORRUPTED); + } + + /* + * Currently only very few inode sizes are supported. + */ + switch (sbp->sb_inodesize) { + case 256: + case 512: + case 1024: + case 2048: + break; + default: + xfs_warn(mp, "inode size of %d bytes not supported", + sbp->sb_inodesize); + return XFS_ERROR(ENOSYS); + } + + if (xfs_sb_validate_fsb_count(sbp, sbp->sb_dblocks) || + xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) { + xfs_warn(mp, + "file system too large to be mounted on this system."); + return XFS_ERROR(EFBIG); + } + + /* + * Version 1 directory format has never worked on Linux. + */ + if (unlikely(!xfs_sb_version_hasdirv2(sbp))) { + xfs_warn(mp, "file system using version 1 directory format"); + return XFS_ERROR(ENOSYS); + } + + return 0; +} + +void +xfs_sb_quota_from_disk(struct xfs_sb *sbp) +{ + /* + * older mkfs doesn't initialize quota inodes to NULLFSINO. This + * leads to in-core values having two different values for a quota + * inode to be invalid: 0 and NULLFSINO. Change it to a single value + * NULLFSINO. + * + * Note that this change affect only the in-core values. These + * values are not written back to disk unless any quota information + * is written to the disk. Even in that case, sb_pquotino field is + * not written to disk unless the superblock supports pquotino. + */ + if (sbp->sb_uquotino == 0) + sbp->sb_uquotino = NULLFSINO; + if (sbp->sb_gquotino == 0) + sbp->sb_gquotino = NULLFSINO; + if (sbp->sb_pquotino == 0) + sbp->sb_pquotino = NULLFSINO; + + /* + * We need to do these manipilations only if we are working + * with an older version of on-disk superblock. + */ + if (xfs_sb_version_has_pquotino(sbp)) + return; + + if (sbp->sb_qflags & XFS_OQUOTA_ENFD) + sbp->sb_qflags |= (sbp->sb_qflags & XFS_PQUOTA_ACCT) ? + XFS_PQUOTA_ENFD : XFS_GQUOTA_ENFD; + if (sbp->sb_qflags & XFS_OQUOTA_CHKD) + sbp->sb_qflags |= (sbp->sb_qflags & XFS_PQUOTA_ACCT) ? + XFS_PQUOTA_CHKD : XFS_GQUOTA_CHKD; + sbp->sb_qflags &= ~(XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD); + + if (sbp->sb_qflags & XFS_PQUOTA_ACCT) { + /* + * In older version of superblock, on-disk superblock only + * has sb_gquotino, and in-core superblock has both sb_gquotino + * and sb_pquotino. But, only one of them is supported at any + * point of time. So, if PQUOTA is set in disk superblock, + * copy over sb_gquotino to sb_pquotino. + */ + sbp->sb_pquotino = sbp->sb_gquotino; + sbp->sb_gquotino = NULLFSINO; + } +} + +void +xfs_sb_from_disk( + struct xfs_sb *to, + xfs_dsb_t *from) +{ + to->sb_magicnum = be32_to_cpu(from->sb_magicnum); + to->sb_blocksize = be32_to_cpu(from->sb_blocksize); + to->sb_dblocks = be64_to_cpu(from->sb_dblocks); + to->sb_rblocks = be64_to_cpu(from->sb_rblocks); + to->sb_rextents = be64_to_cpu(from->sb_rextents); + memcpy(&to->sb_uuid, &from->sb_uuid, sizeof(to->sb_uuid)); + to->sb_logstart = be64_to_cpu(from->sb_logstart); + to->sb_rootino = be64_to_cpu(from->sb_rootino); + to->sb_rbmino = be64_to_cpu(from->sb_rbmino); + to->sb_rsumino = be64_to_cpu(from->sb_rsumino); + to->sb_rextsize = be32_to_cpu(from->sb_rextsize); + to->sb_agblocks = be32_to_cpu(from->sb_agblocks); + to->sb_agcount = be32_to_cpu(from->sb_agcount); + to->sb_rbmblocks = be32_to_cpu(from->sb_rbmblocks); + to->sb_logblocks = be32_to_cpu(from->sb_logblocks); + to->sb_versionnum = be16_to_cpu(from->sb_versionnum); + to->sb_sectsize = be16_to_cpu(from->sb_sectsize); + to->sb_inodesize = be16_to_cpu(from->sb_inodesize); + to->sb_inopblock = be16_to_cpu(from->sb_inopblock); + memcpy(&to->sb_fname, &from->sb_fname, sizeof(to->sb_fname)); + to->sb_blocklog = from->sb_blocklog; + to->sb_sectlog = from->sb_sectlog; + to->sb_inodelog = from->sb_inodelog; + to->sb_inopblog = from->sb_inopblog; + to->sb_agblklog = from->sb_agblklog; + to->sb_rextslog = from->sb_rextslog; + to->sb_inprogress = from->sb_inprogress; + to->sb_imax_pct = from->sb_imax_pct; + to->sb_icount = be64_to_cpu(from->sb_icount); + to->sb_ifree = be64_to_cpu(from->sb_ifree); + to->sb_fdblocks = be64_to_cpu(from->sb_fdblocks); + to->sb_frextents = be64_to_cpu(from->sb_frextents); + to->sb_uquotino = be64_to_cpu(from->sb_uquotino); + to->sb_gquotino = be64_to_cpu(from->sb_gquotino); + to->sb_qflags = be16_to_cpu(from->sb_qflags); + to->sb_flags = from->sb_flags; + to->sb_shared_vn = from->sb_shared_vn; + to->sb_inoalignmt = be32_to_cpu(from->sb_inoalignmt); + to->sb_unit = be32_to_cpu(from->sb_unit); + to->sb_width = be32_to_cpu(from->sb_width); + to->sb_dirblklog = from->sb_dirblklog; + to->sb_logsectlog = from->sb_logsectlog; + to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize); + to->sb_logsunit = be32_to_cpu(from->sb_logsunit); + to->sb_features2 = be32_to_cpu(from->sb_features2); + to->sb_bad_features2 = be32_to_cpu(from->sb_bad_features2); + to->sb_features_compat = be32_to_cpu(from->sb_features_compat); + to->sb_features_ro_compat = be32_to_cpu(from->sb_features_ro_compat); + to->sb_features_incompat = be32_to_cpu(from->sb_features_incompat); + to->sb_features_log_incompat = + be32_to_cpu(from->sb_features_log_incompat); + /* crc is only used on disk, not in memory; just init to 0 here. */ + to->sb_crc = 0; + to->sb_pad = 0; + to->sb_pquotino = be64_to_cpu(from->sb_pquotino); + to->sb_lsn = be64_to_cpu(from->sb_lsn); +} + +static inline void +xfs_sb_quota_to_disk( + xfs_dsb_t *to, + xfs_sb_t *from, + __int64_t *fields) +{ + __uint16_t qflags = from->sb_qflags; + + /* + * We need to do these manipilations only if we are working + * with an older version of on-disk superblock. + */ + if (xfs_sb_version_has_pquotino(from)) + return; + + if (*fields & XFS_SB_QFLAGS) { + /* + * The in-core version of sb_qflags do not have + * XFS_OQUOTA_* flags, whereas the on-disk version + * does. So, convert incore XFS_{PG}QUOTA_* flags + * to on-disk XFS_OQUOTA_* flags. + */ + qflags &= ~(XFS_PQUOTA_ENFD | XFS_PQUOTA_CHKD | + XFS_GQUOTA_ENFD | XFS_GQUOTA_CHKD); + + if (from->sb_qflags & + (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD)) + qflags |= XFS_OQUOTA_ENFD; + if (from->sb_qflags & + (XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD)) + qflags |= XFS_OQUOTA_CHKD; + to->sb_qflags = cpu_to_be16(qflags); + *fields &= ~XFS_SB_QFLAGS; + } + + /* + * GQUOTINO and PQUOTINO cannot be used together in versions + * of superblock that do not have pquotino. from->sb_flags + * tells us which quota is active and should be copied to + * disk. + */ + if ((*fields & XFS_SB_GQUOTINO) && + (from->sb_qflags & XFS_GQUOTA_ACCT)) + to->sb_gquotino = cpu_to_be64(from->sb_gquotino); + else if ((*fields & XFS_SB_PQUOTINO) && + (from->sb_qflags & XFS_PQUOTA_ACCT)) + to->sb_gquotino = cpu_to_be64(from->sb_pquotino); + + *fields &= ~(XFS_SB_PQUOTINO | XFS_SB_GQUOTINO); +} + +/* + * Copy in core superblock to ondisk one. + * + * The fields argument is mask of superblock fields to copy. + */ +void +xfs_sb_to_disk( + xfs_dsb_t *to, + xfs_sb_t *from, + __int64_t fields) +{ + xfs_caddr_t to_ptr = (xfs_caddr_t)to; + xfs_caddr_t from_ptr = (xfs_caddr_t)from; + xfs_sb_field_t f; + int first; + int size; + + ASSERT(fields); + if (!fields) + return; + + /* We should never write the crc here, it's updated in the IO path */ + fields &= ~XFS_SB_CRC; + + xfs_sb_quota_to_disk(to, from, &fields); + while (fields) { + f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); + first = xfs_sb_info[f].offset; + size = xfs_sb_info[f + 1].offset - first; + + ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1); + + if (size == 1 || xfs_sb_info[f].type == 1) { + memcpy(to_ptr + first, from_ptr + first, size); + } else { + switch (size) { + case 2: + *(__be16 *)(to_ptr + first) = + cpu_to_be16(*(__u16 *)(from_ptr + first)); + break; + case 4: + *(__be32 *)(to_ptr + first) = + cpu_to_be32(*(__u32 *)(from_ptr + first)); + break; + case 8: + *(__be64 *)(to_ptr + first) = + cpu_to_be64(*(__u64 *)(from_ptr + first)); + break; + default: + ASSERT(0); + } + } + + fields &= ~(1LL << f); + } +} + +static int +xfs_sb_verify( + struct xfs_buf *bp, + bool check_version) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_sb sb; + + xfs_sb_from_disk(&sb, XFS_BUF_TO_SBP(bp)); + + /* + * Only check the in progress field for the primary superblock as + * mkfs.xfs doesn't clear it from secondary superblocks. + */ + return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR, + check_version); +} + +/* + * If the superblock has the CRC feature bit set or the CRC field is non-null, + * check that the CRC is valid. We check the CRC field is non-null because a + * single bit error could clear the feature bit and unused parts of the + * superblock are supposed to be zero. Hence a non-null crc field indicates that + * we've potentially lost a feature bit and we should check it anyway. + * + * However, past bugs (i.e. in growfs) left non-zeroed regions beyond the + * last field in V4 secondary superblocks. So for secondary superblocks, + * we are more forgiving, and ignore CRC failures if the primary doesn't + * indicate that the fs version is V5. + */ +static void +xfs_sb_read_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp); + int error; + + /* + * open code the version check to avoid needing to convert the entire + * superblock from disk order just to check the version number + */ + if (dsb->sb_magicnum == cpu_to_be32(XFS_SB_MAGIC) && + (((be16_to_cpu(dsb->sb_versionnum) & XFS_SB_VERSION_NUMBITS) == + XFS_SB_VERSION_5) || + dsb->sb_crc != 0)) { + + if (!xfs_buf_verify_cksum(bp, XFS_SB_CRC_OFF)) { + /* Only fail bad secondaries on a known V5 filesystem */ + if (bp->b_bn == XFS_SB_DADDR || + xfs_sb_version_hascrc(&mp->m_sb)) { + error = EFSBADCRC; + goto out_error; + } + } + } + error = xfs_sb_verify(bp, true); + +out_error: + if (error) { + xfs_buf_ioerror(bp, error); + if (error == EFSCORRUPTED || error == EFSBADCRC) + xfs_verifier_error(bp); + } +} + +/* + * We may be probed for a filesystem match, so we may not want to emit + * messages when the superblock buffer is not actually an XFS superblock. + * If we find an XFS superblock, then run a normal, noisy mount because we are + * really going to mount it and want to know about errors. + */ +static void +xfs_sb_quiet_read_verify( + struct xfs_buf *bp) +{ + struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp); + + if (dsb->sb_magicnum == cpu_to_be32(XFS_SB_MAGIC)) { + /* XFS filesystem, verify noisily! */ + xfs_sb_read_verify(bp); + return; + } + /* quietly fail */ + xfs_buf_ioerror(bp, EWRONGFS); +} + +static void +xfs_sb_write_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_buf_log_item *bip = bp->b_fspriv; + int error; + + error = xfs_sb_verify(bp, false); + if (error) { + xfs_buf_ioerror(bp, error); + xfs_verifier_error(bp); + return; + } + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return; + + if (bip) + XFS_BUF_TO_SBP(bp)->sb_lsn = cpu_to_be64(bip->bli_item.li_lsn); + + xfs_buf_update_cksum(bp, XFS_SB_CRC_OFF); +} + +const struct xfs_buf_ops xfs_sb_buf_ops = { + .verify_read = xfs_sb_read_verify, + .verify_write = xfs_sb_write_verify, +}; + +const struct xfs_buf_ops xfs_sb_quiet_buf_ops = { + .verify_read = xfs_sb_quiet_read_verify, + .verify_write = xfs_sb_write_verify, +}; + +/* + * xfs_mount_common + * + * Mount initialization code establishing various mount + * fields from the superblock associated with the given + * mount structure + */ +void +xfs_sb_mount_common( + struct xfs_mount *mp, + struct xfs_sb *sbp) +{ + mp->m_agfrotor = mp->m_agirotor = 0; + spin_lock_init(&mp->m_agirotor_lock); + mp->m_maxagi = mp->m_sb.sb_agcount; + mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG; + mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT; + mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT; + mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1; + mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog; + mp->m_blockmask = sbp->sb_blocksize - 1; + mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; + mp->m_blockwmask = mp->m_blockwsize - 1; + + mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1); + mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0); + mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2; + mp->m_alloc_mnr[1] = mp->m_alloc_mxr[1] / 2; + + mp->m_inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 1); + mp->m_inobt_mxr[1] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 0); + mp->m_inobt_mnr[0] = mp->m_inobt_mxr[0] / 2; + mp->m_inobt_mnr[1] = mp->m_inobt_mxr[1] / 2; + + mp->m_bmap_dmxr[0] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 1); + mp->m_bmap_dmxr[1] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 0); + mp->m_bmap_dmnr[0] = mp->m_bmap_dmxr[0] / 2; + mp->m_bmap_dmnr[1] = mp->m_bmap_dmxr[1] / 2; + + mp->m_bsize = XFS_FSB_TO_BB(mp, 1); + mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK, + sbp->sb_inopblock); + mp->m_ialloc_blks = mp->m_ialloc_inos >> sbp->sb_inopblog; +} + +/* + * xfs_initialize_perag_data + * + * Read in each per-ag structure so we can count up the number of + * allocated inodes, free inodes and used filesystem blocks as this + * information is no longer persistent in the superblock. Once we have + * this information, write it into the in-core superblock structure. + */ +int +xfs_initialize_perag_data( + struct xfs_mount *mp, + xfs_agnumber_t agcount) +{ + xfs_agnumber_t index; + xfs_perag_t *pag; + xfs_sb_t *sbp = &mp->m_sb; + uint64_t ifree = 0; + uint64_t ialloc = 0; + uint64_t bfree = 0; + uint64_t bfreelst = 0; + uint64_t btree = 0; + int error; + + for (index = 0; index < agcount; index++) { + /* + * read the agf, then the agi. This gets us + * all the information we need and populates the + * per-ag structures for us. + */ + error = xfs_alloc_pagf_init(mp, NULL, index, 0); + if (error) + return error; + + error = xfs_ialloc_pagi_init(mp, NULL, index); + if (error) + return error; + pag = xfs_perag_get(mp, index); + ifree += pag->pagi_freecount; + ialloc += pag->pagi_count; + bfree += pag->pagf_freeblks; + bfreelst += pag->pagf_flcount; + btree += pag->pagf_btreeblks; + xfs_perag_put(pag); + } + /* + * Overwrite incore superblock counters with just-read data + */ + spin_lock(&mp->m_sb_lock); + sbp->sb_ifree = ifree; + sbp->sb_icount = ialloc; + sbp->sb_fdblocks = bfree + bfreelst + btree; + spin_unlock(&mp->m_sb_lock); + + /* Fixup the per-cpu counters as well. */ + xfs_icsb_reinit_counters(mp); + + return 0; +} + +/* + * xfs_mod_sb() can be used to copy arbitrary changes to the + * in-core superblock into the superblock buffer to be logged. + * It does not provide the higher level of locking that is + * needed to protect the in-core superblock from concurrent + * access. + */ +void +xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) +{ + xfs_buf_t *bp; + int first; + int last; + xfs_mount_t *mp; + xfs_sb_field_t f; + + ASSERT(fields); + if (!fields) + return; + mp = tp->t_mountp; + bp = xfs_trans_getsb(tp, mp, 0); + first = sizeof(xfs_sb_t); + last = 0; + + /* translate/copy */ + + xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields); + + /* find modified range */ + f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields); + ASSERT((1LL << f) & XFS_SB_MOD_BITS); + last = xfs_sb_info[f + 1].offset - 1; + + f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); + ASSERT((1LL << f) & XFS_SB_MOD_BITS); + first = xfs_sb_info[f].offset; + + xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); + xfs_trans_log_buf(tp, bp, first, last); +} diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_symlink_remote.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_symlink_remote.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_symlink_remote.c 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_symlink_remote.c 2014-05-02 00:09:16.000000000 +0000 @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2000-2006 Silicon Graphics, Inc. + * Copyright (c) 2012-2013 Red Hat, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include + +/* + * Each contiguous block has a header, so it is not just a simple pathlen + * to FSB conversion. + */ +int +xfs_symlink_blocks( + struct xfs_mount *mp, + int pathlen) +{ + int buflen = XFS_SYMLINK_BUF_SPACE(mp, mp->m_sb.sb_blocksize); + + return (pathlen + buflen - 1) / buflen; +} + +int +xfs_symlink_hdr_set( + struct xfs_mount *mp, + xfs_ino_t ino, + uint32_t offset, + uint32_t size, + struct xfs_buf *bp) +{ + struct xfs_dsymlink_hdr *dsl = bp->b_addr; + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return 0; + + dsl->sl_magic = cpu_to_be32(XFS_SYMLINK_MAGIC); + dsl->sl_offset = cpu_to_be32(offset); + dsl->sl_bytes = cpu_to_be32(size); + uuid_copy(&dsl->sl_uuid, &mp->m_sb.sb_uuid); + dsl->sl_owner = cpu_to_be64(ino); + dsl->sl_blkno = cpu_to_be64(bp->b_bn); + bp->b_ops = &xfs_symlink_buf_ops; + + return sizeof(struct xfs_dsymlink_hdr); +} + +/* + * Checking of the symlink header is split into two parts. the verifier does + * CRC, location and bounds checking, the unpacking function checks the path + * parameters and owner. + */ +bool +xfs_symlink_hdr_ok( + struct xfs_mount *mp, + xfs_ino_t ino, + uint32_t offset, + uint32_t size, + struct xfs_buf *bp) +{ + struct xfs_dsymlink_hdr *dsl = bp->b_addr; + + if (offset != be32_to_cpu(dsl->sl_offset)) + return false; + if (size != be32_to_cpu(dsl->sl_bytes)) + return false; + if (ino != be64_to_cpu(dsl->sl_owner)) + return false; + + /* ok */ + return true; +} + +static bool +xfs_symlink_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_dsymlink_hdr *dsl = bp->b_addr; + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return false; + if (dsl->sl_magic != cpu_to_be32(XFS_SYMLINK_MAGIC)) + return false; + if (!uuid_equal(&dsl->sl_uuid, &mp->m_sb.sb_uuid)) + return false; + if (bp->b_bn != be64_to_cpu(dsl->sl_blkno)) + return false; + if (be32_to_cpu(dsl->sl_offset) + + be32_to_cpu(dsl->sl_bytes) >= MAXPATHLEN) + return false; + if (dsl->sl_owner == 0) + return false; + + return true; +} + +static void +xfs_symlink_read_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + + /* no verification of non-crc buffers */ + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return; + + if (!xfs_buf_verify_cksum(bp, XFS_SYMLINK_CRC_OFF)) + xfs_buf_ioerror(bp, EFSBADCRC); + else if (!xfs_symlink_verify(bp)) + xfs_buf_ioerror(bp, EFSCORRUPTED); + + if (bp->b_error) + xfs_verifier_error(bp); +} + +static void +xfs_symlink_write_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_buf_log_item *bip = bp->b_fspriv; + + /* no verification of non-crc buffers */ + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return; + + if (!xfs_symlink_verify(bp)) { + xfs_buf_ioerror(bp, EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + + if (bip) { + struct xfs_dsymlink_hdr *dsl = bp->b_addr; + dsl->sl_lsn = cpu_to_be64(bip->bli_item.li_lsn); + } + xfs_buf_update_cksum(bp, XFS_SYMLINK_CRC_OFF); +} + +const struct xfs_buf_ops xfs_symlink_buf_ops = { + .verify_read = xfs_symlink_read_verify, + .verify_write = xfs_symlink_write_verify, +}; + +void +xfs_symlink_local_to_remote( + struct xfs_trans *tp, + struct xfs_buf *bp, + struct xfs_inode *ip, + struct xfs_ifork *ifp) +{ + struct xfs_mount *mp = ip->i_mount; + char *buf; + + if (!xfs_sb_version_hascrc(&mp->m_sb)) { + bp->b_ops = NULL; + memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes); + return; + } + + /* + * As this symlink fits in an inode literal area, it must also fit in + * the smallest buffer the filesystem supports. + */ + ASSERT(BBTOB(bp->b_length) >= + ifp->if_bytes + sizeof(struct xfs_dsymlink_hdr)); + + bp->b_ops = &xfs_symlink_buf_ops; + + buf = bp->b_addr; + buf += xfs_symlink_hdr_set(mp, ip->i_ino, 0, ifp->if_bytes, bp); + memcpy(buf, ifp->if_u1.if_data, ifp->if_bytes); +} diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_trans.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_trans.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_trans.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_trans.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,648 +0,0 @@ -/* - * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. - * Copyright (C) 2010 Red Hat, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -kmem_zone_t *xfs_trans_zone; -kmem_zone_t *xfs_log_item_desc_zone; - -/* - * Various log reservation values. - * - * These are based on the size of the file system block because that is what - * most transactions manipulate. Each adds in an additional 128 bytes per - * item logged to try to account for the overhead of the transaction mechanism. - * - * Note: Most of the reservations underestimate the number of allocation - * groups into which they could free extents in the xfs_bmap_finish() call. - * This is because the number in the worst case is quite high and quite - * unusual. In order to fix this we need to change xfs_bmap_finish() to free - * extents in only a single AG at a time. This will require changes to the - * EFI code as well, however, so that the EFI for the extents not freed is - * logged again in each transaction. See SGI PV #261917. - * - * Reservation functions here avoid a huge stack in xfs_trans_init due to - * register overflow from temporaries in the calculations. - */ - - -/* - * In a write transaction we can allocate a maximum of 2 - * extents. This gives: - * the inode getting the new extents: inode size - * the inode's bmap btree: max depth * block size - * the agfs of the ags from which the extents are allocated: 2 * sector - * the superblock free block counter: sector size - * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size - * And the bmap_finish transaction can free bmap blocks in a join: - * the agfs of the ags containing the blocks: 2 * sector size - * the agfls of the ags containing the blocks: 2 * sector size - * the super block free block counter: sector size - * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size - */ -STATIC uint -xfs_calc_write_reservation( - struct xfs_mount *mp) -{ - return XFS_DQUOT_LOGRES(mp) + - MAX((mp->m_sb.sb_inodesize + - XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + - 2 * mp->m_sb.sb_sectsize + - mp->m_sb.sb_sectsize + - XFS_ALLOCFREE_LOG_RES(mp, 2) + - 128 * (4 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + - XFS_ALLOCFREE_LOG_COUNT(mp, 2))), - (2 * mp->m_sb.sb_sectsize + - 2 * mp->m_sb.sb_sectsize + - mp->m_sb.sb_sectsize + - XFS_ALLOCFREE_LOG_RES(mp, 2) + - 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))); -} - -/* - * In truncating a file we free up to two extents at once. We can modify: - * the inode being truncated: inode size - * the inode's bmap btree: (max depth + 1) * block size - * And the bmap_finish transaction can free the blocks and bmap blocks: - * the agf for each of the ags: 4 * sector size - * the agfl for each of the ags: 4 * sector size - * the super block to reflect the freed blocks: sector size - * worst case split in allocation btrees per extent assuming 4 extents: - * 4 exts * 2 trees * (2 * max depth - 1) * block size - * the inode btree: max depth * blocksize - * the allocation btrees: 2 trees * (max depth - 1) * block size - */ -STATIC uint -xfs_calc_itruncate_reservation( - struct xfs_mount *mp) -{ - return XFS_DQUOT_LOGRES(mp) + - MAX((mp->m_sb.sb_inodesize + - XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1) + - 128 * (2 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK))), - (4 * mp->m_sb.sb_sectsize + - 4 * mp->m_sb.sb_sectsize + - mp->m_sb.sb_sectsize + - XFS_ALLOCFREE_LOG_RES(mp, 4) + - 128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4)) + - 128 * 5 + - XFS_ALLOCFREE_LOG_RES(mp, 1) + - 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels + - XFS_ALLOCFREE_LOG_COUNT(mp, 1)))); -} - -/* - * In renaming a files we can modify: - * the four inodes involved: 4 * inode size - * the two directory btrees: 2 * (max depth + v2) * dir block size - * the two directory bmap btrees: 2 * max depth * block size - * And the bmap_finish transaction can free dir and bmap blocks (two sets - * of bmap blocks) giving: - * the agf for the ags in which the blocks live: 3 * sector size - * the agfl for the ags in which the blocks live: 3 * sector size - * the superblock for the free block count: sector size - * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size - */ -STATIC uint -xfs_calc_rename_reservation( - struct xfs_mount *mp) -{ - return XFS_DQUOT_LOGRES(mp) + - MAX((4 * mp->m_sb.sb_inodesize + - 2 * XFS_DIROP_LOG_RES(mp) + - 128 * (4 + 2 * XFS_DIROP_LOG_COUNT(mp))), - (3 * mp->m_sb.sb_sectsize + - 3 * mp->m_sb.sb_sectsize + - mp->m_sb.sb_sectsize + - XFS_ALLOCFREE_LOG_RES(mp, 3) + - 128 * (7 + XFS_ALLOCFREE_LOG_COUNT(mp, 3)))); -} - -/* - * For creating a link to an inode: - * the parent directory inode: inode size - * the linked inode: inode size - * the directory btree could split: (max depth + v2) * dir block size - * the directory bmap btree could join or split: (max depth + v2) * blocksize - * And the bmap_finish transaction can free some bmap blocks giving: - * the agf for the ag in which the blocks live: sector size - * the agfl for the ag in which the blocks live: sector size - * the superblock for the free block count: sector size - * the allocation btrees: 2 trees * (2 * max depth - 1) * block size - */ -STATIC uint -xfs_calc_link_reservation( - struct xfs_mount *mp) -{ - return XFS_DQUOT_LOGRES(mp) + - MAX((mp->m_sb.sb_inodesize + - mp->m_sb.sb_inodesize + - XFS_DIROP_LOG_RES(mp) + - 128 * (2 + XFS_DIROP_LOG_COUNT(mp))), - (mp->m_sb.sb_sectsize + - mp->m_sb.sb_sectsize + - mp->m_sb.sb_sectsize + - XFS_ALLOCFREE_LOG_RES(mp, 1) + - 128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))); -} - -/* - * For removing a directory entry we can modify: - * the parent directory inode: inode size - * the removed inode: inode size - * the directory btree could join: (max depth + v2) * dir block size - * the directory bmap btree could join or split: (max depth + v2) * blocksize - * And the bmap_finish transaction can free the dir and bmap blocks giving: - * the agf for the ag in which the blocks live: 2 * sector size - * the agfl for the ag in which the blocks live: 2 * sector size - * the superblock for the free block count: sector size - * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size - */ -STATIC uint -xfs_calc_remove_reservation( - struct xfs_mount *mp) -{ - return XFS_DQUOT_LOGRES(mp) + - MAX((mp->m_sb.sb_inodesize + - mp->m_sb.sb_inodesize + - XFS_DIROP_LOG_RES(mp) + - 128 * (2 + XFS_DIROP_LOG_COUNT(mp))), - (2 * mp->m_sb.sb_sectsize + - 2 * mp->m_sb.sb_sectsize + - mp->m_sb.sb_sectsize + - XFS_ALLOCFREE_LOG_RES(mp, 2) + - 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))); -} - -/* - * For symlink we can modify: - * the parent directory inode: inode size - * the new inode: inode size - * the inode btree entry: 1 block - * the directory btree: (max depth + v2) * dir block size - * the directory inode's bmap btree: (max depth + v2) * block size - * the blocks for the symlink: 1 kB - * Or in the first xact we allocate some inodes giving: - * the agi and agf of the ag getting the new inodes: 2 * sectorsize - * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize - * the inode btree: max depth * blocksize - * the allocation btrees: 2 trees * (2 * max depth - 1) * block size - */ -STATIC uint -xfs_calc_symlink_reservation( - struct xfs_mount *mp) -{ - return XFS_DQUOT_LOGRES(mp) + - MAX((mp->m_sb.sb_inodesize + - mp->m_sb.sb_inodesize + - XFS_FSB_TO_B(mp, 1) + - XFS_DIROP_LOG_RES(mp) + - 1024 + - 128 * (4 + XFS_DIROP_LOG_COUNT(mp))), - (2 * mp->m_sb.sb_sectsize + - XFS_FSB_TO_B(mp, XFS_IALLOC_BLOCKS(mp)) + - XFS_FSB_TO_B(mp, mp->m_in_maxlevels) + - XFS_ALLOCFREE_LOG_RES(mp, 1) + - 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels + - XFS_ALLOCFREE_LOG_COUNT(mp, 1)))); -} - -/* - * For create we can modify: - * the parent directory inode: inode size - * the new inode: inode size - * the inode btree entry: block size - * the superblock for the nlink flag: sector size - * the directory btree: (max depth + v2) * dir block size - * the directory inode's bmap btree: (max depth + v2) * block size - * Or in the first xact we allocate some inodes giving: - * the agi and agf of the ag getting the new inodes: 2 * sectorsize - * the superblock for the nlink flag: sector size - * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize - * the inode btree: max depth * blocksize - * the allocation btrees: 2 trees * (max depth - 1) * block size - */ -STATIC uint -xfs_calc_create_reservation( - struct xfs_mount *mp) -{ - return XFS_DQUOT_LOGRES(mp) + - MAX((mp->m_sb.sb_inodesize + - mp->m_sb.sb_inodesize + - mp->m_sb.sb_sectsize + - XFS_FSB_TO_B(mp, 1) + - XFS_DIROP_LOG_RES(mp) + - 128 * (3 + XFS_DIROP_LOG_COUNT(mp))), - (3 * mp->m_sb.sb_sectsize + - XFS_FSB_TO_B(mp, XFS_IALLOC_BLOCKS(mp)) + - XFS_FSB_TO_B(mp, mp->m_in_maxlevels) + - XFS_ALLOCFREE_LOG_RES(mp, 1) + - 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels + - XFS_ALLOCFREE_LOG_COUNT(mp, 1)))); -} - -/* - * Making a new directory is the same as creating a new file. - */ -STATIC uint -xfs_calc_mkdir_reservation( - struct xfs_mount *mp) -{ - return xfs_calc_create_reservation(mp); -} - -/* - * In freeing an inode we can modify: - * the inode being freed: inode size - * the super block free inode counter: sector size - * the agi hash list and counters: sector size - * the inode btree entry: block size - * the on disk inode before ours in the agi hash list: inode cluster size - * the inode btree: max depth * blocksize - * the allocation btrees: 2 trees * (max depth - 1) * block size - */ -STATIC uint -xfs_calc_ifree_reservation( - struct xfs_mount *mp) -{ - return XFS_DQUOT_LOGRES(mp) + - mp->m_sb.sb_inodesize + - mp->m_sb.sb_sectsize + - mp->m_sb.sb_sectsize + - XFS_FSB_TO_B(mp, 1) + - MAX((__uint16_t)XFS_FSB_TO_B(mp, 1), - XFS_INODE_CLUSTER_SIZE(mp)) + - 128 * 5 + - XFS_ALLOCFREE_LOG_RES(mp, 1) + - 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels + - XFS_ALLOCFREE_LOG_COUNT(mp, 1)); -} - -/* - * When only changing the inode we log the inode and possibly the superblock - * We also add a bit of slop for the transaction stuff. - */ -STATIC uint -xfs_calc_ichange_reservation( - struct xfs_mount *mp) -{ - return XFS_DQUOT_LOGRES(mp) + - mp->m_sb.sb_inodesize + - mp->m_sb.sb_sectsize + - 512; - -} - -/* - * Growing the data section of the filesystem. - * superblock - * agi and agf - * allocation btrees - */ -STATIC uint -xfs_calc_growdata_reservation( - struct xfs_mount *mp) -{ - return mp->m_sb.sb_sectsize * 3 + - XFS_ALLOCFREE_LOG_RES(mp, 1) + - 128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1)); -} - -/* - * Growing the rt section of the filesystem. - * In the first set of transactions (ALLOC) we allocate space to the - * bitmap or summary files. - * superblock: sector size - * agf of the ag from which the extent is allocated: sector size - * bmap btree for bitmap/summary inode: max depth * blocksize - * bitmap/summary inode: inode size - * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize - */ -STATIC uint -xfs_calc_growrtalloc_reservation( - struct xfs_mount *mp) -{ - return 2 * mp->m_sb.sb_sectsize + - XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + - mp->m_sb.sb_inodesize + - XFS_ALLOCFREE_LOG_RES(mp, 1) + - 128 * (3 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + - XFS_ALLOCFREE_LOG_COUNT(mp, 1)); -} - -/* - * Growing the rt section of the filesystem. - * In the second set of transactions (ZERO) we zero the new metadata blocks. - * one bitmap/summary block: blocksize - */ -STATIC uint -xfs_calc_growrtzero_reservation( - struct xfs_mount *mp) -{ - return mp->m_sb.sb_blocksize + 128; -} - -/* - * Growing the rt section of the filesystem. - * In the third set of transactions (FREE) we update metadata without - * allocating any new blocks. - * superblock: sector size - * bitmap inode: inode size - * summary inode: inode size - * one bitmap block: blocksize - * summary blocks: new summary size - */ -STATIC uint -xfs_calc_growrtfree_reservation( - struct xfs_mount *mp) -{ - return mp->m_sb.sb_sectsize + - 2 * mp->m_sb.sb_inodesize + - mp->m_sb.sb_blocksize + - mp->m_rsumsize + - 128 * 5; -} - -/* - * Logging the inode modification timestamp on a synchronous write. - * inode - */ -STATIC uint -xfs_calc_swrite_reservation( - struct xfs_mount *mp) -{ - return mp->m_sb.sb_inodesize + 128; -} - -/* - * Logging the inode mode bits when writing a setuid/setgid file - * inode - */ -STATIC uint -xfs_calc_writeid_reservation(xfs_mount_t *mp) -{ - return mp->m_sb.sb_inodesize + 128; -} - -/* - * Converting the inode from non-attributed to attributed. - * the inode being converted: inode size - * agf block and superblock (for block allocation) - * the new block (directory sized) - * bmap blocks for the new directory block - * allocation btrees - */ -STATIC uint -xfs_calc_addafork_reservation( - struct xfs_mount *mp) -{ - return XFS_DQUOT_LOGRES(mp) + - mp->m_sb.sb_inodesize + - mp->m_sb.sb_sectsize * 2 + - mp->m_dirblksize + - XFS_FSB_TO_B(mp, XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + - XFS_ALLOCFREE_LOG_RES(mp, 1) + - 128 * (4 + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1 + - XFS_ALLOCFREE_LOG_COUNT(mp, 1)); -} - -/* - * Removing the attribute fork of a file - * the inode being truncated: inode size - * the inode's bmap btree: max depth * block size - * And the bmap_finish transaction can free the blocks and bmap blocks: - * the agf for each of the ags: 4 * sector size - * the agfl for each of the ags: 4 * sector size - * the super block to reflect the freed blocks: sector size - * worst case split in allocation btrees per extent assuming 4 extents: - * 4 exts * 2 trees * (2 * max depth - 1) * block size - */ -STATIC uint -xfs_calc_attrinval_reservation( - struct xfs_mount *mp) -{ - return MAX((mp->m_sb.sb_inodesize + - XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + - 128 * (1 + XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))), - (4 * mp->m_sb.sb_sectsize + - 4 * mp->m_sb.sb_sectsize + - mp->m_sb.sb_sectsize + - XFS_ALLOCFREE_LOG_RES(mp, 4) + - 128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4)))); -} - -/* - * Setting an attribute. - * the inode getting the attribute - * the superblock for allocations - * the agfs extents are allocated from - * the attribute btree * max depth - * the inode allocation btree - * Since attribute transaction space is dependent on the size of the attribute, - * the calculation is done partially at mount time and partially at runtime. - */ -STATIC uint -xfs_calc_attrset_reservation( - struct xfs_mount *mp) -{ - return XFS_DQUOT_LOGRES(mp) + - mp->m_sb.sb_inodesize + - mp->m_sb.sb_sectsize + - XFS_FSB_TO_B(mp, XFS_DA_NODE_MAXDEPTH) + - 128 * (2 + XFS_DA_NODE_MAXDEPTH); -} - -/* - * Removing an attribute. - * the inode: inode size - * the attribute btree could join: max depth * block size - * the inode bmap btree could join or split: max depth * block size - * And the bmap_finish transaction can free the attr blocks freed giving: - * the agf for the ag in which the blocks live: 2 * sector size - * the agfl for the ag in which the blocks live: 2 * sector size - * the superblock for the free block count: sector size - * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size - */ -STATIC uint -xfs_calc_attrrm_reservation( - struct xfs_mount *mp) -{ - return XFS_DQUOT_LOGRES(mp) + - MAX((mp->m_sb.sb_inodesize + - XFS_FSB_TO_B(mp, XFS_DA_NODE_MAXDEPTH) + - XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + - 128 * (1 + XFS_DA_NODE_MAXDEPTH + - XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK))), - (2 * mp->m_sb.sb_sectsize + - 2 * mp->m_sb.sb_sectsize + - mp->m_sb.sb_sectsize + - XFS_ALLOCFREE_LOG_RES(mp, 2) + - 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))); -} - -/* - * Clearing a bad agino number in an agi hash bucket. - */ -STATIC uint -xfs_calc_clear_agi_bucket_reservation( - struct xfs_mount *mp) -{ - return mp->m_sb.sb_sectsize + 128; -} - -/* - * Initialize the precomputed transaction reservation values - * in the mount structure. - */ -void -xfs_trans_init( - struct xfs_mount *mp) -{ - struct xfs_trans_reservations *resp = &mp->m_reservations; - - resp->tr_write = xfs_calc_write_reservation(mp); - resp->tr_itruncate = xfs_calc_itruncate_reservation(mp); - resp->tr_rename = xfs_calc_rename_reservation(mp); - resp->tr_link = xfs_calc_link_reservation(mp); - resp->tr_remove = xfs_calc_remove_reservation(mp); - resp->tr_symlink = xfs_calc_symlink_reservation(mp); - resp->tr_create = xfs_calc_create_reservation(mp); - resp->tr_mkdir = xfs_calc_mkdir_reservation(mp); - resp->tr_ifree = xfs_calc_ifree_reservation(mp); - resp->tr_ichange = xfs_calc_ichange_reservation(mp); - resp->tr_growdata = xfs_calc_growdata_reservation(mp); - resp->tr_swrite = xfs_calc_swrite_reservation(mp); - resp->tr_writeid = xfs_calc_writeid_reservation(mp); - resp->tr_addafork = xfs_calc_addafork_reservation(mp); - resp->tr_attrinval = xfs_calc_attrinval_reservation(mp); - resp->tr_attrset = xfs_calc_attrset_reservation(mp); - resp->tr_attrrm = xfs_calc_attrrm_reservation(mp); - resp->tr_clearagi = xfs_calc_clear_agi_bucket_reservation(mp); - resp->tr_growrtalloc = xfs_calc_growrtalloc_reservation(mp); - resp->tr_growrtzero = xfs_calc_growrtzero_reservation(mp); - resp->tr_growrtfree = xfs_calc_growrtfree_reservation(mp); -} - -/* - * Add the given log item to the transaction's list of log items. - * - * The log item will now point to its new descriptor with its li_desc field. - */ -void -xfs_trans_add_item( - struct xfs_trans *tp, - struct xfs_log_item *lip) -{ - struct xfs_log_item_desc *lidp; - - ASSERT(lip->li_mountp = tp->t_mountp); - ASSERT(lip->li_ailp = tp->t_mountp->m_ail); - - lidp = kmem_zone_zalloc(xfs_log_item_desc_zone, KM_SLEEP | KM_NOFS); - - lidp->lid_item = lip; - lidp->lid_flags = 0; - lidp->lid_size = 0; - list_add_tail(&lidp->lid_trans, &tp->t_items); - - lip->li_desc = lidp; -} - -STATIC void -xfs_trans_free_item_desc( - struct xfs_log_item_desc *lidp) -{ - list_del_init(&lidp->lid_trans); - kmem_zone_free(xfs_log_item_desc_zone, lidp); -} - -/* - * Unlink and free the given descriptor. - */ -void -xfs_trans_del_item( - struct xfs_log_item *lip) -{ - xfs_trans_free_item_desc(lip->li_desc); - lip->li_desc = NULL; -} - -/* - * Roll from one trans in the sequence of PERMANENT transactions to - * the next: permanent transactions are only flushed out when - * committed with XFS_TRANS_RELEASE_LOG_RES, but we still want as soon - * as possible to let chunks of it go to the log. So we commit the - * chunk we've been working on and get a new transaction to continue. - */ -int -xfs_trans_roll( - struct xfs_trans **tpp, - struct xfs_inode *dp) -{ - struct xfs_trans *trans; - unsigned int logres, count; - int error; - - /* - * Ensure that the inode is always logged. - */ - trans = *tpp; - xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE); - - /* - * Copy the critical parameters from one trans to the next. - */ - logres = trans->t_log_res; - count = trans->t_log_count; - *tpp = xfs_trans_dup(trans); - - /* - * Commit the current transaction. - * If this commit failed, then it'd just unlock those items that - * are not marked ihold. That also means that a filesystem shutdown - * is in progress. The caller takes the responsibility to cancel - * the duplicate transaction that gets returned. - */ - error = xfs_trans_commit(trans, 0); - if (error) - return (error); - - trans = *tpp; - - /* - * Reserve space in the log for th next transaction. - * This also pushes items in the "AIL", the list of logged items, - * out to disk if they are taking up space at the tail of the log - * that we want to use. This requires that either nothing be locked - * across this call, or that anything that is locked be logged in - * the prior and the next transactions. - */ - error = xfs_trans_reserve(trans, 0, logres, 0, - XFS_TRANS_PERM_LOG_RES, count); - /* - * Ensure that the inode is in the new transaction and locked. - */ - if (error) - return error; - - xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL); - xfs_trans_ihold(trans, dp); - return 0; -} - diff -Nru xfsprogs-3.1.9ubuntu2/libxfs/xfs_trans_resv.c xfsprogs-3.2.1ubuntu1/libxfs/xfs_trans_resv.c --- xfsprogs-3.1.9ubuntu2/libxfs/xfs_trans_resv.c 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxfs/xfs_trans_resv.c 2014-06-19 22:42:17.000000000 +0000 @@ -0,0 +1,817 @@ +/* + * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. + * Copyright (C) 2010 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include + +/* + * A buffer has a format structure overhead in the log in addition + * to the data, so we need to take this into account when reserving + * space in a transaction for a buffer. Round the space required up + * to a multiple of 128 bytes so that we don't change the historical + * reservation that has been used for this overhead. + */ +STATIC uint +xfs_buf_log_overhead(void) +{ + return round_up(sizeof(struct xlog_op_header) + + sizeof(struct xfs_buf_log_format), 128); +} + +/* + * Calculate out transaction log reservation per item in bytes. + * + * The nbufs argument is used to indicate the number of items that + * will be changed in a transaction. size is used to tell how many + * bytes should be reserved per item. + */ +STATIC uint +xfs_calc_buf_res( + uint nbufs, + uint size) +{ + return nbufs * (size + xfs_buf_log_overhead()); +} + +/* + * Logging inodes is really tricksy. They are logged in memory format, + * which means that what we write into the log doesn't directly translate into + * the amount of space they use on disk. + * + * Case in point - btree format forks in memory format use more space than the + * on-disk format. In memory, the buffer contains a normal btree block header so + * the btree code can treat it as though it is just another generic buffer. + * However, when we write it to the inode fork, we don't write all of this + * header as it isn't needed. e.g. the root is only ever in the inode, so + * there's no need for sibling pointers which would waste 16 bytes of space. + * + * Hence when we have an inode with a maximally sized btree format fork, then + * amount of information we actually log is greater than the size of the inode + * on disk. Hence we need an inode reservation function that calculates all this + * correctly. So, we log: + * + * - log op headers for object + * - inode log format object + * - the entire inode contents (core + 2 forks) + * - two bmap btree block headers + */ +STATIC uint +xfs_calc_inode_res( + struct xfs_mount *mp, + uint ninodes) +{ + return ninodes * (sizeof(struct xlog_op_header) + + sizeof(struct xfs_inode_log_format) + + mp->m_sb.sb_inodesize + + 2 * XFS_BMBT_BLOCK_LEN(mp)); +} + +/* + * The free inode btree is a conditional feature and the log reservation + * requirements differ slightly from that of the traditional inode allocation + * btree. The finobt tracks records for inode chunks with at least one free inode. + * Therefore, a record can be removed from the tree for an inode allocation or + * free and the associated merge reservation is unconditional. This also covers + * the possibility of a split on record insertion. + * + * the free inode btree: max depth * block size + * the free inode btree entry: block size + * + * TODO: is the modify res really necessary? covered by the merge/split res? + * This seems to be the pattern of ifree, but not create_resv_alloc. Why? + */ +STATIC uint +xfs_calc_finobt_res( + struct xfs_mount *mp, + int modify) +{ + uint res; + + if (!xfs_sb_version_hasfinobt(&mp->m_sb)) + return 0; + + res = xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)); + if (modify) + res += (uint)XFS_FSB_TO_B(mp, 1); + + return res; +} + +/* + * Various log reservation values. + * + * These are based on the size of the file system block because that is what + * most transactions manipulate. Each adds in an additional 128 bytes per + * item logged to try to account for the overhead of the transaction mechanism. + * + * Note: Most of the reservations underestimate the number of allocation + * groups into which they could free extents in the xfs_bmap_finish() call. + * This is because the number in the worst case is quite high and quite + * unusual. In order to fix this we need to change xfs_bmap_finish() to free + * extents in only a single AG at a time. This will require changes to the + * EFI code as well, however, so that the EFI for the extents not freed is + * logged again in each transaction. See SGI PV #261917. + * + * Reservation functions here avoid a huge stack in xfs_trans_init due to + * register overflow from temporaries in the calculations. + */ + + +/* + * In a write transaction we can allocate a maximum of 2 + * extents. This gives: + * the inode getting the new extents: inode size + * the inode's bmap btree: max depth * block size + * the agfs of the ags from which the extents are allocated: 2 * sector + * the superblock free block counter: sector size + * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size + * And the bmap_finish transaction can free bmap blocks in a join: + * the agfs of the ags containing the blocks: 2 * sector size + * the agfls of the ags containing the blocks: 2 * sector size + * the super block free block counter: sector size + * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size + */ +STATIC uint +xfs_calc_write_reservation( + struct xfs_mount *mp) +{ + return XFS_DQUOT_LOGRES(mp) + + MAX((xfs_calc_inode_res(mp, 1) + + xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), + XFS_FSB_TO_B(mp, 1)) + + xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), + XFS_FSB_TO_B(mp, 1))), + (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), + XFS_FSB_TO_B(mp, 1)))); +} + +/* + * In truncating a file we free up to two extents at once. We can modify: + * the inode being truncated: inode size + * the inode's bmap btree: (max depth + 1) * block size + * And the bmap_finish transaction can free the blocks and bmap blocks: + * the agf for each of the ags: 4 * sector size + * the agfl for each of the ags: 4 * sector size + * the super block to reflect the freed blocks: sector size + * worst case split in allocation btrees per extent assuming 4 extents: + * 4 exts * 2 trees * (2 * max depth - 1) * block size + * the inode btree: max depth * blocksize + * the allocation btrees: 2 trees * (max depth - 1) * block size + */ +STATIC uint +xfs_calc_itruncate_reservation( + struct xfs_mount *mp) +{ + return XFS_DQUOT_LOGRES(mp) + + MAX((xfs_calc_inode_res(mp, 1) + + xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1, + XFS_FSB_TO_B(mp, 1))), + (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 4), + XFS_FSB_TO_B(mp, 1)) + + xfs_calc_buf_res(5, 0) + + xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + XFS_FSB_TO_B(mp, 1)) + + xfs_calc_buf_res(2 + XFS_IALLOC_BLOCKS(mp) + + mp->m_in_maxlevels, 0))); +} + +/* + * In renaming a files we can modify: + * the four inodes involved: 4 * inode size + * the two directory btrees: 2 * (max depth + v2) * dir block size + * the two directory bmap btrees: 2 * max depth * block size + * And the bmap_finish transaction can free dir and bmap blocks (two sets + * of bmap blocks) giving: + * the agf for the ags in which the blocks live: 3 * sector size + * the agfl for the ags in which the blocks live: 3 * sector size + * the superblock for the free block count: sector size + * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size + */ +STATIC uint +xfs_calc_rename_reservation( + struct xfs_mount *mp) +{ + return XFS_DQUOT_LOGRES(mp) + + MAX((xfs_calc_inode_res(mp, 4) + + xfs_calc_buf_res(2 * XFS_DIROP_LOG_COUNT(mp), + XFS_FSB_TO_B(mp, 1))), + (xfs_calc_buf_res(7, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 3), + XFS_FSB_TO_B(mp, 1)))); +} + +/* + * For creating a link to an inode: + * the parent directory inode: inode size + * the linked inode: inode size + * the directory btree could split: (max depth + v2) * dir block size + * the directory bmap btree could join or split: (max depth + v2) * blocksize + * And the bmap_finish transaction can free some bmap blocks giving: + * the agf for the ag in which the blocks live: sector size + * the agfl for the ag in which the blocks live: sector size + * the superblock for the free block count: sector size + * the allocation btrees: 2 trees * (2 * max depth - 1) * block size + */ +STATIC uint +xfs_calc_link_reservation( + struct xfs_mount *mp) +{ + return XFS_DQUOT_LOGRES(mp) + + MAX((xfs_calc_inode_res(mp, 2) + + xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), + XFS_FSB_TO_B(mp, 1))), + (xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + XFS_FSB_TO_B(mp, 1)))); +} + +/* + * For removing a directory entry we can modify: + * the parent directory inode: inode size + * the removed inode: inode size + * the directory btree could join: (max depth + v2) * dir block size + * the directory bmap btree could join or split: (max depth + v2) * blocksize + * And the bmap_finish transaction can free the dir and bmap blocks giving: + * the agf for the ag in which the blocks live: 2 * sector size + * the agfl for the ag in which the blocks live: 2 * sector size + * the superblock for the free block count: sector size + * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size + */ +STATIC uint +xfs_calc_remove_reservation( + struct xfs_mount *mp) +{ + return XFS_DQUOT_LOGRES(mp) + + MAX((xfs_calc_inode_res(mp, 2) + + xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), + XFS_FSB_TO_B(mp, 1))), + (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), + XFS_FSB_TO_B(mp, 1)))); +} + +/* + * For create, break it in to the two cases that the transaction + * covers. We start with the modify case - allocation done by modification + * of the state of existing inodes - and the allocation case. + */ + +/* + * For create we can modify: + * the parent directory inode: inode size + * the new inode: inode size + * the inode btree entry: block size + * the superblock for the nlink flag: sector size + * the directory btree: (max depth + v2) * dir block size + * the directory inode's bmap btree: (max depth + v2) * block size + * the finobt + */ +STATIC uint +xfs_calc_create_resv_modify( + struct xfs_mount *mp) +{ + return xfs_calc_inode_res(mp, 2) + + xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + + (uint)XFS_FSB_TO_B(mp, 1) + + xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1)) + + xfs_calc_finobt_res(mp, 1); +} + +/* + * For create we can allocate some inodes giving: + * the agi and agf of the ag getting the new inodes: 2 * sectorsize + * the superblock for the nlink flag: sector size + * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize + * the inode btree: max depth * blocksize + * the allocation btrees: 2 trees * (max depth - 1) * block size + * the finobt + */ +STATIC uint +xfs_calc_create_resv_alloc( + struct xfs_mount *mp) +{ + return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + + mp->m_sb.sb_sectsize + + xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp), XFS_FSB_TO_B(mp, 1)) + + xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) + + xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + XFS_FSB_TO_B(mp, 1)) + + xfs_calc_finobt_res(mp, 0); +} + +STATIC uint +__xfs_calc_create_reservation( + struct xfs_mount *mp) +{ + return XFS_DQUOT_LOGRES(mp) + + MAX(xfs_calc_create_resv_alloc(mp), + xfs_calc_create_resv_modify(mp)); +} + +/* + * For icreate we can allocate some inodes giving: + * the agi and agf of the ag getting the new inodes: 2 * sectorsize + * the superblock for the nlink flag: sector size + * the inode btree: max depth * blocksize + * the allocation btrees: 2 trees * (max depth - 1) * block size + * the finobt + */ +STATIC uint +xfs_calc_icreate_resv_alloc( + struct xfs_mount *mp) +{ + return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + + mp->m_sb.sb_sectsize + + xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) + + xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + XFS_FSB_TO_B(mp, 1)) + + xfs_calc_finobt_res(mp, 0); +} + +STATIC uint +xfs_calc_icreate_reservation(xfs_mount_t *mp) +{ + return XFS_DQUOT_LOGRES(mp) + + MAX(xfs_calc_icreate_resv_alloc(mp), + xfs_calc_create_resv_modify(mp)); +} + +STATIC uint +xfs_calc_create_reservation( + struct xfs_mount *mp) +{ + if (xfs_sb_version_hascrc(&mp->m_sb)) + return xfs_calc_icreate_reservation(mp); + return __xfs_calc_create_reservation(mp); + +} + +/* + * Making a new directory is the same as creating a new file. + */ +STATIC uint +xfs_calc_mkdir_reservation( + struct xfs_mount *mp) +{ + return xfs_calc_create_reservation(mp); +} + + +/* + * Making a new symplink is the same as creating a new file, but + * with the added blocks for remote symlink data which can be up to 1kB in + * length (MAXPATHLEN). + */ +STATIC uint +xfs_calc_symlink_reservation( + struct xfs_mount *mp) +{ + return xfs_calc_create_reservation(mp) + + xfs_calc_buf_res(1, MAXPATHLEN); +} + +/* + * In freeing an inode we can modify: + * the inode being freed: inode size + * the super block free inode counter: sector size + * the agi hash list and counters: sector size + * the inode btree entry: block size + * the on disk inode before ours in the agi hash list: inode cluster size + * the inode btree: max depth * blocksize + * the allocation btrees: 2 trees * (max depth - 1) * block size + * the finobt + */ +STATIC uint +xfs_calc_ifree_reservation( + struct xfs_mount *mp) +{ + return XFS_DQUOT_LOGRES(mp) + + xfs_calc_inode_res(mp, 1) + + xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(1, XFS_FSB_TO_B(mp, 1)) + + MAX((__uint16_t)XFS_FSB_TO_B(mp, 1), + XFS_INODE_CLUSTER_SIZE(mp)) + + xfs_calc_buf_res(1, 0) + + xfs_calc_buf_res(2 + XFS_IALLOC_BLOCKS(mp) + + mp->m_in_maxlevels, 0) + + xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + XFS_FSB_TO_B(mp, 1)) + + xfs_calc_finobt_res(mp, 1); +} + +/* + * When only changing the inode we log the inode and possibly the superblock + * We also add a bit of slop for the transaction stuff. + */ +STATIC uint +xfs_calc_ichange_reservation( + struct xfs_mount *mp) +{ + return XFS_DQUOT_LOGRES(mp) + + xfs_calc_inode_res(mp, 1) + + xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); + +} + +/* + * Growing the data section of the filesystem. + * superblock + * agi and agf + * allocation btrees + */ +STATIC uint +xfs_calc_growdata_reservation( + struct xfs_mount *mp) +{ + return xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + XFS_FSB_TO_B(mp, 1)); +} + +/* + * Growing the rt section of the filesystem. + * In the first set of transactions (ALLOC) we allocate space to the + * bitmap or summary files. + * superblock: sector size + * agf of the ag from which the extent is allocated: sector size + * bmap btree for bitmap/summary inode: max depth * blocksize + * bitmap/summary inode: inode size + * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize + */ +STATIC uint +xfs_calc_growrtalloc_reservation( + struct xfs_mount *mp) +{ + return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), + XFS_FSB_TO_B(mp, 1)) + + xfs_calc_inode_res(mp, 1) + + xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + XFS_FSB_TO_B(mp, 1)); +} + +/* + * Growing the rt section of the filesystem. + * In the second set of transactions (ZERO) we zero the new metadata blocks. + * one bitmap/summary block: blocksize + */ +STATIC uint +xfs_calc_growrtzero_reservation( + struct xfs_mount *mp) +{ + return xfs_calc_buf_res(1, mp->m_sb.sb_blocksize); +} + +/* + * Growing the rt section of the filesystem. + * In the third set of transactions (FREE) we update metadata without + * allocating any new blocks. + * superblock: sector size + * bitmap inode: inode size + * summary inode: inode size + * one bitmap block: blocksize + * summary blocks: new summary size + */ +STATIC uint +xfs_calc_growrtfree_reservation( + struct xfs_mount *mp) +{ + return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + + xfs_calc_inode_res(mp, 2) + + xfs_calc_buf_res(1, mp->m_sb.sb_blocksize) + + xfs_calc_buf_res(1, mp->m_rsumsize); +} + +/* + * Logging the inode modification timestamp on a synchronous write. + * inode + */ +STATIC uint +xfs_calc_swrite_reservation( + struct xfs_mount *mp) +{ + return xfs_calc_inode_res(mp, 1); +} + +/* + * Logging the inode mode bits when writing a setuid/setgid file + * inode + */ +STATIC uint +xfs_calc_writeid_reservation( + struct xfs_mount *mp) +{ + return xfs_calc_inode_res(mp, 1); +} + +/* + * Converting the inode from non-attributed to attributed. + * the inode being converted: inode size + * agf block and superblock (for block allocation) + * the new block (directory sized) + * bmap blocks for the new directory block + * allocation btrees + */ +STATIC uint +xfs_calc_addafork_reservation( + struct xfs_mount *mp) +{ + return XFS_DQUOT_LOGRES(mp) + + xfs_calc_inode_res(mp, 1) + + xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(1, mp->m_dirblksize) + + xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1, + XFS_FSB_TO_B(mp, 1)) + + xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + XFS_FSB_TO_B(mp, 1)); +} + +/* + * Removing the attribute fork of a file + * the inode being truncated: inode size + * the inode's bmap btree: max depth * block size + * And the bmap_finish transaction can free the blocks and bmap blocks: + * the agf for each of the ags: 4 * sector size + * the agfl for each of the ags: 4 * sector size + * the super block to reflect the freed blocks: sector size + * worst case split in allocation btrees per extent assuming 4 extents: + * 4 exts * 2 trees * (2 * max depth - 1) * block size + */ +STATIC uint +xfs_calc_attrinval_reservation( + struct xfs_mount *mp) +{ + return MAX((xfs_calc_inode_res(mp, 1) + + xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK), + XFS_FSB_TO_B(mp, 1))), + (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 4), + XFS_FSB_TO_B(mp, 1)))); +} + +/* + * Setting an attribute at mount time. + * the inode getting the attribute + * the superblock for allocations + * the agfs extents are allocated from + * the attribute btree * max depth + * the inode allocation btree + * Since attribute transaction space is dependent on the size of the attribute, + * the calculation is done partially at mount time and partially at runtime(see + * below). + */ +STATIC uint +xfs_calc_attrsetm_reservation( + struct xfs_mount *mp) +{ + return XFS_DQUOT_LOGRES(mp) + + xfs_calc_inode_res(mp, 1) + + xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(XFS_DA_NODE_MAXDEPTH, XFS_FSB_TO_B(mp, 1)); +} + +/* + * Setting an attribute at runtime, transaction space unit per block. + * the superblock for allocations: sector size + * the inode bmap btree could join or split: max depth * block size + * Since the runtime attribute transaction space is dependent on the total + * blocks needed for the 1st bmap, here we calculate out the space unit for + * one block so that the caller could figure out the total space according + * to the attibute extent length in blocks by: + * ext * M_RES(mp)->tr_attrsetrt.tr_logres + */ +STATIC uint +xfs_calc_attrsetrt_reservation( + struct xfs_mount *mp) +{ + return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK), + XFS_FSB_TO_B(mp, 1)); +} + +/* + * Removing an attribute. + * the inode: inode size + * the attribute btree could join: max depth * block size + * the inode bmap btree could join or split: max depth * block size + * And the bmap_finish transaction can free the attr blocks freed giving: + * the agf for the ag in which the blocks live: 2 * sector size + * the agfl for the ag in which the blocks live: 2 * sector size + * the superblock for the free block count: sector size + * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size + */ +STATIC uint +xfs_calc_attrrm_reservation( + struct xfs_mount *mp) +{ + return XFS_DQUOT_LOGRES(mp) + + MAX((xfs_calc_inode_res(mp, 1) + + xfs_calc_buf_res(XFS_DA_NODE_MAXDEPTH, + XFS_FSB_TO_B(mp, 1)) + + (uint)XFS_FSB_TO_B(mp, + XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + + xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 0)), + (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), + XFS_FSB_TO_B(mp, 1)))); +} + +/* + * Clearing a bad agino number in an agi hash bucket. + */ +STATIC uint +xfs_calc_clear_agi_bucket_reservation( + struct xfs_mount *mp) +{ + return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); +} + +/* + * Clearing the quotaflags in the superblock. + * the super block for changing quota flags: sector size + */ +STATIC uint +xfs_calc_qm_sbchange_reservation( + struct xfs_mount *mp) +{ + return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); +} + +/* + * Adjusting quota limits. + * the xfs_disk_dquot_t: sizeof(struct xfs_disk_dquot) + */ +STATIC uint +xfs_calc_qm_setqlim_reservation( + struct xfs_mount *mp) +{ + return xfs_calc_buf_res(1, sizeof(struct xfs_disk_dquot)); +} + +/* + * Allocating quota on disk if needed. + * the write transaction log space: M_RES(mp)->tr_write.tr_logres + * the unit of quota allocation: one system block size + */ +STATIC uint +xfs_calc_qm_dqalloc_reservation( + struct xfs_mount *mp) +{ + ASSERT(M_RES(mp)->tr_write.tr_logres); + return M_RES(mp)->tr_write.tr_logres + + xfs_calc_buf_res(1, + XFS_FSB_TO_B(mp, XFS_DQUOT_CLUSTER_SIZE_FSB) - 1); +} + +/* + * Turning off quotas. + * the xfs_qoff_logitem_t: sizeof(struct xfs_qoff_logitem) * 2 + * the superblock for the quota flags: sector size + */ +STATIC uint +xfs_calc_qm_quotaoff_reservation( + struct xfs_mount *mp) +{ + return sizeof(struct xfs_qoff_logitem) * 2 + + xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); +} + +/* + * End of turning off quotas. + * the xfs_qoff_logitem_t: sizeof(struct xfs_qoff_logitem) * 2 + */ +STATIC uint +xfs_calc_qm_quotaoff_end_reservation( + struct xfs_mount *mp) +{ + return sizeof(struct xfs_qoff_logitem) * 2; +} + +/* + * Syncing the incore super block changes to disk. + * the super block to reflect the changes: sector size + */ +STATIC uint +xfs_calc_sb_reservation( + struct xfs_mount *mp) +{ + return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); +} + +void +xfs_trans_resv_calc( + struct xfs_mount *mp, + struct xfs_trans_resv *resp) +{ + /* + * The following transactions are logged in physical format and + * require a permanent reservation on space. + */ + resp->tr_write.tr_logres = xfs_calc_write_reservation(mp); + resp->tr_write.tr_logcount = XFS_WRITE_LOG_COUNT; + resp->tr_write.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_itruncate.tr_logres = xfs_calc_itruncate_reservation(mp); + resp->tr_itruncate.tr_logcount = XFS_ITRUNCATE_LOG_COUNT; + resp->tr_itruncate.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_rename.tr_logres = xfs_calc_rename_reservation(mp); + resp->tr_rename.tr_logcount = XFS_RENAME_LOG_COUNT; + resp->tr_rename.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_link.tr_logres = xfs_calc_link_reservation(mp); + resp->tr_link.tr_logcount = XFS_LINK_LOG_COUNT; + resp->tr_link.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_remove.tr_logres = xfs_calc_remove_reservation(mp); + resp->tr_remove.tr_logcount = XFS_REMOVE_LOG_COUNT; + resp->tr_remove.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_symlink.tr_logres = xfs_calc_symlink_reservation(mp); + resp->tr_symlink.tr_logcount = XFS_SYMLINK_LOG_COUNT; + resp->tr_symlink.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_create.tr_logres = xfs_calc_create_reservation(mp); + resp->tr_create.tr_logcount = XFS_CREATE_LOG_COUNT; + resp->tr_create.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_mkdir.tr_logres = xfs_calc_mkdir_reservation(mp); + resp->tr_mkdir.tr_logcount = XFS_MKDIR_LOG_COUNT; + resp->tr_mkdir.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_ifree.tr_logres = xfs_calc_ifree_reservation(mp); + resp->tr_ifree.tr_logcount = XFS_INACTIVE_LOG_COUNT; + resp->tr_ifree.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_addafork.tr_logres = xfs_calc_addafork_reservation(mp); + resp->tr_addafork.tr_logcount = XFS_ADDAFORK_LOG_COUNT; + resp->tr_addafork.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_attrinval.tr_logres = xfs_calc_attrinval_reservation(mp); + resp->tr_attrinval.tr_logcount = XFS_ATTRINVAL_LOG_COUNT; + resp->tr_attrinval.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_attrsetm.tr_logres = xfs_calc_attrsetm_reservation(mp); + resp->tr_attrsetm.tr_logcount = XFS_ATTRSET_LOG_COUNT; + resp->tr_attrsetm.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_attrrm.tr_logres = xfs_calc_attrrm_reservation(mp); + resp->tr_attrrm.tr_logcount = XFS_ATTRRM_LOG_COUNT; + resp->tr_attrrm.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_growrtalloc.tr_logres = xfs_calc_growrtalloc_reservation(mp); + resp->tr_growrtalloc.tr_logcount = XFS_DEFAULT_PERM_LOG_COUNT; + resp->tr_growrtalloc.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_qm_dqalloc.tr_logres = xfs_calc_qm_dqalloc_reservation(mp); + resp->tr_qm_dqalloc.tr_logcount = XFS_WRITE_LOG_COUNT; + resp->tr_qm_dqalloc.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + /* + * The following transactions are logged in logical format with + * a default log count. + */ + resp->tr_qm_sbchange.tr_logres = xfs_calc_qm_sbchange_reservation(mp); + resp->tr_qm_sbchange.tr_logcount = XFS_DEFAULT_LOG_COUNT; + + resp->tr_qm_setqlim.tr_logres = xfs_calc_qm_setqlim_reservation(mp); + resp->tr_qm_setqlim.tr_logcount = XFS_DEFAULT_LOG_COUNT; + + resp->tr_qm_quotaoff.tr_logres = xfs_calc_qm_quotaoff_reservation(mp); + resp->tr_qm_quotaoff.tr_logcount = XFS_DEFAULT_LOG_COUNT; + + resp->tr_qm_equotaoff.tr_logres = + xfs_calc_qm_quotaoff_end_reservation(mp); + resp->tr_qm_equotaoff.tr_logcount = XFS_DEFAULT_LOG_COUNT; + + resp->tr_sb.tr_logres = xfs_calc_sb_reservation(mp); + resp->tr_sb.tr_logcount = XFS_DEFAULT_LOG_COUNT; + + /* The following transaction are logged in logical format */ + resp->tr_ichange.tr_logres = xfs_calc_ichange_reservation(mp); + resp->tr_growdata.tr_logres = xfs_calc_growdata_reservation(mp); + resp->tr_swrite.tr_logres = xfs_calc_swrite_reservation(mp); + resp->tr_fsyncts.tr_logres = xfs_calc_swrite_reservation(mp); + resp->tr_writeid.tr_logres = xfs_calc_writeid_reservation(mp); + resp->tr_attrsetrt.tr_logres = xfs_calc_attrsetrt_reservation(mp); + resp->tr_clearagi.tr_logres = xfs_calc_clear_agi_bucket_reservation(mp); + resp->tr_growrtzero.tr_logres = xfs_calc_growrtzero_reservation(mp); + resp->tr_growrtfree.tr_logres = xfs_calc_growrtfree_reservation(mp); +} diff -Nru xfsprogs-3.1.9ubuntu2/libxlog/xfs_log_recover.c xfsprogs-3.2.1ubuntu1/libxlog/xfs_log_recover.c --- xfsprogs-3.1.9ubuntu2/libxlog/xfs_log_recover.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/libxlog/xfs_log_recover.c 2014-05-02 00:09:16.000000000 +0000 @@ -18,10 +18,15 @@ #include -#define xlog_unpack_data_checksum(rhead, dp, log) ((void)0) -#define xlog_clear_stale_blocks(log, tail_lsn) (0) #define xfs_readonly_buftarg(buftarg) (0) +/* avoid set-but-unused var warning. gcc is not very bright. */ +#define xlog_clear_stale_blocks(log, taillsn) ({ \ + (taillsn) = (taillsn); \ + (0); \ +}) + +#define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1) /* * Verify the given count of basic blocks is valid number of blocks @@ -31,7 +36,7 @@ static inline int xlog_buf_bbcount_valid( - xlog_t *log, + struct xlog *log, int bbcount) { return bbcount > 0 && bbcount <= log->l_logBBsize; @@ -44,11 +49,11 @@ */ xfs_buf_t * xlog_get_bp( - xlog_t *log, + struct xlog *log, int nbblks) { if (!xlog_buf_bbcount_valid(log, nbblks)) { - xlog_warn("XFS: Invalid block length (0x%x) given for buffer", + xfs_warn(log->l_mp, "Invalid block length (0x%x) for buffer", nbblks); XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp); return NULL; @@ -57,7 +62,7 @@ /* * We do log I/O in units of log sectors (a power-of-2 * multiple of the basic block size), so we round up the - * requested size to acommodate the basic blocks required + * requested size to accommodate the basic blocks required * for complete log sectors. * * In addition, the buffer may be used for a non-sector- @@ -68,12 +73,11 @@ * an issue. Nor will this be a problem if the log I/O is * done in basic blocks (sector size 1). But otherwise we * extend the buffer by one extra log sector to ensure - * there's space to accomodate this possiblility. + * there's space to accommodate this possibility. */ if (nbblks > 1 && log->l_sectBBsize > 1) nbblks += log->l_sectBBsize; - if (log->l_sectBBsize) - nbblks = round_up(nbblks, log->l_sectBBsize); + nbblks = round_up(nbblks, log->l_sectBBsize); return libxfs_getbufr(log->l_dev, (xfs_daddr_t)-1, nbblks); } @@ -91,57 +95,54 @@ */ STATIC xfs_caddr_t xlog_align( - xlog_t *log, + struct xlog *log, xfs_daddr_t blk_no, int nbblks, - xfs_buf_t *bp) + struct xfs_buf *bp) { - xfs_daddr_t offset = 0; - - if (log->l_sectBBsize) - offset = blk_no & ((xfs_daddr_t)log->l_sectBBsize - 1); + xfs_daddr_t offset = blk_no & ((xfs_daddr_t)log->l_sectBBsize - 1); - ASSERT(BBTOB(offset + nbblks) <= XFS_BUF_SIZE(bp)); - return XFS_BUF_PTR(bp) + BBTOB(offset); + ASSERT(offset + nbblks <= bp->b_length); + return bp->b_addr + BBTOB(offset); } + /* * nbblks should be uint, but oh well. Just want to catch that 32-bit length. */ int xlog_bread_noalign( - xlog_t *log, + struct xlog *log, xfs_daddr_t blk_no, int nbblks, - xfs_buf_t *bp) + struct xfs_buf *bp) { if (!xlog_buf_bbcount_valid(log, nbblks)) { - xlog_warn("XFS: Invalid block length (0x%x) given for buffer", + xfs_warn(log->l_mp, "Invalid block length (0x%x) for buffer", nbblks); XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp); return EFSCORRUPTED; } - if (log->l_sectBBsize > 1) { - blk_no = round_down(blk_no, log->l_sectBBsize); - nbblks = round_up(nbblks, log->l_sectBBsize); - } + blk_no = round_down(blk_no, log->l_sectBBsize); + nbblks = round_up(nbblks, log->l_sectBBsize); ASSERT(nbblks > 0); ASSERT(BBTOB(nbblks) <= XFS_BUF_SIZE(bp)); XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no); XFS_BUF_SET_COUNT(bp, BBTOB(nbblks)); + bp->b_error = 0; return libxfs_readbufr(log->l_dev, XFS_BUF_ADDR(bp), bp, nbblks, 0); } int xlog_bread( - xlog_t *log, + struct xlog *log, xfs_daddr_t blk_no, int nbblks, - xfs_buf_t *bp, + struct xfs_buf *bp, xfs_caddr_t *offset) { int error; @@ -155,6 +156,35 @@ } /* + * Read at an offset into the buffer. Returns with the buffer in it's original + * state regardless of the result of the read. + */ +STATIC int +xlog_bread_offset( + struct xlog *log, + xfs_daddr_t blk_no, /* block to read from */ + int nbblks, /* blocks to read */ + struct xfs_buf *bp, + xfs_caddr_t offset) +{ + xfs_caddr_t orig_offset = bp->b_addr; + int orig_len = bp->b_bcount; + int error, error2; + + error = XFS_BUF_SET_PTR(bp, offset, BBTOB(nbblks)); + if (error) + return error; + + error = xlog_bread_noalign(log, blk_no, nbblks, bp); + + /* must reset buffer pointer even on error */ + error2 = XFS_BUF_SET_PTR(bp, orig_offset, orig_len); + if (error) + return error; + return error2; +} + +/* * This routine finds (to an approximation) the first block in the physical * log which contains the given cycle. It uses a binary search algorithm. * Note that the algorithm can not be perfect because the disk will not @@ -162,8 +192,8 @@ */ int xlog_find_cycle_start( - xlog_t *log, - xfs_buf_t *bp, + struct xlog *log, + struct xfs_buf *bp, xfs_daddr_t first_blk, xfs_daddr_t *last_blk, uint cycle) @@ -205,7 +235,7 @@ */ STATIC int xlog_find_verify_cycle( - xlog_t *log, + struct xlog *log, xfs_daddr_t start_blk, int nbblks, uint stop_on_cycle_no, @@ -225,9 +255,11 @@ * a log sector, or we're out of luck. */ bufblks = 1 << ffs(nbblks); + while (bufblks > log->l_logBBsize) + bufblks >>= 1; while (!(bp = xlog_get_bp(log, bufblks))) { bufblks >>= 1; - if (bufblks < MAX(log->l_sectBBsize, 1)) + if (bufblks < log->l_sectBBsize) return ENOMEM; } @@ -272,7 +304,7 @@ */ STATIC int xlog_find_verify_log_record( - xlog_t *log, + struct xlog *log, xfs_daddr_t start_blk, xfs_daddr_t *last_blk, int extra_bblks) @@ -302,8 +334,8 @@ for (i = (*last_blk) - 1; i >= 0; i--) { if (i < start_blk) { /* valid log record not found */ - xlog_warn( - "XFS: Log inconsistent (didn't find previous header)"); + xfs_warn(log->l_mp, + "Log inconsistent (didn't find previous header)"); ASSERT(0); error = XFS_ERROR(EIO); goto out; @@ -317,7 +349,7 @@ head = (xlog_rec_header_t *)offset; - if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(head->h_magicno)) + if (head->h_magicno == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) break; if (!smallmem) @@ -382,7 +414,7 @@ */ STATIC int xlog_find_head( - xlog_t *log, + struct xlog *log, xfs_daddr_t *return_head_blk) { xfs_buf_t *bp; @@ -403,12 +435,12 @@ * mkfs etc write a dummy unmount record to a fresh * log so we can store the uuid in there */ - xlog_warn("XFS: totally zeroed log"); + xfs_warn(log->l_mp, "totally zeroed log"); } return 0; } else if (error) { - xlog_warn("XFS: empty log check failed"); + xfs_warn(log->l_mp, "empty log check failed"); return error; } @@ -631,7 +663,7 @@ xlog_put_bp(bp); if (error) - xlog_warn("XFS: failed to find log head"); + xfs_warn(log->l_mp, "failed to find log head"); return error; } @@ -653,7 +685,7 @@ */ int xlog_find_tail( - xlog_t *log, + struct xlog *log, xfs_daddr_t *head_blk, xfs_daddr_t *tail_blk) { @@ -699,7 +731,7 @@ if (error) goto done; - if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(*(__be32 *)offset)) { + if (*(__be32 *)offset == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { found = 1; break; } @@ -716,15 +748,16 @@ if (error) goto done; - if (XLOG_HEADER_MAGIC_NUM == - be32_to_cpu(*(__be32 *)offset)) { + if (*(__be32 *)offset == + cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { found = 2; break; } } } if (!found) { - xlog_warn("XFS: xlog_find_tail: couldn't find sync record"); + xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__); + xlog_put_bp(bp); ASSERT(0); return XFS_ERROR(EIO); } @@ -750,9 +783,9 @@ log->l_curr_cycle++; atomic64_set(&log->l_tail_lsn, be64_to_cpu(rhead->h_tail_lsn)); atomic64_set(&log->l_last_sync_lsn, be64_to_cpu(rhead->h_lsn)); - xlog_assign_grant_head(&log->l_grant_reserve_head, log->l_curr_cycle, + xlog_assign_grant_head(&log->l_reserve_head.grant, log->l_curr_cycle, BBTOB(log->l_curr_block)); - xlog_assign_grant_head(&log->l_grant_write_head, log->l_curr_cycle, + xlog_assign_grant_head(&log->l_write_head.grant, log->l_curr_cycle, BBTOB(log->l_curr_block)); /* @@ -840,7 +873,7 @@ xlog_put_bp(bp); if (error) - xlog_warn("XFS: failed to locate log tail"); + xfs_warn(log->l_mp, "failed to locate log tail"); return error; } @@ -862,7 +895,7 @@ */ int xlog_find_zeroed( - xlog_t *log, + struct xlog *log, xfs_daddr_t *blk_no) { xfs_buf_t *bp; @@ -904,8 +937,10 @@ * the first block must be 1. If it's not, maybe we're * not looking at a log... Bail out. */ - xlog_warn("XFS: Log inconsistent or not a log (last==0, first!=1)"); - return XFS_ERROR(EINVAL); + xfs_warn(log->l_mp, + "Log inconsistent or not a log (last==0, first!=1)"); + error = XFS_ERROR(EINVAL); + goto bp_err; } /* we have a partially zeroed log */ @@ -1000,10 +1035,12 @@ list_add_tail(&item->ri_list, head); } +#define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1) + STATIC int xlog_recover_add_to_cont_trans( - struct log *log, - xlog_recover_t *trans, + struct xlog *log, + struct xlog_recover *trans, xfs_caddr_t dp, int len) { @@ -1025,7 +1062,7 @@ old_ptr = item->ri_buf[item->ri_cnt-1].i_addr; old_len = item->ri_buf[item->ri_cnt-1].i_len; - ptr = kmem_realloc(old_ptr, len+old_len, old_len, 0u); + ptr = kmem_realloc(old_ptr, len+old_len, old_len, KM_SLEEP); memcpy(&ptr[old_len], dp, len); /* d, s, l */ item->ri_buf[item->ri_cnt-1].i_len += len; item->ri_buf[item->ri_cnt-1].i_addr = ptr; @@ -1048,8 +1085,8 @@ */ STATIC int xlog_recover_add_to_trans( - struct log *log, - xlog_recover_t *trans, + struct xlog *log, + struct xlog_recover *trans, xfs_caddr_t dp, int len) { @@ -1062,8 +1099,8 @@ if (list_empty(&trans->r_itemq)) { /* we need to catch log corruptions here */ if (*(uint *)dp != XFS_TRANS_HEADER_MAGIC) { - xlog_warn("XFS: xlog_recover_add_to_trans: " - "bad header magic number"); + xfs_warn(log->l_mp, "%s: bad header magic number", + __func__); ASSERT(0); return XFS_ERROR(EIO); } @@ -1090,10 +1127,11 @@ if (item->ri_total == 0) { /* first region to be added */ if (in_f->ilf_size == 0 || in_f->ilf_size > XLOG_MAX_REGIONS_IN_ITEM) { - xlog_warn( - "XFS: bad number of regions (%d) in inode log format", + xfs_warn(log->l_mp, + "bad number of regions (%d) in inode log format", in_f->ilf_size); ASSERT(0); + kmem_free(ptr); return XFS_ERROR(EIO); } @@ -1144,7 +1182,7 @@ */ STATIC int xlog_recover_commit_trans( - struct log *log, + struct xlog *log, struct xlog_recover *trans, int pass) { @@ -1163,7 +1201,7 @@ xlog_recover_t *trans) { /* Do nothing now */ - xlog_warn("XFS: xlog_recover_unmount_trans: Unmount LR"); + xfs_warn(log->l_mp, "%s: Unmount LR", __func__); return 0; } @@ -1178,9 +1216,9 @@ */ STATIC int xlog_recover_process_data( - xlog_t *log, + struct xlog *log, struct hlist_head rhash[], - xlog_rec_header_t *rhead, + struct xlog_rec_header *rhead, xfs_caddr_t dp, int pass) { @@ -1206,8 +1244,8 @@ dp += sizeof(xlog_op_header_t); if (ohead->oh_clientid != XFS_TRANSACTION && ohead->oh_clientid != XFS_LOG) { - xlog_warn( - "XFS: xlog_recover_process_data: bad clientid"); + xfs_warn(log->l_mp, "%s: bad clientid 0x%x", + __func__, ohead->oh_clientid); ASSERT(0); return (XFS_ERROR(EIO)); } @@ -1220,8 +1258,8 @@ be64_to_cpu(rhead->h_lsn)); } else { if (dp + be32_to_cpu(ohead->oh_len) > lp) { - xlog_warn( - "XFS: xlog_recover_process_data: bad length"); + xfs_warn(log->l_mp, "%s: bad length 0x%x", + __func__, be32_to_cpu(ohead->oh_len)); return (XFS_ERROR(EIO)); } flags = ohead->oh_flags & ~XLOG_END_TRANS; @@ -1241,8 +1279,8 @@ be32_to_cpu(ohead->oh_len)); break; case XLOG_START_TRANS: - xlog_warn( - "XFS: xlog_recover_process_data: bad transaction"); + xfs_warn(log->l_mp, "%s: bad transaction", + __func__); ASSERT(0); error = XFS_ERROR(EIO); break; @@ -1252,8 +1290,8 @@ dp, be32_to_cpu(ohead->oh_len)); break; default: - xlog_warn( - "XFS: xlog_recover_process_data: bad flag"); + xfs_warn(log->l_mp, "%s: bad flag 0x%x", + __func__, flags); ASSERT(0); error = XFS_ERROR(EIO); break; @@ -1267,13 +1305,62 @@ return 0; } -STATIC void +/* + * Upack the log buffer data and crc check it. If the check fails, issue a + * warning if and only if the CRC in the header is non-zero. This makes the + * check an advisory warning, and the zero CRC check will prevent failure + * warnings from being emitted when upgrading the kernel from one that does not + * add CRCs by default. + * + * When filesystems are CRC enabled, this CRC mismatch becomes a fatal log + * corruption failure + * + * XXX: we do not calculate the CRC here yet. It's not clear what we should do + * with CRC errors here in userspace, so we'll address that problem later on. + */ +#define xlog_cksum(l,r,dp,len) ((r)->h_crc) +STATIC int +xlog_unpack_data_crc( + struct xlog_rec_header *rhead, + xfs_caddr_t dp, + struct xlog *log) +{ + __le32 crc; + + crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len)); + if (crc != rhead->h_crc) { + if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) { + xfs_alert(log->l_mp, + "log record CRC mismatch: found 0x%x, expected 0x%x.", + le32_to_cpu(rhead->h_crc), + le32_to_cpu(crc)); + xfs_hex_dump(dp, 32); + } + + /* + * If we've detected a log record corruption, then we can't + * recover past this point. Abort recovery if we are enforcing + * CRC protection by punting an error back up the stack. + */ + if (xfs_sb_version_hascrc(&log->l_mp->m_sb)) + return EFSCORRUPTED; + } + + return 0; +} + +STATIC int xlog_unpack_data( - xlog_rec_header_t *rhead, + struct xlog_rec_header *rhead, xfs_caddr_t dp, - xlog_t *log) + struct xlog *log) { int i, j, k; + int error; + + error = xlog_unpack_data_crc(rhead, dp, log); + if (error) + return error; for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) && i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) { @@ -1290,17 +1377,19 @@ dp += BBSIZE; } } + + return 0; } STATIC int xlog_valid_rec_header( - xlog_t *log, - xlog_rec_header_t *rhead, + struct xlog *log, + struct xlog_rec_header *rhead, xfs_daddr_t blkno) { int hlen; - if (unlikely(be32_to_cpu(rhead->h_magicno) != XLOG_HEADER_MAGIC_NUM)) { + if (unlikely(rhead->h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM))) { XFS_ERROR_REPORT("xlog_valid_rec_header(1)", XFS_ERRLEVEL_LOW, log->l_mp); return XFS_ERROR(EFSCORRUPTED); @@ -1308,7 +1397,7 @@ if (unlikely( (!rhead->h_version || (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))))) { - xlog_warn("XFS: %s: unrecognised log version (%d).", + xfs_warn(log->l_mp, "%s: unrecognised log version (%d).", __func__, be32_to_cpu(rhead->h_version)); return XFS_ERROR(EIO); } @@ -1338,7 +1427,7 @@ */ int xlog_do_recovery_pass( - xlog_t *log, + struct xlog *log, xfs_daddr_t head_blk, xfs_daddr_t tail_blk, int pass) @@ -1421,9 +1510,13 @@ if (error) goto bread_err2; - xlog_unpack_data(rhead, offset, log); - if ((error = xlog_recover_process_data(log, - rhash, rhead, offset, pass))) + error = xlog_unpack_data(rhead, offset, log); + if (error) + goto bread_err2; + + error = xlog_recover_process_data(log, + rhash, rhead, offset, pass); + if (error) goto bread_err2; blk_no += bblks + hblks; } @@ -1438,7 +1531,7 @@ /* * Check for header wrapping around physical end-of-log */ - offset = XFS_BUF_PTR(hbp); + offset = hbp->b_addr; split_hblks = 0; wrapped_hblks = 0; if (blk_no + hblks <= log->l_logBBsize) { @@ -1474,19 +1567,9 @@ * - order is important. */ wrapped_hblks = hblks - split_hblks; - error = XFS_BUF_SET_PTR(hbp, - offset + BBTOB(split_hblks), - BBTOB(hblks - split_hblks)); - if (error) - goto bread_err2; - - error = xlog_bread_noalign(log, 0, - wrapped_hblks, hbp); - if (error) - goto bread_err2; - - error = XFS_BUF_SET_PTR(hbp, offset, - BBTOB(hblks)); + error = xlog_bread_offset(log, 0, + wrapped_hblks, hbp, + offset + BBTOB(split_hblks)); if (error) goto bread_err2; } @@ -1508,7 +1591,7 @@ } else { /* This log record is split across the * physical end of log */ - offset = XFS_BUF_PTR(dbp); + offset = dbp->b_addr; split_bblks = 0; if (blk_no != log->l_logBBsize) { /* some data is before the physical @@ -1537,25 +1620,20 @@ * _first_, then the log start (LR header end) * - order is important. */ - error = XFS_BUF_SET_PTR(dbp, - offset + BBTOB(split_bblks), - BBTOB(bblks - split_bblks)); + error = xlog_bread_offset(log, 0, + bblks - split_bblks, dbp, + offset + BBTOB(split_bblks)); if (error) goto bread_err2; + } - error = xlog_bread_noalign(log, wrapped_hblks, - bblks - split_bblks, - dbp); - if (error) - goto bread_err2; + error = xlog_unpack_data(rhead, offset, log); + if (error) + goto bread_err2; - error = XFS_BUF_SET_PTR(dbp, offset, h_size); - if (error) - goto bread_err2; - } - xlog_unpack_data(rhead, offset, log); - if ((error = xlog_recover_process_data(log, rhash, - rhead, offset, pass))) + error = xlog_recover_process_data(log, rhash, + rhead, offset, pass); + if (error) goto bread_err2; blk_no += bblks; } @@ -1580,9 +1658,13 @@ if (error) goto bread_err2; - xlog_unpack_data(rhead, offset, log); - if ((error = xlog_recover_process_data(log, rhash, - rhead, offset, pass))) + error = xlog_unpack_data(rhead, offset, log); + if (error) + goto bread_err2; + + error = xlog_recover_process_data(log, rhash, + rhead, offset, pass); + if (error) goto bread_err2; blk_no += bblks + hblks; } diff -Nru xfsprogs-3.1.9ubuntu2/logprint/log_copy.c xfsprogs-3.2.1ubuntu1/logprint/log_copy.c --- xfsprogs-3.1.9ubuntu2/logprint/log_copy.c 2009-02-17 01:14:58.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/logprint/log_copy.c 2013-06-06 22:52:59.000000000 +0000 @@ -24,7 +24,7 @@ void xfs_log_copy( - xlog_t *log, + struct xlog *log, int fd, char *filename) { diff -Nru xfsprogs-3.1.9ubuntu2/logprint/log_dump.c xfsprogs-3.2.1ubuntu1/logprint/log_dump.c --- xfsprogs-3.1.9ubuntu2/logprint/log_dump.c 2009-02-17 01:14:58.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/logprint/log_dump.c 2013-06-06 22:52:59.000000000 +0000 @@ -24,7 +24,7 @@ void xfs_log_dump( - xlog_t *log, + struct xlog *log, int fd, int print_block_start) { diff -Nru xfsprogs-3.1.9ubuntu2/logprint/log_misc.c xfsprogs-3.2.1ubuntu1/logprint/log_misc.c --- xfsprogs-3.1.9ubuntu2/logprint/log_misc.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/logprint/log_misc.c 2014-07-21 09:15:17.000000000 +0000 @@ -25,8 +25,6 @@ #define BAD_HEADER (-1) #define NO_ERROR (0) -#define XLOG_SET(f,b) (((f) & (b)) == (b)) - static int logBBsize; char *trans_type[] = { "", @@ -72,6 +70,7 @@ "SWAPEXT", "SB_COUNT", "CHECKPOINT", + "ICREATE", }; typedef struct xlog_split_item { @@ -270,7 +269,13 @@ blen = f->blf_len; map_size = f->blf_map_size; flags = f->blf_flags; - struct_size = sizeof(xfs_buf_log_format_t); + + /* + * size of the format header is dependent on the size of the bitmap, not + * the size of the in-memory structure. Hence the slightly obtuse + * calculation. + */ + struct_size = offsetof(struct xfs_buf_log_format, blf_map_size) + map_size; if (len >= struct_size) { ASSERT((len - sizeof(struct_size)) % sizeof(int) == 0); @@ -472,13 +477,17 @@ int -xlog_print_trans_efi(xfs_caddr_t *ptr, uint src_len) +xlog_print_trans_efi( + xfs_caddr_t *ptr, + uint src_len, + int continued) { - xfs_efi_log_format_t *src_f, *f; + xfs_efi_log_format_t *src_f, *f = NULL; uint dst_len; xfs_extent_t *ex; int i; int error = 0; + int core_size = offsetof(xfs_efi_log_format_t, efi_extents); /* * memmove to ensure 8-byte alignment for the long longs in @@ -493,17 +502,30 @@ /* convert to native format */ dst_len = sizeof(xfs_efi_log_format_t) + (src_f->efi_nextents - 1) * sizeof(xfs_extent_t); + + if (continued && src_len < core_size) { + printf(_("EFI: Not enough data to decode further\n")); + error = 1; + goto error; + } + if ((f = (xfs_efi_log_format_t *)malloc(dst_len)) == NULL) { fprintf(stderr, _("%s: xlog_print_trans_efi: malloc failed\n"), progname); exit(1); } - if (xfs_efi_copy_format((char*)src_f, src_len, f)) { + if (xfs_efi_copy_format((char*)src_f, src_len, f, continued)) { error = 1; goto error; } printf(_("EFI: #regs: %d num_extents: %d id: 0x%llx\n"), f->efi_size, f->efi_nextents, (unsigned long long)f->efi_id); + + if (continued) { + printf(_("EFI free extent data skipped (CONTINUE set, no space)\n")); + goto error; + } + ex = f->efi_extents; for (i=0; i < f->efi_nextents; i++) { printf("(s: 0x%llx, l: %d) ", @@ -560,16 +582,16 @@ } void -xlog_print_dir_sf(xfs_dir_shortform_t *sfp, int size) +xlog_print_dir2_sf( + struct xlog *log, + xfs_dir2_sf_hdr_t *sfp, + int size) { xfs_ino_t ino; int count; int i; char namebuf[257]; - xfs_dir_sf_entry_t *sfep; - - /* XXX need to determine whether this is v1 or v2, then - print appropriate structure */ + xfs_dir2_sf_entry_t *sfep; printf(_("SHORTFORM DIRECTORY size %d\n"), size); @@ -578,24 +600,30 @@ return; printf(_("SHORTFORM DIRECTORY size %d count %d\n"), - size, sfp->hdr.count); - memmove(&ino, &(sfp->hdr.parent), sizeof(ino)); - printf(_(".. ino 0x%llx\n"), (unsigned long long) be64_to_cpu(ino)); + size, sfp->count); + memmove(&ino, &(sfp->parent), sizeof(ino)); + printf(_(".. ino 0x%llx\n"), (unsigned long long) be64_to_cpu(ino)); - count = (uint)(sfp->hdr.count); - sfep = &(sfp->list[0]); + count = sfp->count; + sfep = xfs_dir2_sf_firstentry(sfp); for (i = 0; i < count; i++) { - memmove(&ino, &(sfep->inumber), sizeof(ino)); + ino = xfs_dir3_sfe_get_ino(log->l_mp, sfp, sfep); memmove(namebuf, (sfep->name), sfep->namelen); namebuf[sfep->namelen] = '\0'; printf(_("%s ino 0x%llx namelen %d\n"), namebuf, (unsigned long long)ino, sfep->namelen); - sfep = xfs_dir_sf_nextentry(sfep); + sfep = xfs_dir3_sf_nextentry(log->l_mp, sfp, sfep); } } int -xlog_print_trans_inode(xfs_caddr_t *ptr, int len, int *i, int num_ops) +xlog_print_trans_inode( + struct xlog *log, + xfs_caddr_t *ptr, + int len, + int *i, + int num_ops, + boolean_t continued) { xfs_icdinode_t dino; xlog_op_header_t *op_head; @@ -617,8 +645,9 @@ memmove(&src_lbuf, *ptr, MIN(sizeof(xfs_inode_log_format_64_t), len)); (*i)++; /* bump index */ *ptr += len; - if (len == sizeof(xfs_inode_log_format_32_t) || - len == sizeof(xfs_inode_log_format_64_t)) { + if (!continued && + (len == sizeof(xfs_inode_log_format_32_t) || + len == sizeof(xfs_inode_log_format_64_t))) { f = xfs_inode_item_format_convert((char*)&src_lbuf, len, &dst_lbuf); printf(_("INODE: ")); printf(_("#regs: %d ino: 0x%llx flags: 0x%x dsize: %d\n"), @@ -641,7 +670,7 @@ op_head = (xlog_op_header_t *)*ptr; xlog_print_op_header(op_head, *i, ptr); - if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) { + if (op_head->oh_flags & XLOG_CONTINUE_TRANS) { return f->ilf_size-1; } @@ -649,7 +678,7 @@ mode = dino.di_mode & S_IFMT; size = (int)dino.di_size; xlog_print_trans_inode_core(&dino); - *ptr += sizeof(xfs_icdinode_t); + *ptr += xfs_icdinode_size(dino.di_version); if (*i == num_ops-1 && f->ilf_size == 3) { return 1; @@ -657,97 +686,75 @@ /* does anything come next */ op_head = (xlog_op_header_t *)*ptr; - switch (f->ilf_fields & XFS_ILOG_NONCORE) { - case XFS_ILOG_DEXT: { - ASSERT(f->ilf_size == 3); - (*i)++; - xlog_print_op_header(op_head, *i, ptr); - printf(_("EXTENTS inode data\n")); - *ptr += be32_to_cpu(op_head->oh_len); - if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) { - return 1; - } - break; - } - case XFS_ILOG_DBROOT: { - ASSERT(f->ilf_size == 3); - (*i)++; - xlog_print_op_header(op_head, *i, ptr); - printf(_("BTREE inode data\n")); - *ptr += be32_to_cpu(op_head->oh_len); - if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) { - return 1; - } - break; - } - case XFS_ILOG_DDATA: { - ASSERT(f->ilf_size == 3); - (*i)++; - xlog_print_op_header(op_head, *i, ptr); - printf(_("LOCAL inode data\n")); - if (mode == S_IFDIR) { - xlog_print_dir_sf((xfs_dir_shortform_t*)*ptr, size); - } - *ptr += be32_to_cpu(op_head->oh_len); - if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) { - return 1; - } - break; - } - case XFS_ILOG_AEXT: { - ASSERT(f->ilf_size == 3); + + switch (f->ilf_fields & (XFS_ILOG_DEV | XFS_ILOG_UUID)) { + case XFS_ILOG_DEV: + printf(_("DEV inode: no extra region\n")); + break; + case XFS_ILOG_UUID: + printf(_("UUID inode: no extra region\n")); + break; + } + + /* Only the inode core is logged */ + if (f->ilf_size == 2) + return 0; + + ASSERT(f->ilf_size <= 4); + ASSERT((f->ilf_size == 3) || (f->ilf_fields & XFS_ILOG_AFORK)); + + if (f->ilf_fields & XFS_ILOG_DFORK) { (*i)++; xlog_print_op_header(op_head, *i, ptr); - printf(_("EXTENTS inode attr\n")); - *ptr += be32_to_cpu(op_head->oh_len); - if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) { - return 1; + + switch (f->ilf_fields & XFS_ILOG_DFORK) { + case XFS_ILOG_DEXT: + printf(_("EXTENTS inode data\n")); + break; + case XFS_ILOG_DBROOT: + printf(_("BTREE inode data\n")); + break; + case XFS_ILOG_DDATA: + printf(_("LOCAL inode data\n")); + if (mode == S_IFDIR) + xlog_print_dir2_sf(log, (xfs_dir2_sf_hdr_t *)*ptr, size); + break; + default: + ASSERT((f->ilf_fields & XFS_ILOG_DFORK) == 0); + break; } - break; - } - case XFS_ILOG_ABROOT: { - ASSERT(f->ilf_size == 3); - (*i)++; - xlog_print_op_header(op_head, *i, ptr); - printf(_("BTREE inode attr\n")); + *ptr += be32_to_cpu(op_head->oh_len); - if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) { + if (op_head->oh_flags & XLOG_CONTINUE_TRANS) return 1; - } - break; - } - case XFS_ILOG_ADATA: { - ASSERT(f->ilf_size == 3); + op_head = (xlog_op_header_t *)*ptr; + } + + if (f->ilf_fields & XFS_ILOG_AFORK) { (*i)++; xlog_print_op_header(op_head, *i, ptr); - printf(_("LOCAL inode attr\n")); - if (mode == S_IFDIR) { - xlog_print_dir_sf((xfs_dir_shortform_t*)*ptr, size); + + switch (f->ilf_fields & XFS_ILOG_AFORK) { + case XFS_ILOG_AEXT: + printf(_("EXTENTS attr data\n")); + break; + case XFS_ILOG_ABROOT: + printf(_("BTREE attr data\n")); + break; + case XFS_ILOG_ADATA: + printf(_("LOCAL attr data\n")); + if (mode == S_IFDIR) + xlog_print_dir2_sf(log, (xfs_dir2_sf_hdr_t *)*ptr, size); + break; + default: + ASSERT((f->ilf_fields & XFS_ILOG_AFORK) == 0); + break; } *ptr += be32_to_cpu(op_head->oh_len); - if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) { + if (op_head->oh_flags & XLOG_CONTINUE_TRANS) return 1; - } - break; - } - case XFS_ILOG_DEV: { - ASSERT(f->ilf_size == 2); - printf(_("DEV inode: no extra region\n")); - break; - } - case XFS_ILOG_UUID: { - ASSERT(f->ilf_size == 2); - printf(_("UUID inode: no extra region\n")); - break; - } - case 0: { - ASSERT(f->ilf_size == 2); - break; - } - default: { - xlog_panic(_("xlog_print_trans_inode: illegal inode type")); - } } + return 0; } /* xlog_print_trans_inode */ @@ -807,6 +814,34 @@ } /* xlog_print_trans_dquot */ +STATIC int +xlog_print_trans_icreate( + xfs_caddr_t *ptr, + int len, + int *i, + int num_ops) +{ + struct xfs_icreate_log icl_buf = {0}; + struct xfs_icreate_log *icl; + + memmove(&icl_buf, *ptr, MIN(sizeof(struct xfs_icreate_log), len)); + icl = &icl_buf; + *ptr += len; + + /* handle complete header only */ + if (len != sizeof(struct xfs_icreate_log)) { + printf(_("ICR: split header, not printing\n")); + return 1; /* to skip leftover in next region */ + } + + printf(_("ICR: #ag: %d agbno: 0x%x len: %d\n" + " cnt: %d isize: %d gen: 0x%x\n"), + be32_to_cpu(icl->icl_ag), be32_to_cpu(icl->icl_agbno), + be32_to_cpu(icl->icl_length), be32_to_cpu(icl->icl_count), + be32_to_cpu(icl->icl_isize), be32_to_cpu(icl->icl_gen)); + return 0; +} + /****************************************************************************** * * Log print routines @@ -815,7 +850,7 @@ */ void -xlog_print_lseek(xlog_t *log, int fd, xfs_daddr_t blkno, int whence) +xlog_print_lseek(struct xlog *log, int fd, xfs_daddr_t blkno, int whence) { #define BBTOOFF64(bbs) (((xfs_off_t)(bbs)) << BBSHIFT) xfs_off_t offset; @@ -842,16 +877,19 @@ int -xlog_print_record(int fd, - int num_ops, - int len, - int *read_type, - xfs_caddr_t *partial_buf, - xlog_rec_header_t *rhead, - xlog_rec_ext_header_t *xhdrs) +xlog_print_record( + struct xlog *log, + int fd, + int num_ops, + int len, + int *read_type, + xfs_caddr_t *partial_buf, + xlog_rec_header_t *rhead, + xlog_rec_ext_header_t *xhdrs, + int bad_hdr_warn) { xfs_caddr_t buf, ptr; - int read_len, skip; + int read_len, skip, lost_context = 0; int ret, n, i, j, k; if (print_no_print) @@ -920,11 +958,12 @@ */ if (be32_to_cpu(rhead->h_cycle) != be32_to_cpu(*(__be32 *)ptr)) { - if (*read_type == FULL_READ) - return -1; - else if (be32_to_cpu(rhead->h_cycle) + 1 != - be32_to_cpu(*(__be32 *)ptr)) - return -1; + if ((*read_type == FULL_READ) || + (be32_to_cpu(rhead->h_cycle) + 1 != + be32_to_cpu(*(__be32 *)ptr))) { + free(buf); + return -1; + } } } @@ -945,29 +984,40 @@ ptr = buf; for (i=0; ioh_flags & XLOG_WAS_CONT_TRANS) || + (op_head->oh_flags & XLOG_CONTINUE_TRANS)); - /* print transaction data */ - if (print_no_data || - ((XLOG_SET(op_head->oh_flags, XLOG_WAS_CONT_TRANS) || - XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) && - be32_to_cpu(op_head->oh_len) == 0)) { + if (continued && be32_to_cpu(op_head->oh_len) == 0) + continue; + + if (print_no_data) { for (n = 0; n < be32_to_cpu(op_head->oh_len); n++) { - printf("%c", *ptr); + printf("0x%02x ", (unsigned int)*ptr); + if (n % 16 == 15) + printf("\n"); ptr++; } printf("\n"); continue; } + + /* print transaction data */ if (xlog_print_find_tid(be32_to_cpu(op_head->oh_tid), op_head->oh_flags & XLOG_WAS_CONT_TRANS)) { printf(_("Left over region from split log item\n")); + /* Skip this leftover bit */ ptr += be32_to_cpu(op_head->oh_len); + /* We've lost context; don't complain if next one looks bad too */ + lost_context = 1; continue; } + if (be32_to_cpu(op_head->oh_len) != 0) { if (*(uint *)ptr == XFS_TRANS_HEADER_MAGIC) { skip = xlog_print_trans_header(&ptr, @@ -980,12 +1030,18 @@ &i, num_ops); break; } - case XFS_LI_INODE: { - skip = xlog_print_trans_inode(&ptr, + case XFS_LI_ICREATE: { + skip = xlog_print_trans_icreate(&ptr, be32_to_cpu(op_head->oh_len), &i, num_ops); break; } + case XFS_LI_INODE: { + skip = xlog_print_trans_inode(log, &ptr, + be32_to_cpu(op_head->oh_len), + &i, num_ops, continued); + break; + } case XFS_LI_DQUOT: { skip = xlog_print_trans_dquot(&ptr, be32_to_cpu(op_head->oh_len), @@ -994,7 +1050,8 @@ } case XFS_LI_EFI: { skip = xlog_print_trans_efi(&ptr, - be32_to_cpu(op_head->oh_len)); + be32_to_cpu(op_head->oh_len), + continued); break; } case XFS_LI_EFD: { @@ -1013,14 +1070,21 @@ break; } default: { - fprintf(stderr, _("%s: unknown log operation type (%x)\n"), - progname, *(unsigned short *)ptr); - if (print_exit) { - free(buf); - return BAD_HEADER; + if (bad_hdr_warn && !lost_context) { + fprintf(stderr, + _("%s: unknown log operation type (%x)\n"), + progname, *(unsigned short *)ptr); + if (print_exit) { + free(buf); + return BAD_HEADER; + } + } else { + printf( + _("Left over region from split log item\n")); } skip = 0; ptr += be32_to_cpu(op_head->oh_len); + lost_context = 0; } } /* switch */ } /* else */ @@ -1035,7 +1099,7 @@ int -xlog_print_rec_head(xlog_rec_header_t *head, int *len) +xlog_print_rec_head(xlog_rec_header_t *head, int *len, int bad_hdr_warn) { int i; char uub[64]; @@ -1048,14 +1112,15 @@ return ZEROED_LOG; if (be32_to_cpu(head->h_magicno) != XLOG_HEADER_MAGIC_NUM) { - printf(_("Header 0x%x wanted 0x%x\n"), - be32_to_cpu(head->h_magicno), - XLOG_HEADER_MAGIC_NUM); + if (bad_hdr_warn) + printf(_("Header 0x%x wanted 0x%x\n"), + be32_to_cpu(head->h_magicno), + XLOG_HEADER_MAGIC_NUM); return BAD_HEADER; } /* check for cleared blocks written by xlog_clear_stale_blocks() */ - if (!head->h_len && !head->h_chksum && !head->h_prev_block && + if (!head->h_len && !head->h_crc && !head->h_prev_block && !head->h_num_logops && !head->h_size) return CLEARED_BLKS; @@ -1264,7 +1329,7 @@ /* * This code is gross and needs to be rewritten. */ -void xfs_log_print(xlog_t *log, +void xfs_log_print(struct xlog *log, int fd, int print_block_start) { @@ -1276,8 +1341,9 @@ xfs_daddr_t zeroed_blkno = 0, cleared_blkno = 0; int read_type = FULL_READ; xfs_caddr_t partial_buf; - int zeroed = 0; - int cleared = 0; + int zeroed = 0; + int cleared = 0; + int first_hdr_found = 0; logBBsize = log->l_logBBsize; @@ -1309,7 +1375,7 @@ blkno++; goto loop; } - num_ops = xlog_print_rec_head(hdr, &len); + num_ops = xlog_print_rec_head(hdr, &len, first_hdr_found); blkno++; if (zeroed && num_ops != ZEROED_LOG) { @@ -1335,7 +1401,10 @@ cleared_blkno = blkno-1; cleared++; } else { - print_xlog_bad_header(blkno-1, hbuf); + if (!first_hdr_found) + block_start = blkno; + else + print_xlog_bad_header(blkno-1, hbuf); } goto loop; @@ -1346,7 +1415,9 @@ break; } - error = xlog_print_record(fd, num_ops, len, &read_type, &partial_buf, hdr, xhdrs); + error = xlog_print_record(log, fd, num_ops, len, &read_type, &partial_buf, + hdr, xhdrs, first_hdr_found); + first_hdr_found++; switch (error) { case 0: { blkno += BTOBB(len); @@ -1422,7 +1493,7 @@ blkno++; goto loop2; } - num_ops = xlog_print_rec_head(hdr, &len); + num_ops = xlog_print_rec_head(hdr, &len, first_hdr_found); blkno++; if (num_ops == ZEROED_LOG || @@ -1445,13 +1516,9 @@ } partial_log_read: - error= xlog_print_record(fd, - num_ops, - len, - &read_type, - &partial_buf, - (xlog_rec_header_t *)hbuf, - xhdrs); + error= xlog_print_record(log, fd, num_ops, len, &read_type, + &partial_buf, (xlog_rec_header_t *)hbuf, + xhdrs, first_hdr_found); if (read_type != FULL_READ) len -= read_type; read_type = FULL_READ; @@ -1522,7 +1589,11 @@ } int -xfs_efi_copy_format(char *buf, uint len, xfs_efi_log_format_t *dst_efi_fmt) +xfs_efi_copy_format( + char *buf, + uint len, + struct xfs_efi_log_format *dst_efi_fmt, + int continued) { uint i; uint nextents = ((xfs_efi_log_format_t *)buf)->efi_nextents; @@ -1530,7 +1601,7 @@ uint len32 = sizeof(xfs_efi_log_format_32_t) + (nextents - 1) * sizeof(xfs_extent_32_t); uint len64 = sizeof(xfs_efi_log_format_64_t) + (nextents - 1) * sizeof(xfs_extent_64_t); - if (len == dst_len) { + if (len == dst_len || continued) { memcpy((char *)dst_efi_fmt, buf, len); return 0; } else if (len == len32) { diff -Nru xfsprogs-3.1.9ubuntu2/logprint/log_print_all.c xfsprogs-3.2.1ubuntu1/logprint/log_print_all.c --- xfsprogs-3.1.9ubuntu2/logprint/log_print_all.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/logprint/log_print_all.c 2014-05-02 00:09:16.000000000 +0000 @@ -23,13 +23,13 @@ */ int xlog_print_find_oldest( - struct log *log, + struct xlog *log, xfs_daddr_t *last_blk) { xfs_buf_t *bp; xfs_daddr_t first_blk; uint first_half_cycle, last_half_cycle; - int error; + int error = 0; if (xlog_find_zeroed(log, &first_blk)) return 0; @@ -43,17 +43,14 @@ last_half_cycle = xlog_get_cycle(XFS_BUF_PTR(bp)); ASSERT(last_half_cycle != 0); - if (first_half_cycle == last_half_cycle) { /* all cycle nos are same */ + if (first_half_cycle == last_half_cycle) /* all cycle nos are same */ *last_blk = 0; - } else { /* have 1st and last; look for middle cycle */ + else /* have 1st and last; look for middle cycle */ error = xlog_find_cycle_start(log, bp, first_blk, last_blk, last_half_cycle); - if (error) - return error; - } xlog_put_bp(bp); - return 0; + return error; } void @@ -92,7 +89,6 @@ xfs_disk_dquot_t *ddq; f = (xfs_buf_log_format_t *)item->ri_buf[0].i_addr; - len = item->ri_buf[0].i_len; printf(" "); ASSERT(f->blf_type == XFS_LI_BUF); printf(_("BUF: #regs:%d start blkno:0x%llx len:%d bmap size:%d flags:0x%x\n"), @@ -122,6 +118,7 @@ be32_to_cpu(*(__be32 *)(p+56)), be32_to_cpu(*(__be32 *)(p+60))); } else if (be32_to_cpu(*(__be32 *)p) == XFS_AGI_MAGIC) { + int bucket, buckets; agi = (xfs_agi_t *)p; printf(_(" AGI Buffer: (XAGI)\n")); if (!print_buffer) @@ -137,6 +134,24 @@ be32_to_cpu(agi->agi_level), be32_to_cpu(agi->agi_freecount), be32_to_cpu(agi->agi_newino)); + if (len == 128) { + buckets = 17; + } else if (len == 256) { + buckets = 32 + 17; + } else { + buckets = XFS_AGI_UNLINKED_BUCKETS; + } + for (bucket = 0; bucket < buckets;) { + int col; + printf(_("bucket[%d - %d]: "), bucket, bucket+3); + for (col = 0; col < 4; col++, bucket++) { + if (bucket < buckets) { + printf("0x%x ", + be32_to_cpu(agi->agi_unlinked[bucket])); + } + } + printf("\n"); + } } else if (be32_to_cpu(*(__be32 *)p) == XFS_AGF_MAGIC) { agf = (xfs_agf_t *)p; printf(_(" AGF Buffer: (XAGF)\n")); @@ -243,7 +258,7 @@ (di->di_magic>>8) & 0xff, di->di_magic & 0xff, di->di_mode, di->di_version, di->di_format, di->di_onlink); printf(_(" uid:%d gid:%d nlink:%d projid:%u\n"), - di->di_uid, di->di_gid, di->di_nlink, xfs_get_projid(*di)); + di->di_uid, di->di_gid, di->di_nlink, xfs_get_projid(di)); printf(_(" atime:%d mtime:%d ctime:%d\n"), di->di_atime.t_sec, di->di_mtime.t_sec, di->di_ctime.t_sec); printf(_(" flushiter:%d\n"), di->di_flushiter); @@ -276,7 +291,8 @@ f->ilf_dsize); /* core inode comes 2nd */ - ASSERT(item->ri_buf[1].i_len == sizeof(xfs_icdinode_t)); + ASSERT(item->ri_buf[1].i_len == xfs_icdinode_size(1) || + item->ri_buf[1].i_len == xfs_icdinode_size(3)); xlog_recover_print_inode_core((xfs_icdinode_t *) item->ri_buf[1].i_addr); @@ -394,7 +410,7 @@ fprintf(stderr, _("%s: xlog_recover_print_efi: malloc failed\n"), progname); exit(1); } - if (xfs_efi_copy_format((char*)src_f, src_len, f)) { + if (xfs_efi_copy_format((char*)src_f, src_len, f, 0)) { free(f); return; } @@ -415,6 +431,21 @@ free(f); } +STATIC void +xlog_recover_print_icreate( + struct xlog_recover_item *item) +{ + struct xfs_icreate_log *icl; + + icl = (struct xfs_icreate_log *)item->ri_buf[0].i_addr; + + printf(_(" ICR: #ag: %d agbno: 0x%x len: %d\n" + " cnt: %d isize: %d gen: 0x%x\n"), + be32_to_cpu(icl->icl_ag), be32_to_cpu(icl->icl_agbno), + be32_to_cpu(icl->icl_length), be32_to_cpu(icl->icl_count), + be32_to_cpu(icl->icl_isize), be32_to_cpu(icl->icl_gen)); +} + void xlog_recover_print_logitem( xlog_recover_item_t *item) @@ -423,6 +454,9 @@ case XFS_LI_BUF: xlog_recover_print_buffer(item); break; + case XFS_LI_ICREATE: + xlog_recover_print_icreate(item); + break; case XFS_LI_INODE: xlog_recover_print_inode(item); break; @@ -454,6 +488,9 @@ case XFS_LI_BUF: printf("BUF"); break; + case XFS_LI_ICREATE: + printf("ICR"); + break; case XFS_LI_INODE: printf("INO"); break; diff -Nru xfsprogs-3.1.9ubuntu2/logprint/logprint.c xfsprogs-3.2.1ubuntu1/logprint/logprint.c --- xfsprogs-3.1.9ubuntu2/logprint/logprint.c 2009-02-17 01:14:58.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/logprint/logprint.c 2013-10-10 21:07:17.000000000 +0000 @@ -44,6 +44,7 @@ -c try to continue if error found in log\n\ -C copy the log from the filesystem to filename\n\ -d dump the log in log-record format\n\ + -e exit when an error is found in the log\n\ -f specified device is actually a file\n\ -l filename of external log\n\ -n don't try and interpret log data\n\ @@ -93,6 +94,10 @@ x.logBBsize = XFS_FSB_TO_BB(mp, sb->sb_logblocks); x.logBBstart = XFS_FSB_TO_DADDR(mp, sb->sb_logstart); + x.lbsize = BBSIZE; + if (xfs_sb_version_hassector(sb)) + x.lbsize <<= (sb->sb_logsectlog - BBSHIFT); + if (!x.logname && sb->sb_logstart == 0) { fprintf(stderr, _(" external log device not specified\n\n")); usage(); @@ -104,6 +109,7 @@ stat(x.dname, &s); x.logBBsize = s.st_size >> 9; x.logBBstart = 0; + x.lbsize = BBSIZE; } @@ -128,12 +134,13 @@ int c; int logfd; char *copy_file = NULL; - xlog_t log = {0}; + struct xlog log = {0}; xfs_mount_t mount; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); + memset(&mount, 0, sizeof(mount)); progname = basename(argv[0]); while ((c = getopt(argc, argv, "bC:cdefl:iqnors:tDVv")) != EOF) { @@ -214,6 +221,7 @@ exit(1); logstat(&mount); + libxfs_buftarg_init(&mount, x.ddev, x.logdev, x.rtdev); logfd = (x.logfd < 0) ? x.dfd : x.logfd; @@ -230,10 +238,11 @@ ASSERT(x.logBBsize <= INT_MAX); - log.l_dev = x.logdev; + log.l_dev = mount.m_logdev_targp; log.l_logsize = BBTOB(x.logBBsize); log.l_logBBstart = x.logBBstart; log.l_logBBsize = x.logBBsize; + log.l_sectBBsize = BTOBB(x.lbsize); log.l_mp = &mount; switch (print_operation) { diff -Nru xfsprogs-3.1.9ubuntu2/logprint/logprint.h xfsprogs-3.2.1ubuntu1/logprint/logprint.h --- xfsprogs-3.1.9ubuntu2/logprint/logprint.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/logprint/logprint.h 2014-05-02 00:09:16.000000000 +0000 @@ -34,12 +34,12 @@ /* exports */ extern char *trans_type[]; -extern void xlog_print_lseek(xlog_t *, int, xfs_daddr_t, int); +extern void xlog_print_lseek(struct xlog *, int, xfs_daddr_t, int); -extern void xfs_log_copy(xlog_t *, int, char *); -extern void xfs_log_dump(xlog_t *, int, int); -extern void xfs_log_print(xlog_t *, int, int); -extern void xfs_log_print_trans(xlog_t *, int); +extern void xfs_log_copy(struct xlog *, int, char *); +extern void xfs_log_dump(struct xlog *, int, int); +extern void xfs_log_print(struct xlog *, int, int); +extern void xfs_log_print_trans(struct xlog *, int); extern void print_xlog_record_line(void); extern void print_xlog_op_line(void); @@ -47,6 +47,6 @@ extern xfs_inode_log_format_t * xfs_inode_item_format_convert(char *, uint, xfs_inode_log_format_t *); -extern int xfs_efi_copy_format(char *, uint, xfs_efi_log_format_t *); +extern int xfs_efi_copy_format(char *, uint, xfs_efi_log_format_t *, int); #endif /* LOGPRINT_H */ diff -Nru xfsprogs-3.1.9ubuntu2/logprint/log_print_trans.c xfsprogs-3.2.1ubuntu1/logprint/log_print_trans.c --- xfsprogs-3.1.9ubuntu2/logprint/log_print_trans.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/logprint/log_print_trans.c 2013-10-10 21:07:17.000000000 +0000 @@ -30,7 +30,7 @@ int xlog_recover_do_trans( - xlog_t *log, + struct xlog *log, xlog_recover_t *trans, int pass) { @@ -40,7 +40,7 @@ void xfs_log_print_trans( - xlog_t *log, + struct xlog *log, int print_block_start) { xfs_daddr_t head_blk, tail_blk; @@ -68,6 +68,24 @@ if (head_blk == tail_blk) return; + + /* + * Version 5 superblock log feature mask validation. We know the + * log is dirty so check if there are any unknown log features + * in what we need to recover. If there are unknown features + * (e.g. unsupported transactions) then warn about it. + */ + if (XFS_SB_VERSION_NUM(&log->l_mp->m_sb) == XFS_SB_VERSION_5 && + xfs_sb_has_incompat_log_feature(&log->l_mp->m_sb, + XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN)) { + printf(_( +"Superblock has unknown incompatible log features (0x%x) enabled.\n" +"Output may be incomplete or inaccurate. It is recommended that you\n" +"upgrade your xfsprogs installation to match the filesystem features.\n"), + (log->l_mp->m_sb.sb_features_log_incompat & + XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN)); + } + if ((error = xlog_do_recovery_pass(log, head_blk, tail_blk, XLOG_RECOVER_PASS1))) { fprintf(stderr, _("%s: failed in xfs_do_recovery_pass, error: %d\n"), progname, error); diff -Nru xfsprogs-3.1.9ubuntu2/ltmain.sh xfsprogs-3.2.1ubuntu1/ltmain.sh --- xfsprogs-3.1.9ubuntu2/ltmain.sh 2012-01-31 09:53:45.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/ltmain.sh 2013-02-14 01:41:01.000000000 +0000 @@ -70,7 +70,7 @@ # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1 +# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.2 # automake: $automake_version # autoconf: $autoconf_version # @@ -80,7 +80,7 @@ PROGRAM=libtool PACKAGE=libtool -VERSION="2.4.2 Debian-2.4.2-1" +VERSION="2.4.2 Debian-2.4.2-1.2" TIMESTAMP="" package_revision=1.3337 diff -Nru xfsprogs-3.1.9ubuntu2/m4/libtool.m4 xfsprogs-3.2.1ubuntu1/m4/libtool.m4 --- xfsprogs-3.1.9ubuntu2/m4/libtool.m4 2013-12-18 17:13:26.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/m4/libtool.m4 2014-08-08 11:52:02.000000000 +0000 @@ -1324,7 +1324,14 @@ LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) - LD="${LD-ld} -m elf_i386" + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac ;; powerpc64le-*) LD="${LD-ld} -m elf32lppclinux" @@ -1694,7 +1701,8 @@ ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else @@ -2518,17 +2526,6 @@ esac ;; -gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no @@ -2645,7 +2642,7 @@ ;; # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no @@ -3261,10 +3258,6 @@ fi ;; -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - haiku*) lt_cv_deplibs_check_method=pass_all ;; @@ -3303,7 +3296,7 @@ ;; # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; @@ -4055,7 +4048,7 @@ ;; esac ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler @@ -4354,7 +4347,7 @@ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) @@ -6247,9 +6240,6 @@ _LT_TAGVAR(ld_shlibs, $1)=yes ;; - gnu*) - ;; - haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes @@ -6411,7 +6401,7 @@ _LT_TAGVAR(inherit_rpath, $1)=yes ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler diff -Nru xfsprogs-3.1.9ubuntu2/m4/package_libcdev.m4 xfsprogs-3.2.1ubuntu1/m4/package_libcdev.m4 --- xfsprogs-3.1.9ubuntu2/m4/package_libcdev.m4 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/m4/package_libcdev.m4 2013-10-10 21:07:17.000000000 +0000 @@ -170,3 +170,18 @@ AC_SUBST(have_sync_file_range) ]) +# +# Check if we have a readdir libc call +# +AC_DEFUN([AC_HAVE_READDIR], + [ AC_MSG_CHECKING([for readdir]) + AC_TRY_LINK([ +#include + ], [ + readdir(0); + ], have_readdir=yes + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + AC_SUBST(have_readdir) + ]) + diff -Nru xfsprogs-3.1.9ubuntu2/m4/package_types.m4 xfsprogs-3.2.1ubuntu1/m4/package_types.m4 --- xfsprogs-3.1.9ubuntu2/m4/package_types.m4 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/m4/package_types.m4 2013-10-10 21:07:17.000000000 +0000 @@ -39,3 +39,14 @@ __u32 u32; ], AC_DEFINE(HAVE___U32) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no)) ]) +# +# Check if we have umode_t +# +AC_DEFUN([AC_TYPE_UMODE_T], + [ AC_MSG_CHECKING([for umode_t]) + AC_TRY_COMPILE([ +#include + ], [ + umode_t umode; + ], AC_DEFINE(HAVE_UMODE_T) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no)) + ]) diff -Nru xfsprogs-3.1.9ubuntu2/Makefile xfsprogs-3.2.1ubuntu1/Makefile --- xfsprogs-3.1.9ubuntu2/Makefile 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/Makefile 2013-10-10 21:07:16.000000000 +0000 @@ -29,7 +29,8 @@ CONFIGURE = aclocal.m4 configure config.guess config.sub install-sh ltmain.sh LSRCFILES = configure.ac release.sh README VERSION $(CONFIGURE) - +SRCTARINC = m4/libtool.m4 m4/lt~obsolete.m4 m4/ltoptions.m4 m4/ltsugar.m4 \ + m4/ltversion.m4 po/xfsprogs.pot .gitcensus $(CONFIGURE) LDIRT = config.log .ltdep .dep config.status config.cache confdefs.h \ conftest* built .census install.* install-dev.* *.gz \ autom4te.cache/* libtool include/builddefs include/platform_defs.h @@ -118,7 +119,7 @@ $(Q)rm -f $(LDIRT) realclean: distclean - $(Q)rm -f $(CONFIGURE) + $(Q)rm -f $(CONFIGURE) .gitcensus # # All this gunk is to allow for a make dist on an unconfigured tree @@ -134,17 +135,22 @@ ifeq ($(HAVE_BUILDDEFS), no) $(Q)$(MAKE) $(MAKEOPTS) -C . $@ else - $(Q)$(MAKE) $(MAKEOPTS) $(SRCDIR) + # need to build translations before the source tarball $(Q)$(MAKE) $(MAKEOPTS) -C po - $(Q)$(MAKE) $(MAKEOPTS) source-link + $(Q)$(MAKE) $(MAKEOPTS) $(SRCDIR) $(Q)cd $(SRCDIR) && dpkg-buildpackage endif -$(SRCDIR) : $(_FORCE) +$(SRCDIR) : $(_FORCE) $(SRCTAR) rm -fr $@ - mkdir -p $@ + $(Q)$(TAR) -zxvf $(SRCTAR) -$(SRCTAR) : default $(SRCDIR) - $(Q)$(MAKE) $(MAKEOPTS) source-link - unset TAPE; $(TAR) -cf - $(SRCDIR) | $(ZIP) --best > $@ && \ +$(SRCTAR) : default $(SRCTARINC) .gitcensus + $(Q)$(TAR) --transform "s,^,$(SRCDIR)/," -zcf $(SRCDIR).tar.gz \ + `cat .gitcensus` $(SRCTARINC) echo Wrote: $@ + +.gitcensus: $(_FORCE) + $(Q)if test -d .git; then \ + git ls-files > .gitcensus && echo "new .gitcensus"; \ + fi diff -Nru xfsprogs-3.1.9ubuntu2/man/man5/projects.5 xfsprogs-3.2.1ubuntu1/man/man5/projects.5 --- xfsprogs-3.1.9ubuntu2/man/man5/projects.5 2009-04-27 05:48:02.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man5/projects.5 2013-06-06 22:52:59.000000000 +0000 @@ -1,6 +1,6 @@ .TH projects 5 .SH NAME -projects \- persistent project root defintion +projects \- persistent project root definition .SH DESCRIPTION The .I /etc/projects diff -Nru xfsprogs-3.1.9ubuntu2/man/man5/xfs.5 xfsprogs-3.2.1ubuntu1/man/man5/xfs.5 --- xfsprogs-3.1.9ubuntu2/man/man5/xfs.5 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man5/xfs.5 2014-06-19 22:42:17.000000000 +0000 @@ -1,6 +1,6 @@ .TH xfs 5 .SH NAME -xfs \- layout of the XFS filesystem +xfs \- layout and mount options for the XFS filesystem .SH DESCRIPTION An XFS filesystem can reside on a regular disk partition or on a logical volume. @@ -98,9 +98,210 @@ .BR open_by_handle (3)) interfaces. .SH MOUNT OPTIONS -Refer to the +The following XFS-specific mount options may be used when mounting +an XFS filesystem. Other generic options may be used as well; refer to the .BR mount (8) -manual entry for descriptions of the individual XFS mount options. +manual page for more details. +.TP +.B allocsize=size +Sets the buffered I/O end-of-file preallocation size when +doing delayed allocation writeout. Valid values for this +option are page size (typically 4KiB) through to 1GiB, +inclusive, in power-of-2 increments. +.sp +The default behavior is for dynamic end-of-file +preallocation size, which uses a set of heuristics to +optimise the preallocation size based on the current +allocation patterns within the file and the access patterns +to the file. Specifying a fixed allocsize value turns off +the dynamic behavior. +.TP +.BR attr2 | noattr2 +The options enable/disable an "opportunistic" improvement to +be made in the way inline extended attributes are stored +on-disk. When the new form is used for the first time when +attr2 is selected (either when setting or removing extended +attributes) the on-disk superblock feature bit field will be +updated to reflect this format being in use. +.sp +The default behavior is determined by the on-disk feature +bit indicating that attr2 behavior is active. If either +mount option it set, then that becomes the new default used +by the filesystem. +.sp +CRC enabled filesystems always use the attr2 format, and so +will reject the noattr2 mount option if it is set. +.TP +.BR barrier | nobarrier +Enables/disables the use of block layer write barriers for +writes into the journal and for data integrity operations. +This allows for drive level write caching to be enabled, for +devices that support write barriers. +.sp +Barriers are enabled by default. +.TP +.BR discard | nodiscard +Enable/disable the issuing of commands to let the block +device reclaim space freed by the filesystem. This is +useful for SSD devices, thinly provisioned LUNs and virtual +machine images, but may have a performance impact. +.sp +Note: It is currently recommended that you use the fstrim +application to discard unused blocks rather than the discard +mount option because the performance impact of this option +is quite severe. For this reason, nodiscard is the default. +.TP +.BR grpid | bsdgroups | nogrpid | sysvgroups +These options define what group ID a newly created file +gets. When grpid is set, it takes the group ID of the +directory in which it is created; otherwise it takes the +fsgid of the current process, unless the directory has the +setgid bit set, in which case it takes the gid from the +parent directory, and also gets the setgid bit set if it is +a directory itself. +.TP +.B filestreams +Make the data allocator use the filestreams allocation mode +across the entire filesystem rather than just on directories +configured to use it. +.TP +.BR ikeep | noikeep +When ikeep is specified, XFS does not delete empty inode +clusters and keeps them around on disk. When noikeep is +specified, empty inode clusters are returned to the free +space pool. noikeep is the default. +.TP +.BR inode32 | inode64 +When inode32 is specified, it indicates that XFS limits +inode creation to locations which will not result in inode +numbers with more than 32 bits of significance. +.sp +When inode64 is specified, it indicates that XFS is allowed +to create inodes at any location in the filesystem, +including those which will result in inode numbers occupying +more than 32 bits of significance. +.sp +inode32 is provided for backwards compatibility with older +systems and applications, since 64 bits inode numbers might +cause problems for some applications that cannot handle +large inode numbers. If applications are in use which do +not handle inode numbers bigger than 32 bits, the inode32 +option should be specified. +.sp +For kernel v3.7 and later, inode64 is the default. +.TP +.BR largeio | nolargeio +If "nolargeio" is specified, the optimal I/O reported in +st_blksize by stat(2) will be as small as possible to allow +user applications to avoid inefficient read/modify/write +I/O. This is typically the page size of the machine, as +this is the granularity of the page cache. +.sp +If "largeio" specified, a filesystem that was created with a +"swidth" specified will return the "swidth" value (in bytes) +in st_blksize. If the filesystem does not have a "swidth" +specified but does specify an "allocsize" then "allocsize" +(in bytes) will be returned instead. Otherwise the behavior +is the same as if "nolargeio" was specified. nolargeio +is the default. +.TP +.B logbufs=value +Set the number of in-memory log buffers. Valid numbers +range from 2\(en8 inclusive. +.sp +The default value is 8 buffers. +.sp +If the memory cost of 8 log buffers is too high on small +systems, then it may be reduced at some cost to performance +on metadata intensive workloads. The logbsize option below +controls the size of each buffer and so is also relevant to +this case. +.TP +.B logbsize=value +Set the size of each in-memory log buffer. The size may be +specified in bytes, or in kibibytes (KiB) with a "k" suffix. +Valid sizes for version 1 and version 2 logs are 16384 (value=16k) +and 32768 (value=32k). Valid sizes for version 2 logs also +include 65536 (value=64k), 131072 (value=128k) and 262144 (value=256k). The +logbsize must be an integer multiple of the log +stripe unit configured at mkfs time. +.sp +The default value for version 1 logs is 32768, while the +default value for version 2 logs is MAX(32768, log_sunit). +.TP +.BR logdev=device and rtdev=device +Use an external log (metadata journal) and/or real-time device. +An XFS filesystem has up to three parts: a data section, a log +section, and a real-time section. The real-time section is +optional, and the log section can be separate from the data +section or contained within it. +.TP +.B noalign +Data allocations will not be aligned at stripe unit +boundaries. This is only relevant to filesystems created +with non-zero data alignment parameters (sunit, swidth) by +mkfs. +.TP +.B norecovery +The filesystem will be mounted without running log recovery. +If the filesystem was not cleanly unmounted, it is likely to +be inconsistent when mounted in "norecovery" mode. +Some files or directories may not be accessible because of this. +Filesystems mounted "norecovery" must be mounted read-only or +the mount will fail. +.TP +.B nouuid +Don't check for double mounted file systems using the file +system uuid. This is useful to mount LVM snapshot volumes, +and often used in combination with "norecovery" for mounting +read-only snapshots. +.TP +.B noquota +Forcibly turns off all quota accounting and enforcement +within the filesystem. +.TP +.B uquota/usrquota/uqnoenforce/quota +User disk quota accounting enabled, and limits (optionally) +enforced. Refer to xfs_quota(8) for further details. +.TP +.B gquota/grpquota/gqnoenforce +Group disk quota accounting enabled and limits (optionally) +enforced. Refer to xfs_quota(8) for further details. +.TP +.B pquota/prjquota/pqnoenforce +Project disk quota accounting enabled and limits (optionally) +enforced. Refer to xfs_quota(8) for further details. +.TP +.BR sunit=value " and " swidth=value +Used to specify the stripe unit and width for a RAID device +or a stripe volume. "value" must be specified in 512-byte +block units. These options are only relevant to filesystems +that were created with non-zero data alignment parameters. +.sp +The sunit and swidth parameters specified must be compatible +with the existing filesystem alignment characteristics. In +general, that means the only valid changes to sunit are +increasing it by a power-of-2 multiple. Valid swidth values +are any integer multiple of a valid sunit value. +.sp +Typically the only time these mount options are necessary if +after an underlying RAID device has had it's geometry +modified, such as adding a new disk to a RAID5 lun and +reshaping it. +.TP +.B swalloc +Data allocations will be rounded up to stripe width boundaries +when the current end of file is being extended and the file +size is larger than the stripe width size. +.TP +.B wsync +When specified, all filesystem namespace operations are +executed synchronously. This ensures that when the namespace +operation (create, unlink, etc) completes, the change to the +namespace is on stable storage. This is useful in HA setups +where failover must not result in clients seeing +inconsistent namespace presentation during or after a +failover event. .SH SEE ALSO .BR xfsctl (3), .BR mount (8), diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/fsck.xfs.8 xfsprogs-3.2.1ubuntu1/man/man8/fsck.xfs.8 --- xfsprogs-3.1.9ubuntu2/man/man8/fsck.xfs.8 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/fsck.xfs.8 2014-05-02 00:09:16.000000000 +0000 @@ -20,8 +20,6 @@ If you wish to check the consistency of an XFS filesystem, or repair a damaged or corrupt XFS filesystem, see -.BR xfs_check (8) -and .BR xfs_repair (8). . .SH FILES @@ -30,5 +28,4 @@ .BR fsck (8), .BR fstab (5), .BR xfs (5), -.BR xfs_check (8), .BR xfs_repair (8). diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/mkfs.xfs.8 xfsprogs-3.2.1ubuntu1/man/man8/mkfs.xfs.8 --- xfsprogs-3.1.9ubuntu2/man/man8/mkfs.xfs.8 2010-11-09 11:17:04.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/mkfs.xfs.8 2014-06-19 22:42:17.000000000 +0000 @@ -7,6 +7,9 @@ .B \-b .I block_size ] [ +.B \-m +.I global_metadata_options +] [ .B \-d .I data_section_options ] [ @@ -40,6 +43,8 @@ .B \-K ] .I device +.br +.B mkfs.xfs \-V .SH DESCRIPTION .B mkfs.xfs constructs an XFS filesystem by writing on a special @@ -123,6 +128,48 @@ maximum is 65536 (64 KiB). XFS on Linux currently only supports pagesize or smaller blocks. .TP +.BI \-m " global_metadata_options" +These options specify metadata format options that either apply to the entire +filesystem or aren't easily characterised by a specific functionality group. The +valid +.I global_metadata_options +are: +.RS 1.2i +.TP +.BI crc= value +This is used to create a filesystem which maintains and checks CRC information +in all metadata objects on disk. The value is either 0 to disable the feature, +or 1 to enable the use of CRCs. +.IP +CRCs enable enhanced error detection due to hardware issues, whilst the format +changes also improves crash recovery algorithms and the ability of various tools +to validate and repair metadata corruptions when they are found. The CRC +algorithm used is CRC32c, so the overhead is dependent on CPU architecture as +some CPUs have hardware acceleration of this algorithm. Typically the overhead +of calculating and checking the CRCs is not noticable in normal operation. +.IP +By default, +.B mkfs.xfs +will not enable metadata CRCs. +.TP +.BI finobt= value +This option enables the use of a separate free inode btree index in each +allocation group. The value is either 0 to disable the feature, or 1 to create +a free inode btree in each allocation group. +.IP +The free inode btree mirrors the existing allocated inode btree index which +indexes both used and free inodes. The free inode btree does not index used +inodes, allowing faster, more consistent inode allocation performance as +filesystems age. +.IP +By default, +.B mkfs.xfs +will not create free inode btrees. This feature is also currently only available +for filesystems created with the +.B \-m crc=1 +option set. +.RE +.TP .BI \-d " data_section_options" These options specify the location, size, and other parameters of the data section of the filesystem. The valid @@ -242,6 +289,11 @@ and .B swidth values. +.TP +.BI noalign +This option disables automatic geometry detection and creates the filesystem +without stripe geometry alignment even if the underlying storage device provides +this information. .RE .TP .B \-f @@ -279,7 +331,7 @@ .BR log= , or as the number fitting in a filesystem block with .BR perblock= . -The mininum (and default) +The minimum (and default) .I value is 256 bytes. The maximum @@ -297,7 +349,7 @@ .B mkfs.xfs will attempt to choose a size such that inode numbers will be < 32 bits. If an inode size -is specified, or if a filesystem is sufficently large, +is specified, or if a filesystem is sufficiently large, .B mkfs.xfs will warn if this will create inode numbers > 32 significant bits. @@ -355,7 +407,8 @@ This is used to enable 32bit quota project identifiers. The .I value is either 0 or 1, with 1 signifying that 32bit projid are to be enabled. -If the value is omitted, 0 is assumed. +If the value is omitted, 1 is assumed. (This default changed +in release version 3.2.0.) .RE .TP .BI \-l " log_section_options" @@ -450,7 +503,7 @@ This changes the method of logging various persistent counters in the superblock. Under metadata intensive workloads, these counters are updated and logged frequently enough that the superblock -updates become a serialisation point in the filesystem. The +updates become a serialization point in the filesystem. The .I value can be either 0 or 1. .IP @@ -510,6 +563,25 @@ are stored in directories using the case they were created with. .IP Note: Version 1 directories are not supported. +.TP +.BI ftype= value +This feature allows the inode type to be stored in the directory +structure so that the +.BR readdir (3) +and +.BR getdents (2) +do not need to look up the inode to determine the inode type. + +The +.I value +is either 0 or 1, with 1 signifiying that filetype information +will be stored in the directory structure. The default value is 0. + +When CRCs are enabled via +.B \-m crc=1, +the ftype functionality is always enabled. This feature can not be turned +off for such filesystem configurations. +.IP .RE .TP .BI \-p " protofile" @@ -693,6 +765,10 @@ This suboption is only needed if the real-time section of the filesystem should occupy less space than the size of the partition or logical volume containing the section. +.TP +.BI noalign +This option disables stripe size detection, enforcing a realtime device with no +stripe geometry. .RE .TP .BI \-s " sector_size" @@ -728,6 +804,9 @@ .TP .B \-K Do not attempt to discard blocks at mkfs time. +.TP +.B \-V +Prints the version number and exits. .SH SEE ALSO .BR xfs (5), .BR mkfs (8), diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_admin.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_admin.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_admin.8 2010-11-09 11:17:04.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_admin.8 2013-06-06 22:52:59.000000000 +0000 @@ -15,6 +15,8 @@ .I uuid ] .I device +.br +.B xfs_admin \-V .SH DESCRIPTION .B xfs_admin uses the @@ -97,6 +99,9 @@ may also be .BR generate , which will generate a new UUID for the filesystem. +.TP +.B \-V +Prints the version number and exits. .PP The .BR mount (8) diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_bmap.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_bmap.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_bmap.8 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_bmap.8 2013-06-06 22:52:59.000000000 +0000 @@ -10,6 +10,8 @@ .I num_extents ] .I file +.br +.B xfs_bmap \-V .SH DESCRIPTION .B xfs_bmap prints the map of disk blocks used by files in an XFS filesystem. @@ -91,6 +93,9 @@ option will print out the .I flags legend. +.TP +.B \-V +Prints the version number and exits. .SH SEE ALSO .BR xfs_fsr (8), .BR xfs (5). diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_check.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_check.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_check.8 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_check.8 1970-01-01 00:00:00.000000000 +0000 @@ -1,198 +0,0 @@ -.TH xfs_check 8 -.SH NAME -xfs_check \- check XFS filesystem consistency -.SH SYNOPSIS -.B xfs_check -[ -.B \-i -.I ino -] ... [ -.B \-b -.I bno -] ... [ -.B \-f -] [ -.B \-s -] [ -.B \-v -] [ -.B \-l -.I logdev -] -.I device -.SH DESCRIPTION -.B xfs_check -checks whether an XFS filesystem is consistent. -It is normally run only when there is reason to believe that the -filesystem has a consistency problem. -The filesystem to be checked is specified by the -.I device -argument, which should be the disk or volume device for the filesystem. -Filesystems stored in files can also be checked, using the -.B \-f -flag. The filesystem should normally be unmounted or read-only -during the execution of -.BR xfs_check . -Otherwise, spurious problems are reported. -.PP -Note that using -.B xfs_check -is NOT recommended. Please use -.BR xfs_repair " " \-n -instead, for better scalability and speed. -.SH -OPTIONS -.TP -.B \-f -Specifies that the filesystem image to be processed is stored in a -regular file at -.I device -(see the -.BR mkfs.xfs "(8) " \-d -.I file -option). This might happen if an image copy -of a filesystem has been made into an ordinary file. -.TP -.BI \-l " logdev" -Specifies the device where the filesystem's external log resides. -Only for those filesystems which use an external log. See the -.BR mkfs.xfs "(8) " \-l -option, and refer to -.BR xfs (5) -for a detailed description of the XFS log. -.TP -.B \-s -Specifies that only serious errors should be reported. -Serious errors are those that make it impossible to find major data -structures in the filesystem. This option can be used to cut down the -amount of output when there is a serious problem, when the output -might make it difficult to see what the real problem is. -.TP -.B \-v -Specifies verbose output; it is impossibly long for a -reasonably-sized filesystem. -This option is intended for internal use only. -.TP -.BI \-i " ino" -Specifies verbose behavior for the specified inode -.IR ino . -For instance, it can be used to locate all the blocks -associated with a given inode. -.TP -.BI \-b " bno" -Specifies verbose behavior for the specific filesystem block at -.IR bno . -For instance, it can be used to determine what a specific block -is used for. The block number is a "file system block number". -Conversion between disk addresses (i.e. addresses reported by -.BR xfs_bmap (8)) -and file system blocks may be accomplished using -.BR xfs_db "(8)'s " convert -command. -.PP -Any output that is produced when -.B xfs_check -is not run in verbose mode indicates that the filesystem has an -inconsistency. The filesystem can be repaired using either -.BR xfs_repair (8) -to fix the filesystem in place, or by using -.BR xfsdump (8) -and -.BR mkfs.xfs (8) -to dump the filesystem, make a new filesystem, then use -.BR xfsrestore (8) -to restore the data onto the new filesystem. -Note that xfsdump may fail on a corrupt filesystem. -However, if the filesystem is mountable, xfsdump can -be used to try and save important data before -repairing the filesystem with xfs_repair. -If the filesystem is not mountable though, xfs_repair is -the only viable option. -.SH DIAGNOSTICS -If the filesystem is completely corrupt, a core dump might -be produced instead of the message -.RS -.I device -.B is not a valid filesystem -.RE -.PP -If the filesystem is very large (has many files) then -.B xfs_check -might run out of memory. In this case the message -.RS -.B out of memory -.RE -is printed. -.PP -The following is a description of the most likely problems and the associated -messages. -Most of the diagnostics produced are only meaningful with an understanding -of the structure of the filesystem. -.TP -.BI "agf_freeblks " n ", counted " m " in ag " a -The freeblocks count in the allocation group header for allocation group -.I a -doesn't match the number of blocks counted free. -.TP -.BI "agf_longest " n ", counted " m " in ag " a -The longest free extent in the allocation group header for allocation group -.I a -doesn't match the longest free extent found in the allocation group. -.TP -.BI "agi_count " n ", counted " m " in ag " a -The allocated inode count in the allocation group header for allocation group -.I a -doesn't match the number of inodes counted in the allocation group. -.TP -.BI "agi_freecount " n ", counted " m " in ag " a -The free inode count in the allocation group header for allocation group -.I a -doesn't match the number of inodes counted free in the allocation group. -.TP -.BI "block " a/b " expected inum 0 got " i -The block number is specified as a pair -(allocation group number, block in the allocation group). -The block is used multiple times (shared), between multiple inodes. -This message usually follows a message of the next type. -.TP -.BI "block " a/b " expected type unknown got " y -The block is used multiple times (shared). -.TP -.BI "block " a/b " type unknown not expected -The block is unaccounted for (not in the freelist and not in use). -.TP -.BI "link count mismatch for inode " nnn " (name " xxx "), nlink " m ", counted " n -The inode has a bad link count (number of references in directories). -.TP -.BI "rtblock " b " expected inum 0 got " i -The block is used multiple times (shared), between multiple inodes. -This message usually follows a message of the next type. -.TP -.BI "rtblock " b " expected type unknown got " y -The real-time block is used multiple times (shared). -.TP -.BI "rtblock " b " type unknown not expected -The real-time block is unaccounted for (not in the freelist and not in use). -.TP -.BI "sb_fdblocks " n ", counted " m -The number of free data blocks recorded -in the superblock doesn't match the number counted free in the filesystem. -.TP -.BI "sb_frextents " n ", counted " m -The number of free real-time extents recorded -in the superblock doesn't match the number counted free in the filesystem. -.TP -.BI "sb_icount " n ", counted " m -The number of allocated inodes recorded -in the superblock doesn't match the number allocated in the filesystem. -.TP -.BI "sb_ifree " n ", counted " m -The number of free inodes recorded -in the superblock doesn't match the number free in the filesystem. -.SH SEE ALSO -.BR mkfs.xfs (8), -.BR xfsdump (8), -.BR xfsrestore (8), -.BR xfs_ncheck (8), -.BR xfs_repair (8), -.BR xfs (5). diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_copy.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_copy.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_copy.8 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_copy.8 2013-06-06 22:52:59.000000000 +0000 @@ -13,6 +13,8 @@ [ .I target2 \&... ] +.br +.B xfs_copy \-V .SH DESCRIPTION .B xfs_copy copies an XFS filesystem to one or more targets in parallel (see @@ -87,6 +89,9 @@ if the default location of .I /var/tmp/xfs_copy.log.XXXXXX is not desired. +.TP +.B \-V +Prints the version number and exits. .SH DIAGNOSTICS .B xfs_copy reports errors to both diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_db.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_db.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_db.8 2010-11-09 11:17:04.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_db.8 2014-06-19 22:42:17.000000000 +0000 @@ -38,8 +38,7 @@ on the command line. Multiple .B \-c arguments may be given. The commands are run in the sequence given, -then the program exits. This is the mechanism used to implement -.BR xfs_check (8). +then the program exits. .TP .B \-f Specifies that the filesystem image to be processed is stored in a @@ -56,15 +55,12 @@ .B \-F Specifies that we want to continue even if the superblock magic is not correct. For use in -.BR xfs_check -and .BR xfs_metadump . .TP .B \-i Allows execution on a mounted filesystem, provided it is mounted read-only. -Useful for shell scripts such as -.BR xfs_check (8), -which must only operate on filesystems in a guarenteed consistent state +Useful for shell scripts +which must only operate on filesystems in a guaranteed consistent state (either unmounted or mounted read-only). These semantics are slightly different to that of the .B -r @@ -103,7 +99,7 @@ commands. .TP .B \-V -Prints out the current version number and exits. +Prints the version number and exits. .SH CONCEPTS .B xfs_db commands can be broken up into two classes. Most commands are for @@ -204,9 +200,7 @@ Get block usage and check filesystem consistency. The information is saved for use by a subsequent .BR blockuse ", " ncheck ", or " blocktrash -command. See -.BR xfs_check (8) -for more information. +command. .RS 1.0i .TP 0.4i .B \-b @@ -244,7 +238,7 @@ This command is available only in debugging versions of .BR xfs_db . It is useful for testing -.BR xfs_repair "(8) and " xfs_check (8). +.BR xfs_repair "(8). .RS 1.0i .TP 0.4i .BR \-0 " | " -1 " | " -2 " | " -3 @@ -960,12 +954,12 @@ (1 if the extent is unwritten). .TP .B keys -[nonleaf blocks only] array of key records. These are the first key +[non-leaf blocks only] array of key records. These are the first key value of each block in the level below this one. Each record contains .BR startoff . .TP .B ptrs -[nonleaf blocks only] array of child block pointers. +[non-leaf blocks only] array of child block pointers. Each pointer is a filesystem block number to the next level in the Btree. .PD .RE @@ -975,7 +969,7 @@ allocation Btree for each allocation group. The root block of this Btree is designated by the .B bnoroot -field in the coresponding AGF block. +field in the corresponding AGF block. The blocks are linked to sibling left and right blocks at each level, as well as by pointers from parent to child blocks. Each block has the following fields: @@ -1004,14 +998,14 @@ .BR blockcount . .TP .B keys -[nonleaf blocks only] array of key records. These are the first value +[non-leaf blocks only] array of key records. These are the first value of each block in the level below this one. Each record contains .B startblock and .BR blockcount . .TP .B ptrs -[nonleaf blocks only] array of child block pointers. Each pointer is a +[non-leaf blocks only] array of child block pointers. Each pointer is a block number within the allocation group to the next level in the Btree. .PD .RE @@ -1021,7 +1015,7 @@ allocation Btree for each allocation group. The root block of this Btree is designated by the .B cntroot -field in the coresponding AGF block. The blocks are linked to sibling +field in the corresponding AGF block. The blocks are linked to sibling left and right blocks at each level, as well as by pointers from parent to child blocks. Each block has the following fields: .RS 1.4i @@ -1049,14 +1043,14 @@ .BR blockcount . .TP .B keys -[nonleaf blocks only] array of key records. These are the first value +[non-leaf blocks only] array of key records. These are the first value of each block in the level below this one. Each record contains .B blockcount and .BR startblock . .TP .B ptrs -[nonleaf blocks only] array of child block pointers. Each pointer is a +[non-leaf blocks only] array of child block pointers. Each pointer is a block number within the allocation group to the next level in the Btree. .PD .RE @@ -1368,7 +1362,7 @@ There is one set of filesystem blocks forming the inode allocation Btree for each allocation group. The root block of this Btree is designated by the .B root -field in the coresponding AGI block. +field in the corresponding AGI block. The blocks are linked to sibling left and right blocks at each level, as well as by pointers from parent to child blocks. Each block has the following fields: @@ -1400,12 +1394,12 @@ bitmap, LSB corresponds to inode 0. .TP .B keys -[nonleaf blocks only] array of key records. These are the first value of each +[non-leaf blocks only] array of key records. These are the first value of each block in the level below this one. Each record contains .BR startino . .TP .B ptrs -[nonleaf blocks only] array of child block pointers. Each pointer is a +[non-leaf blocks only] array of child block pointers. Each pointer is a block number within the allocation group to the next level in the Btree. .PD .RE @@ -1856,12 +1850,60 @@ Many messages can come from the .B check .RB ( blockget ) -command; these are documented in -.BR xfs_check (8). +command. +If the filesystem is completely corrupt, a core dump might +be produced instead of the message +.RS +.I device +.B is not a valid filesystem +.RE +.PP +If the filesystem is very large (has many files) then +.B check +might run out of memory. In this case the message +.RS +.B out of memory +.RE +is printed. +.PP +The following is a description of the most likely problems and the associated +messages. +Most of the diagnostics produced are only meaningful with an understanding +of the structure of the filesystem. +.TP +.BI "agf_freeblks " n ", counted " m " in ag " a +The freeblocks count in the allocation group header for allocation group +.I a +doesn't match the number of blocks counted free. +.TP +.BI "agf_longest " n ", counted " m " in ag " a +The longest free extent in the allocation group header for allocation group +.I a +doesn't match the longest free extent found in the allocation group. +.TP +.BI "agi_count " n ", counted " m " in ag " a +The allocated inode count in the allocation group header for allocation group +.I a +doesn't match the number of inodes counted in the allocation group. +.TP +.BI "agi_freecount " n ", counted " m " in ag " a +The free inode count in the allocation group header for allocation group +.I a +doesn't match the number of inodes counted free in the allocation group. +.TP +.BI "block " a/b " expected inum 0 got " i +The block number is specified as a pair +(allocation group number, block in the allocation group). +The block is used multiple times (shared), between multiple inodes. +This message usually follows a message of the next type. +.TP +.BI "block " a/b " expected type unknown got " y +The block is used multiple times (shared). +.TP +.BI "block " a/b " type unknown not expected .SH SEE ALSO .BR mkfs.xfs (8), .BR xfs_admin (8), -.BR xfs_check (8), .BR xfs_copy (8), .BR xfs_logprint (8), .BR xfs_metadump (8), diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_estimate.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_estimate.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_estimate.8 2009-05-06 01:57:52.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_estimate.8 2013-06-06 22:52:59.000000000 +0000 @@ -3,8 +3,10 @@ xfs_estimate \- estimate the space that an XFS filesystem will take .SH SYNOPSIS .nf -\f3xfs_estimate\f1 [ \f3\-h?\f1 ] [ \f3\-b\f1 blocksize ] [ \f3\-i\f1 logsize ] +\f3xfs_estimate\f1 [ \f3\-h\f1 ] [ \f3\-b\f1 blocksize ] [ \f3\-i\f1 logsize ] [ \f3\-e\f1 logsize ] [ \f3\-v\f1 ] directory ... +.br +.B xfs_estimate \-V .fi .SH DESCRIPTION For each \f2directory\f1 argument, @@ -51,9 +53,6 @@ .B \-h Display usage message. .TP -.B \-? -Display usage message. -.TP \f3\-i, \-e\f1 \f2logsize\f1 Use .I logsize @@ -77,6 +76,9 @@ .IP requests an estimate of the space required by the directory / on an XFS filesystem using an internal log of 1 megabyte. +.TP +.B \-V +Print the version number and exits. .SH EXAMPLES .nf .sp 8v diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_freeze.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_freeze.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_freeze.8 2009-02-17 01:14:58.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_freeze.8 2013-06-06 22:52:59.000000000 +0000 @@ -2,10 +2,15 @@ .SH NAME xfs_freeze \- suspend access to an XFS filesystem .SH SYNOPSIS -.B xfs_freeze \-f +.B xfs_freeze +[ +.B \-f | .B \-u +] .I mount-point +.br +.B xfs_freeze \-V .fi .SH DESCRIPTION .B xfs_freeze @@ -25,6 +30,7 @@ The filesystem must be mounted to be frozen (see .BR mount (8)). .PP +.PP The .B \-f flag requests the specified XFS filesystem to be @@ -48,7 +54,13 @@ Any filesystem modifications that were blocked by the freeze are unblocked and allowed to complete. .PP -One of +The +.B \-V +flag prints the version number and exits. +.PP +Unless +.B \-V +is specified, one of .B \-f or .B \-u diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_fsr.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_fsr.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_fsr.8 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_fsr.8 2013-06-06 22:52:59.000000000 +0000 @@ -3,10 +3,12 @@ xfs_fsr \- filesystem reorganizer for XFS .SH SYNOPSIS .nf -\f3xfs_fsr\f1 [\f3\-v\f1] \c -[\f3\-t\f1 seconds] [\f3\-f\f1 leftoff] [\f3\-m\f1 mtab] -\f3xfs_fsr\f1 [\f3\-v\f1] \c +\f3xfs_fsr\f1 [\f3\-vdg\f1] \c +[\f3\-t\f1 seconds] [\f3\-p\f1 passes] [\f3\-f\f1 leftoff] [\f3\-m\f1 mtab] +\f3xfs_fsr\f1 [\f3\-vdg\f1] \c [xfsdev | file] ... +.br +.B xfs_fsr \-V .fi .SH DESCRIPTION .I xfs_fsr @@ -35,7 +37,11 @@ .TP .BI \-t " seconds" How long to reorganize. -The default is 7200 (2 hours). +The default is 7200 seconds (2 hours). +.TP +.BI \-p " passes" +Number of passes before terminating global re-org. +The default is 10 passes. .TP .BI \-f " leftoff" Use this file instead of @@ -47,6 +53,16 @@ Verbose. Print cryptic information about each file being reorganized. +.TP +.B \-d +Debug. Print even more cryptic information. +.TP +.B \-g +Print to syslog (default if stdout not a tty). +.TP +.B \-V +Prints the version number and exits. + .PP When invoked with no arguments .I xfs_fsr diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_growfs.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_growfs.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_growfs.8 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_growfs.8 2013-06-06 22:52:59.000000000 +0000 @@ -15,7 +15,7 @@ .SH SYNOPSIS .B xfs_growfs [ -.B \-dilnrxV +.B \-dilnrx ] [ .B \-D .I size @@ -37,12 +37,17 @@ ] .I mount-point .br +.B xfs_growfs \-V +.PP +.br .B xfs_info [ .B \-t .I mtab ] .I mount-point +.br +.B xfs_info \-V .SH DESCRIPTION .B xfs_growfs expands an existing XFS filesystem (see diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_io.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_io.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_io.8 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_io.8 2014-05-02 00:09:16.000000000 +0000 @@ -4,7 +4,7 @@ .SH SYNOPSIS .B xfs_io [ -.B \-adfmrRstx +.B \-adfmrRstxT ] [ .B \-c .I cmd @@ -13,6 +13,8 @@ .I prog ] .I file +.br +.B xfs_io \-V .SH DESCRIPTION .B xfs_io is a debugging tool like @@ -52,6 +54,9 @@ .B \-x Expert mode. Dangerous commands are only available in this mode. These commands also tend to require additional privileges. +.TP +.B \-V +Prints the version number and exits. .PP The other .BR open (2) @@ -83,7 +88,7 @@ Display a list of all open files and (optionally) switch to an alternate current open file. .TP -.BI "open [[ \-acdfrstR ] " path " ]" +.BI "open [[ \-acdfrstRT ] " path " ]" Closes the current file, and opens the file specified by .I path instead. Without any arguments, displays statistics about the current @@ -111,6 +116,17 @@ .B \-t truncates on open (O_TRUNC). .TP +.B \-n +opens in non-blocking mode if possible (O_NONBLOCK). +.TP +.B \-T +create a temporary file not linked into the filesystem namespace +(O_TMPFILE). The pathname passed must refer to a directory which +is treated as virtual parent for the newly created invisible file. +Can not be used together with the +.B \-r +option. +.TP .B \-R marks the file as a realtime XFS file after opening it, if it is not already marked as such. @@ -245,6 +261,12 @@ .BR xfs_bmap (8) manual page for complete documentation. .TP +.BI "fiemap [ \-alv ] [ \-n " nx " ]" +Prints the block mapping for the current open file using the fiemap +ioctl. Options behave as described in the +.BR xfs_bmap (8) +manual page. +.TP .BI "extsize [ \-R | \-D ] [ " value " ]" Display and/or modify the preferred extent size used when allocating space for the currently open file. If the @@ -355,17 +377,34 @@ .BI "falloc [ \-k ]" " offset length" Allocates reserved, unwritten space for part of a file using the fallocate routine as described in the -.BR fallocate (3) +.BR fallocate (2) manual page. .RS 1.0i .PD 0 .TP 0.4i .B \-k will set the FALLOC_FL_KEEP_SIZE flag as described in -.BR fallocate (3). +.BR fallocate (2). .PD .RE .TP +.BI fcollapse " offset length" +Call fallocate with FALLOC_FL_COLLAPSE_RANGE flag as described in the +.BR fallocate (2) +manual page to de-allocates blocks and eliminates the hole created in this process +by shifting data blocks into the hole. +.TP +.BI fpunch " offset length" +Punches (de-allocates) blocks in the file by calling fallocate with +the FALLOC_FL_PUNCH_HOLE flag as described in the +.BR fallocate (2) +manual page. +.TP +.BI fzero " offset length" +Call fallocate with FALLOC_FL_ZERO_RANGE flag as described in the +.BR fallocate (2) +manual page to allocate and zero blocks within the range. +.TP .BI truncate " offset" Truncates the current file at the given offset using .BR ftruncate (2). @@ -377,6 +416,66 @@ .RB ( \-f ) or by path .RB ( \-i ). +.TP +.BI "readdir [ -v ] [ -o " offset " ] [ -l " length " ] " +Read a range of directory entries from a given offset of a directory. +.RS 1.0i +.PD 0 +.TP 0.4i +.B \-v +verbose mode - dump dirent content as defined in +.BR readdir (3) +.TP +.B \-o +specify starting +.I offset +.TP +.B \-l +specify total +.I length +to read (in bytes) +.RE +.PD +.TP +.TP +.BI "seek \-a | \-d | \-h [ \-r ] [ \-s ] offset" +On platforms that support the +.BR lseek (2) +.B SEEK_DATA +and +.B SEEK_HOLE +options, display the offsets of the specified segments. +.RS 1.0i +.PD 0 +.TP 0.4i +.B \-a +Display both +.B data +and +.B hole +segments starting at the specified +.B offset. +.TP +.B \-d +Display the +.B data +segment starting at the specified +.B offset. +.TP +.B \-h +Display the +.B hole +segment starting at the specified +.B offset. +.TP +.B \-r +Recursively display all the specified segments starting at the specified +.B offset. +.TP +.B \-s +Display the starting lseek(2) offset. This offset will be a calculated value when +both data and holes are displayed together or performing a recusively display. +.TP .SH MEMORY MAPPED I/O COMMANDS .TP @@ -544,6 +643,9 @@ Undo the effects of a filesystem freeze operation. Only available in expert mode and requires privileges. .TP +.BI "flink " path +Link the currently open file descriptor into the filesystem namespace. +.TP .BI "inject [ " tag " ]" Inject errors into a filesystem to observe filesystem behavior at specific points under adverse conditions. Without the @@ -575,6 +677,24 @@ and the XFS_IOC_FSGEOMETRY system call on the filesystem where the current file resides. .TP +.BR chproj " [ " \-R | \-D " ]" +Modifies the project identifier associated with the current path. The +.B \-R +option will recursively descend if the current path is a directory. The +.B \-D +option will also recursively descend, only setting modifying projects +on subdirectories. See the +.BR xfs_quota (8) +manual page for more information about project identifiers. +.TP +.BR lsproj " [ " \-R | \-D " ]" +Displays the project identifier associated with the current path. The +.B \-R +and +.B \-D +options behave as described above, in +.B chproj. +.TP .BR parent " [ " \-cpv " ]" By default this command prints out the parent inode numbers, inode generation numbers and basenames of all the hardlinks which @@ -611,4 +731,5 @@ .BR msync (2), .BR open (2), .BR pread (2), -.BR pwrite (2). +.BR pwrite (2), +.BR readdir (3). diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_logprint.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_logprint.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_logprint.8 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_logprint.8 2013-06-06 22:52:59.000000000 +0000 @@ -97,6 +97,12 @@ .TP .B \-t Print out the transactional view. +.TP +.B \-v +Print "overwrite" data. +.TP +.B \-V +Prints the version number and exits. .SH SEE ALSO .BR mkfs.xfs (8), .BR mount (8). diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_mdrestore.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_mdrestore.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_mdrestore.8 2010-08-18 03:47:06.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_mdrestore.8 2014-06-19 22:42:17.000000000 +0000 @@ -8,6 +8,8 @@ ] .I source .I target +.br +.B xfs_mdrestore \-V .SH DESCRIPTION .B xfs_mdrestore is a debugging tool that restores a metadata image generated by @@ -16,7 +18,7 @@ .I source argument specifies the location of the metadump image and the .I target -argument specifies the destination for the filsystem image. +argument specifies the destination for the filesystem image. If the .I source is \-, then the metadata image is read from stdin. This allows the output of @@ -36,6 +38,9 @@ .TP .B \-g Shows restore progress on stdout. +.TP +.B \-V +Prints the version number and exits. .SH DIAGNOSTICS .B xfs_mdrestore returns an exit code of 0 if all the metadata is successfully restored or @@ -43,7 +48,6 @@ .SH SEE ALSO .BR xfs_metadump (8), .BR xfs_repair (8), -.BR xfs_check (8), .BR xfs (5) .SH BUGS Email bug reports to diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_metadump.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_metadump.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_metadump.8 2010-08-18 03:46:50.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_metadump.8 2014-05-02 00:09:16.000000000 +0000 @@ -4,13 +4,19 @@ .SH SYNOPSIS .B xfs_metadump [ -.B \-efgow +.B \-efFgow +] [ +.B \-m +.I max_extents +] ] [ .B \-l .I logdev ] .I source .I target +.br +.B xfs_metadump \-V .SH DESCRIPTION .B xfs_metadump is a debugging tool that copies the metadata from an XFS filesystem to a file. @@ -26,10 +32,8 @@ redirected to another program such as a compression application. .PP .B xfs_metadump -should only be used to copy unmounted filesystems, read-only mounted -filesystems, or frozen filesystems (see -.BR xfs_freeze (8)). -Otherwise, the generated dump could be inconsistent or corrupt. +may only be used to copy unmounted filesystems, or read-only mounted +filesystems. .PP .B xfs_metadump does not alter the source filesystem in any way. The @@ -82,6 +86,11 @@ been made into an ordinary file with .BR xfs_copy (8). .TP +.B \-F +Specifies that we want to continue even if the superblock magic is not correct. +If the source is truly not an XFS filesystem, the resulting image will be useless, +and xfs_metadump may crash. +.TP .B \-g Shows dump progress. This is sent to stdout if the .I target @@ -94,12 +103,20 @@ external log resides. The external log is not copied, only internal logs are copied. .TP +.B \-m +Set the maximum size of an allowed metadata extent. Extremely large metadata +extents are likely to be corrupt, and will be skipped if they exceed +this value. The default size is 1000 blocks. +.TP .B \-o Disables obfuscation of file names and extended attributes. .TP .B \-w Prints warnings of inconsistent metadata encountered to stderr. Bad metadata is still copied. +.TP +.B \-V +Prints the version number and exits. .SH DIAGNOSTICS .B xfs_metadump returns an exit code of 0 if all readable metadata is successfully copied or diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_mkfile.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_mkfile.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_mkfile.8 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_mkfile.8 2013-06-06 22:52:59.000000000 +0000 @@ -7,10 +7,14 @@ .B \-v ] [ .B \-n +] [ +.B \-p ] .I size\c .RB [ k | b | m | g ] .IR filename " ..." +.br +.B xfs_mkfile \-V .SH DESCRIPTION .B xfs_mkfile creates one or more files. The file is padded with zeroes by default. @@ -30,3 +34,10 @@ .B \-n No bytes. Create a holey file - that is, do not write out any data, just seek to end of file and write a block. +.TP +.B \-p +Preallocate. The file is preallocated, then overwritten with zeroes, +then truncated to the desired size. +.TP +.B \-V +Prints the version number and exits. diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_ncheck.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_ncheck.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_ncheck.8 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_ncheck.8 2014-06-19 22:42:17.000000000 +0000 @@ -15,6 +15,8 @@ .I logdev ] .I device +.br +.B xfs_ncheck \-V .SH DESCRIPTION .B xfs_ncheck with no @@ -56,15 +58,17 @@ .BI \-i " ino" Limits the report to only those files whose inode numbers follow. May be given multiple times to select multiple inode numbers. +.TP +.B \-V +Prints the version number and exits. .PP If the filesystem is seriously corrupted, or very busy and looks -like it is corrupt, a message of the form that would be generated by -.BR xfs_check (8) -may appear. +like it is corrupt, a message of the form that would be generated by the +.BR xfs_db (8) +"check" command may appear. .PP .B xfs_ncheck is only useful with XFS filesystems. .SH SEE ALSO .BR mkfs.xfs (8), -.BR xfs_check (8), .BR xfs (5). diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_quota.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_quota.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_quota.8 2009-05-06 01:57:47.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_quota.8 2013-06-06 22:52:59.000000000 +0000 @@ -16,6 +16,8 @@ .I project ] ... [ .IR path " ... ]" +.br +.B xfs_quota \-V .SH DESCRIPTION .B xfs_quota is a utility for reporting and editing various aspects of filesystem quota. @@ -50,6 +52,9 @@ commands to the set of projects specified. Multiple .B \-d arguments may be given. +.TP +.B \-V +Prints the version number and exits. .PP The optional .I path @@ -623,7 +628,7 @@ 1 is first level ... ). Option .B \-p -adds posibility to specify project paths in command line without a need +adds possibility to specify project paths in command line without a need for .I /etc/projects to exist. Note that if projects file exists then it is also used. diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_repair.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_repair.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_repair.8 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_repair.8 2014-06-19 22:42:17.000000000 +0000 @@ -130,12 +130,6 @@ supported are: .RS 1.0i .TP -.BI ihash= ihashsize -overrides the default inode cache hash size. The total number of -inode cache entries are limited to 8 times this amount. The default -.I ihashsize -is 1024 (for a total of 8192 entries). -.TP .BI bhash= bhashsize overrides the default buffer cache hash size. The total number of buffer cache entries are limited to 8 times this amount. The default @@ -150,7 +144,7 @@ .BI force_geometry Check the filesystem even if geometry information could not be validated. Geometry information can not be validated if only a single allocation -group and exist and thus we do not have a backup superblock available, or +group exists and thus we do not have a backup superblock available, or if there are two allocation groups and the two superblocks do not agree on the filesystem geometry. Only use this option if you validated the geometry yourself and know what you are doing. If In doubt run @@ -158,7 +152,7 @@ .RE .TP .B \-t " interval" -Modify reporting interval. During long runs +Modify reporting interval, specified in seconds. During long runs .B xfs_repair outputs its progress every 15 minutes. Reporting is only activated when ag_stride is enabled. @@ -170,10 +164,10 @@ Repair dangerously. Allow .B xfs_repair to repair an XFS filesystem mounted read only. This is typically done -on a root fileystem from single user mode, immediately followed by a reboot. +on a root filesystem from single user mode, immediately followed by a reboot. .TP .B \-V -Prints out the current version number and exits. +Prints the version number and exits. .SS Checks Performed Inconsistencies corrected include the following: .IP 1. @@ -239,7 +233,7 @@ aborts on most disk I/O errors. Therefore, if you are trying to repair a filesystem that was damaged due to a disk drive failure, steps should be taken to ensure that all blocks in the filesystem are -readable and writeable before attempting to use +readable and writable before attempting to use .B xfs_repair to repair the filesystem. A possible method is using .BR dd (8) @@ -554,6 +548,5 @@ .BR mkfs.xfs (8), .BR umount (8), .BR xfs_admin (8), -.BR xfs_check (8), .BR xfs_metadump (8), .BR xfs (5). diff -Nru xfsprogs-3.1.9ubuntu2/man/man8/xfs_rtcp.8 xfsprogs-3.2.1ubuntu1/man/man8/xfs_rtcp.8 --- xfsprogs-3.1.9ubuntu2/man/man8/xfs_rtcp.8 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/man/man8/xfs_rtcp.8 2013-06-06 22:52:59.000000000 +0000 @@ -10,6 +10,8 @@ .B -p ] .IR source " ... " target +.br +.B xfs_rtcp \-V .SH DESCRIPTION .B xfs_rtcp copies a file to the realtime partition on an XFS filesystem. @@ -35,6 +37,9 @@ of the filesystem block size. This is necessary since the realtime file is created using direct I/O and the minimum I/O is the filesystem block size. +.TP +.B \-V +Prints the version number and exits. .SH SEE ALSO .BR xfs (5), .BR mkfs.xfs (8), diff -Nru xfsprogs-3.1.9ubuntu2/mdrestore/Makefile xfsprogs-3.2.1ubuntu1/mdrestore/Makefile --- xfsprogs-3.1.9ubuntu2/mdrestore/Makefile 2010-03-24 03:07:34.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/mdrestore/Makefile 2013-10-10 21:07:17.000000000 +0000 @@ -8,7 +8,7 @@ LTCOMMAND = xfs_mdrestore CFILES = xfs_mdrestore.c -LLDLIBS = $(LIBXFS) $(LIBRT) $(LIBPTHREAD) +LLDLIBS = $(LIBXFS) $(LIBRT) $(LIBPTHREAD) $(LIBUUID) LTDEPENDENCIES = $(LIBXFS) LLDFLAGS = -static diff -Nru xfsprogs-3.1.9ubuntu2/mdrestore/xfs_mdrestore.c xfsprogs-3.2.1ubuntu1/mdrestore/xfs_mdrestore.c --- xfsprogs-3.1.9ubuntu2/mdrestore/xfs_mdrestore.c 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/mdrestore/xfs_mdrestore.c 2014-05-02 00:09:16.000000000 +0000 @@ -169,6 +169,11 @@ memset(block_buffer, 0, sb.sb_sectsize); sb.sb_inprogress = 0; libxfs_sb_to_disk((xfs_dsb_t *)block_buffer, &sb, XFS_SB_ALL_BITS); + if (xfs_sb_version_hascrc(&sb)) { + xfs_update_cksum(block_buffer, sb.sb_sectsize, + offsetof(struct xfs_sb, sb_crc)); + } + if (pwrite(dst_fd, block_buffer, sb.sb_sectsize, 0) < 0) fatal("error writing primary superblock: %s\n", strerror(errno)); @@ -178,7 +183,7 @@ static void usage(void) { - fprintf(stderr, "Usage: %s [-bg] source target\n", progname); + fprintf(stderr, "Usage: %s [-V] [-g] source target\n", progname); exit(1); } diff -Nru xfsprogs-3.1.9ubuntu2/mkfs/maxtrres.c xfsprogs-3.2.1ubuntu1/mkfs/maxtrres.c --- xfsprogs-3.1.9ubuntu2/mkfs/maxtrres.c 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/mkfs/maxtrres.c 2013-10-10 21:07:17.000000000 +0000 @@ -27,60 +27,20 @@ #include #include "xfs_mkfs.h" -static void -max_attrset_trans_res_adjust( - xfs_mount_t *mp) -{ - int local; - int size; - int nblks; - int res; - - /* - * Determine space the maximal sized attribute will use, - * to calculate the largest reservation size needed. - */ - size = libxfs_attr_leaf_newentsize(MAXNAMELEN, 64 * 1024, - mp->m_sb.sb_blocksize, &local); - ASSERT(!local); - nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); - nblks += XFS_B_TO_FSB(mp, size); - nblks += XFS_NEXTENTADD_SPACE_RES(mp, size, XFS_ATTR_FORK); - res = XFS_ATTRSET_LOG_RES(mp, nblks); - -#if 0 - printf("size = %d nblks = %d res = %d\n", size, nblks, res); -#endif - - mp->m_reservations.tr_attrset = res; -} - -static int -max_trans_res_by_mount( - xfs_mount_t *mp) -{ - uint *p; - int rval; - xfs_trans_reservations_t *tr = &mp->m_reservations; - - for (rval = 0, p = (uint *)tr; p < (uint *)(tr + 1); p++) { - if ((int)*p > rval) - rval = (int)*p; - } - return rval; -} - int max_trans_res( + int crcs_enabled, int dirversion, int sectorlog, int blocklog, int inodelog, - int dirblocklog) + int dirblocklog, + int logversion, + int log_sunit) { xfs_sb_t *sbp; xfs_mount_t mount; - int maxres, maxfsb; + int maxfsb; memset(&mount, 0, sizeof(mount)); sbp = &mount.m_sb; @@ -95,18 +55,27 @@ sbp->sb_inodesize = 1 << inodelog; sbp->sb_inopblock = 1 << (blocklog - inodelog); sbp->sb_dirblklog = dirblocklog - blocklog; - sbp->sb_versionnum = XFS_SB_VERSION_4 | - (dirversion == 2 ? XFS_SB_VERSION_DIRV2BIT : 0); + + if (log_sunit > 0) { + log_sunit <<= blocklog; + logversion = 2; + } else + log_sunit = 1; + sbp->sb_logsunit = log_sunit; + + sbp->sb_versionnum = + (crcs_enabled ? XFS_SB_VERSION_5 : XFS_SB_VERSION_4) | + (dirversion == 2 ? XFS_SB_VERSION_DIRV2BIT : 0) | + (logversion > 1 ? XFS_SB_VERSION_LOGV2BIT : 0); libxfs_mount(&mount, sbp, 0,0,0,0); - max_attrset_trans_res_adjust(&mount); - maxres = max_trans_res_by_mount(&mount); - maxfsb = XFS_B_TO_FSB(&mount, maxres); + maxfsb = xfs_log_calc_minimum_size(&mount); libxfs_umount(&mount); #if 0 - printf("#define\tMAXTRRES_S%d_B%d_I%d_D%d_V%d\t%lld\n", - sectorlog, blocklog, inodelog, dirblocklog, dirversion, maxfsb); + printf("#define\tMAXTRRES_S%d_B%d_I%d_D%d_V%d_LSU%d\t%d\n", + sectorlog, blocklog, inodelog, dirblocklog, dirversion, + log_sunit, maxfsb); #endif return maxfsb; diff -Nru xfsprogs-3.1.9ubuntu2/mkfs/proto.c xfsprogs-3.2.1ubuntu1/mkfs/proto.c --- xfsprogs-3.1.9ubuntu2/mkfs/proto.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/mkfs/proto.c 2014-06-19 22:42:17.000000000 +0000 @@ -49,7 +49,7 @@ setup_proto( char *fname) { - char *buf; + char *buf = NULL; static char dflt[] = "d--755 0 0 $"; int fd; long size; @@ -59,18 +59,19 @@ if ((fd = open(fname, O_RDONLY)) < 0 || (size = filesize(fd)) < 0) { fprintf(stderr, _("%s: failed to open %s: %s\n"), progname, fname, strerror(errno)); - exit(1); + goto out_fail; } + buf = malloc(size + 1); if (read(fd, buf, size) < size) { fprintf(stderr, _("%s: read failed on %s: %s\n"), progname, fname, strerror(errno)); - exit(1); + goto out_fail; } if (buf[size - 1] != '\n') { fprintf(stderr, _("%s: proto file %s premature EOF\n"), progname, fname); - exit(1); + goto out_fail; } buf[size] = '\0'; /* @@ -79,7 +80,14 @@ (void)getstr(&buf); /* boot image name */ (void)getnum(&buf); /* block count */ (void)getnum(&buf); /* inode count */ + close(fd); return buf; + +out_fail: + if (fd >= 0) + close(fd); + free(buf); + exit(1); } static long @@ -119,7 +127,9 @@ mp = tp->t_mountp; for (i = 0, r = MKFS_BLOCKRES(blocks); r >= blocks; r--) { - i = libxfs_trans_reserve(tp, r, 0, 0, 0, 0); + struct xfs_trans_res tres = {0}; + + i = libxfs_trans_reserve(tp, &tres, r, 0); if (i == 0) return; } @@ -187,7 +197,6 @@ tp = libxfs_trans_alloc(mp, 0); libxfs_trans_ijoin(tp, ip, 0); - libxfs_trans_ihold(tp, ip); ip->i_d.di_mode &= ~S_ISUID; @@ -243,7 +252,7 @@ } else if (len > 0) { nb = XFS_B_TO_FSB(mp, len); nmap = 1; - error = libxfs_bmapi(tp, ip, 0, nb, XFS_BMAPI_WRITE, first, nb, + error = libxfs_bmapi_write(tp, ip, 0, nb, 0, first, nb, &map, &nmap, flist); if (error) { fail(_("error allocating space for a file"), error); @@ -306,12 +315,14 @@ struct xfs_name *name, xfs_ino_t inum, xfs_fsblock_t *first, - xfs_bmap_free_t *flist, - xfs_extlen_t total) + xfs_bmap_free_t *flist) { int error; + int rsv; + + rsv = XFS_DIRENTER_SPACE_RES(mp, name->len); - error = libxfs_dir_createname(tp, pip, name, inum, first, flist, total); + error = libxfs_dir_createname(tp, pip, name, inum, first, flist, rsv); if (error) fail(_("directory createname error"), error); } @@ -434,6 +445,7 @@ creds.cr_gid = (int)getnum(pp); xname.name = (uchar_t *)name; xname.len = name ? strlen(name) : 0; + xname.type = 0; tp = libxfs_trans_alloc(mp, 0); flags = XFS_ILOG_CORE; xfs_bmap_init(&flist, &first); @@ -449,8 +461,8 @@ if (buf) free(buf); libxfs_trans_ijoin(tp, pip, 0); - newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); - libxfs_trans_ihold(tp, pip); + xname.type = XFS_DIR3_FT_REG_FILE; + newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist); break; case IF_RESERVED: /* pre-allocated space only */ @@ -465,8 +477,8 @@ libxfs_trans_ijoin(tp, pip, 0); - newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); - libxfs_trans_ihold(tp, pip); + xname.type = XFS_DIR3_FT_REG_FILE; + newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist); libxfs_trans_log_inode(tp, ip, flags); error = libxfs_bmap_finish(&tp, &flist, &committed); @@ -474,6 +486,7 @@ fail(_("Pre-allocated file creation failed"), error); libxfs_trans_commit(tp, 0); rsvfile(mp, ip, llen); + IRELE(ip); return; case IF_BLOCK: @@ -486,8 +499,8 @@ fail(_("Inode allocation failed"), error); } libxfs_trans_ijoin(tp, pip, 0); - newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); - libxfs_trans_ihold(tp, pip); + xname.type = XFS_DIR3_FT_BLKDEV; + newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist); flags |= XFS_ILOG_DEV; break; @@ -500,8 +513,8 @@ if (error) fail(_("Inode allocation failed"), error); libxfs_trans_ijoin(tp, pip, 0); - newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); - libxfs_trans_ihold(tp, pip); + xname.type = XFS_DIR3_FT_CHRDEV; + newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist); flags |= XFS_ILOG_DEV; break; @@ -512,8 +525,8 @@ if (error) fail(_("Inode allocation failed"), error); libxfs_trans_ijoin(tp, pip, 0); - newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); - libxfs_trans_ihold(tp, pip); + xname.type = XFS_DIR3_FT_FIFO; + newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist); break; case IF_SYMLINK: buf = getstr(pp); @@ -525,8 +538,8 @@ fail(_("Inode allocation failed"), error); flags |= newfile(tp, ip, &flist, &first, 1, 1, buf, len); libxfs_trans_ijoin(tp, pip, 0); - newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); - libxfs_trans_ihold(tp, pip); + xname.type = XFS_DIR3_FT_SYMLINK; + newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist); break; case IF_DIRECTORY: getres(tp, 0); @@ -539,14 +552,13 @@ pip = ip; mp->m_sb.sb_rootino = ip->i_ino; libxfs_mod_sb(tp, XFS_SB_ROOTINO); - mp->m_rootip = ip; isroot = 1; } else { libxfs_trans_ijoin(tp, pip, 0); + xname.type = XFS_DIR3_FT_DIR; newdirent(mp, tp, pip, &xname, ip->i_ino, - &first, &flist, 1); + &first, &flist); pip->i_d.di_nlink++; - libxfs_trans_ihold(tp, pip); libxfs_trans_log_inode(tp, pip, XFS_ILOG_CORE); } newdirectory(mp, tp, ip, pip); @@ -554,7 +566,6 @@ error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) fail(_("Directory creation failed"), error); - libxfs_trans_ihold(tp, ip); libxfs_trans_commit(tp, 0); /* * RT initialization. Do this here to ensure that @@ -571,8 +582,11 @@ break; parseproto(mp, ip, fsxp, pp, name); } - libxfs_iput(ip, 0); + IRELE(ip); return; + default: + ASSERT(0); + fail(_("Unknown format"), EINVAL); } libxfs_trans_log_inode(tp, ip, flags); error = libxfs_bmap_finish(&tp, &flist, &committed); @@ -581,6 +595,7 @@ error); } libxfs_trans_commit(tp, 0); + IRELE(ip); } void @@ -615,13 +630,16 @@ xfs_trans_t *tp; struct cred creds; struct fsxattr fsxattrs; + struct xfs_trans_res tres = {0}; /* * First, allocate the inodes. */ tp = libxfs_trans_alloc(mp, 0); - if ((i = libxfs_trans_reserve(tp, MKFS_BLOCKRES_INODE, 0, 0, 0, 0))) + i = libxfs_trans_reserve(tp, &tres, MKFS_BLOCKRES_INODE, 0); + if (i) res_failed(i); + memset(&creds, 0, sizeof(creds)); memset(&fsxattrs, 0, sizeof(fsxattrs)); error = libxfs_inode_alloc(&tp, NULL, S_IFREG, 1, 0, @@ -640,7 +658,6 @@ *(__uint64_t *)&rbmip->i_d.di_atime = 0; libxfs_trans_log_inode(tp, rbmip, XFS_ILOG_CORE); libxfs_mod_sb(tp, XFS_SB_RBMINO); - libxfs_trans_ihold(tp, rbmip); mp->m_rbmip = rbmip; error = libxfs_inode_alloc(&tp, NULL, S_IFREG, 1, 0, &creds, &fsxattrs, &rsumip); @@ -651,32 +668,32 @@ rsumip->i_d.di_size = mp->m_rsumsize; libxfs_trans_log_inode(tp, rsumip, XFS_ILOG_CORE); libxfs_mod_sb(tp, XFS_SB_RSUMINO); - libxfs_trans_ihold(tp, rsumip); libxfs_trans_commit(tp, 0); mp->m_rsumip = rsumip; /* * Next, give the bitmap file some zero-filled blocks. */ tp = libxfs_trans_alloc(mp, 0); - if ((i = libxfs_trans_reserve(tp, mp->m_sb.sb_rbmblocks + - (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0, 0, 0, 0))) + i = libxfs_trans_reserve(tp, &tres, mp->m_sb.sb_rbmblocks + + (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0); + if (i) res_failed(i); + libxfs_trans_ijoin(tp, rbmip, 0); - libxfs_trans_ihold(tp, rbmip); bno = 0; xfs_bmap_init(&flist, &first); while (bno < mp->m_sb.sb_rbmblocks) { nmap = XFS_BMAP_MAX_NMAP; - error = libxfs_bmapi(tp, rbmip, bno, + error = libxfs_bmapi_write(tp, rbmip, bno, (xfs_extlen_t)(mp->m_sb.sb_rbmblocks - bno), - XFS_BMAPI_WRITE, &first, mp->m_sb.sb_rbmblocks, + 0, &first, mp->m_sb.sb_rbmblocks, map, &nmap, &flist); if (error) { fail(_("Allocation of the realtime bitmap failed"), error); } for (i = 0, ep = map; i < nmap; i++, ep++) { - libxfs_device_zero(mp->m_dev, + libxfs_device_zero(mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, ep->br_startblock), XFS_FSB_TO_BB(mp, ep->br_blockcount)); bno += ep->br_blockcount; @@ -694,26 +711,25 @@ */ tp = libxfs_trans_alloc(mp, 0); nsumblocks = mp->m_rsumsize >> mp->m_sb.sb_blocklog; - if ((i = libxfs_trans_reserve(tp, - nsumblocks + (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), - 0, 0, 0, 0))) + i = libxfs_trans_reserve(tp, &tres, nsumblocks + + (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0); + if (i) res_failed(i); libxfs_trans_ijoin(tp, rsumip, 0); - libxfs_trans_ihold(tp, rsumip); bno = 0; xfs_bmap_init(&flist, &first); while (bno < nsumblocks) { nmap = XFS_BMAP_MAX_NMAP; - error = libxfs_bmapi(tp, rsumip, bno, + error = libxfs_bmapi_write(tp, rsumip, bno, (xfs_extlen_t)(nsumblocks - bno), - XFS_BMAPI_WRITE, &first, nsumblocks, + 0, &first, nsumblocks, map, &nmap, &flist); if (error) { fail(_("Allocation of the realtime summary failed"), error); } for (i = 0, ep = map; i < nmap; i++, ep++) { - libxfs_device_zero(mp->m_dev, + libxfs_device_zero(mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, ep->br_startblock), XFS_FSB_TO_BB(mp, ep->br_blockcount)); bno += ep->br_blockcount; @@ -731,8 +747,10 @@ */ for (bno = 0; bno < mp->m_sb.sb_rextents; bno = ebno) { tp = libxfs_trans_alloc(mp, 0); - if ((i = libxfs_trans_reserve(tp, 0, 0, 0, 0, 0))) + i = libxfs_trans_reserve(tp, &tres, 0, 0); + if (i) res_failed(i); + libxfs_trans_ijoin(tp, rbmip, 0); xfs_bmap_init(&flist, &first); ebno = XFS_RTMIN(mp->m_sb.sb_rextents, bno + NBBY * mp->m_sb.sb_blocksize); diff -Nru xfsprogs-3.1.9ubuntu2/mkfs/xfs_mkfs.c xfsprogs-3.2.1ubuntu1/mkfs/xfs_mkfs.c --- xfsprogs-3.1.9ubuntu2/mkfs/xfs_mkfs.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/mkfs/xfs_mkfs.c 2014-06-19 22:42:17.000000000 +0000 @@ -147,6 +147,8 @@ "size", #define N_VERSION 2 "version", +#define N_FTYPE 3 + "ftype", NULL, }; @@ -178,6 +180,14 @@ NULL }; +char *mopts[] = { +#define M_CRC 0 + "crc", +#define M_FINOBT 1 + "finobt", + NULL +}; + #define TERABYTES(count, blog) ((__uint64_t)(count) << (40 - (blog))) #define GIGABYTES(count, blog) ((__uint64_t)(count) << (30 - (blog))) #define MEGABYTES(count, blog) ((__uint64_t)(count) << (20 - (blog))) @@ -396,26 +406,26 @@ if (!tp) goto out_free_probe; - /* - * Blkid reports the information in terms of bytes, but we want it in - * terms of 512 bytes blocks (just to convert it to bytes later..) - * - * If the reported values are just the normal 512 byte block size - * do not bother to report anything. It will just causes warnings - * if people specifier larger stripe units or widths manually. - */ - val = blkid_topology_get_minimum_io_size(tp) >> 9; - if (val > 1) - *sunit = val; - val = blkid_topology_get_optimal_io_size(tp) >> 9; - if (val > 1) - *swidth = val; - val = blkid_topology_get_logical_sector_size(tp); *lsectorsize = val; val = blkid_topology_get_physical_sector_size(tp); *psectorsize = val; + /* + * Blkid reports the information in terms of bytes, but we want it in + * terms of 512 bytes blocks (just to convert it to bytes later..) + * + * If the reported values are the same as the physical sector size + * do not bother to report anything. It will just cause warnings + * if people specify larger stripe units or widths manually. + */ + val = blkid_topology_get_minimum_io_size(tp); + if (val > *psectorsize) + *sunit = val >> 9; + val = blkid_topology_get_optimal_io_size(tp); + if (val > *psectorsize) + *swidth = val >> 9; + if (blkid_topology_get_alignment_offset(tp) != 0) { fprintf(stderr, _("warning: device is not properly aligned %s\n"), @@ -447,11 +457,30 @@ int force_overwrite) { if (!xi->disfile) { - const char *dfile = xi->volname ? xi->volname : xi->dname; + char *dfile = xi->volname ? xi->volname : xi->dname; + struct stat statbuf; - blkid_get_topology(dfile, &ft->dsunit, &ft->dswidth, - &ft->lsectorsize, &ft->psectorsize, - force_overwrite); + /* + * If our target is a regular file, and xi->disfile isn't + * set (i.e. no "-d file" invocation), use platform_findsizes + * to try to obtain the underlying filesystem's requirements + * for direct IO; we'll set our sector size to that if possible. + */ + if (!stat(dfile, &statbuf) && S_ISREG(statbuf.st_mode)) { + int fd; + long long dummy; + + fd = open(dfile, O_RDONLY); + if (fd >= 0) { + platform_findsizes(dfile, fd, &dummy, + &ft->lsectorsize); + close(fd); + } + } else { + blkid_get_topology(dfile, &ft->dsunit, &ft->dswidth, + &ft->lsectorsize, &ft->psectorsize, + force_overwrite); + } } if (xi->rtname && !xi->risfile) { @@ -864,7 +893,7 @@ __uint64_t agsize; xfs_alloc_rec_t *arec; int attrversion; - int projid32bit; + int projid16bit; struct xfs_btree_block *block; int blflag; int blocklog; @@ -879,6 +908,7 @@ char *dfile; int dirblocklog; int dirblocksize; + int dirftype; int dirversion; char *dsize; int dsu; @@ -916,7 +946,6 @@ int lssflag; int lsu; int lsunit; - int max_tr_res; int min_logblocks; xfs_mount_t *mp; xfs_mount_t mbuf; @@ -925,6 +954,7 @@ int nodsflag; int norsflag; xfs_alloc_rec_t *nrec; + int nftype; int nsflag; int nvflag; int nci; @@ -952,6 +982,8 @@ libxfs_init_t xi; struct fs_topology ft; int lazy_sb_counters; + int crcs_enabled; + int finobt; progname = basename(argv[0]); setlocale(LC_ALL, ""); @@ -959,7 +991,7 @@ textdomain(PACKAGE); attrversion = 2; - projid32bit = 0; + projid16bit = 0; blflag = bsflag = slflag = ssflag = lslflag = lssflag = 0; blocklog = blocksize = 0; sectorlog = lsectorlog = XFS_MIN_SECTORSIZE_LOG; @@ -971,6 +1003,7 @@ logversion = 2; logagno = logblocks = rtblocks = rtextblocks = 0; Nflag = nlflag = nsflag = nvflag = nci = 0; + nftype = dirftype = 0; /* inode type information in the dir */ dirblocklog = dirblocksize = 0; dirversion = XFS_DFL_DIR_VERSION; qflag = 0; @@ -983,13 +1016,15 @@ force_overwrite = 0; worst_freelist = 0; lazy_sb_counters = 1; + crcs_enabled = 0; + finobt = 0; memset(&fsx, 0, sizeof(fsx)); memset(&xi, 0, sizeof(xi)); xi.isdirect = LIBXFS_DIRECT; xi.isreadonly = LIBXFS_EXCLUSIVELY; - while ((c = getopt(argc, argv, "b:d:i:l:L:n:KNp:qr:s:CfV")) != EOF) { + while ((c = getopt(argc, argv, "b:d:i:l:L:m:n:KNp:qr:s:CfV")) != EOF) { switch (c) { case 'C': case 'f': @@ -1302,7 +1337,7 @@ c = atoi(value); if (c < 0 || c > 1) illegal(value, "i projid32bit"); - projid32bit = c; + projid16bit = c ? 0 : 1; break; default: unknown('i', value); @@ -1455,6 +1490,38 @@ illegal(optarg, "L"); label = optarg; break; + case 'm': + p = optarg; + while (*p != '\0') { + char *value; + + switch (getsubopt(&p, (constpp)mopts, &value)) { + case M_CRC: + if (!value || *value == '\0') + reqval('m', mopts, M_CRC); + c = atoi(value); + if (c < 0 || c > 1) + illegal(value, "m crc"); + crcs_enabled = c; + if (nftype && crcs_enabled) { + fprintf(stderr, +_("cannot specify both crc and ftype\n")); + usage(); + } + break; + case M_FINOBT: + if (!value || *value == '\0') + reqval('m', mopts, M_CRC); + c = atoi(value); + if (c < 0 || c > 1) + illegal(value, "m finobt"); + finobt = c; + break; + default: + unknown('m', value); + } + } + break; case 'n': p = optarg; while (*p != '\0') { @@ -1507,6 +1574,19 @@ } nvflag = 1; break; + case N_FTYPE: + if (!value || *value == '\0') + reqval('n', nopts, N_FTYPE); + if (nftype) + respec('n', nopts, N_FTYPE); + dirftype = atoi(value); + if (crcs_enabled) { + fprintf(stderr, +_("cannot specify both crc and ftype\n")); + usage(); + } + nftype = 1; + break; default: unknown('n', value); } @@ -1727,6 +1807,67 @@ logversion = 2; } + /* + * Now we have blocks and sector sizes set up, check parameters that are + * no longer optional for CRC enabled filesystems. Catch them up front + * here before doing anything else. + */ + if (crcs_enabled) { + /* minimum inode size is 512 bytes, ipflag checked later */ + if ((isflag || ilflag) && inodelog < XFS_DINODE_DFL_CRC_LOG) { + fprintf(stderr, +_("Minimum inode size for CRCs is %d bytes\n"), + 1 << XFS_DINODE_DFL_CRC_LOG); + usage(); + } + + /* inodes always aligned */ + if (iaflag != 1) { + fprintf(stderr, +_("Inodes always aligned for CRC enabled filesytems\n")); + usage(); + } + + /* lazy sb counters always on */ + if (lazy_sb_counters != 1) { + fprintf(stderr, +_("Lazy superblock counted always enabled for CRC enabled filesytems\n")); + usage(); + } + + /* version 2 logs always on */ + if (logversion != 2) { + fprintf(stderr, +_("V2 logs always enabled for CRC enabled filesytems\n")); + usage(); + } + + /* attr2 always on */ + if (attrversion != 2) { + fprintf(stderr, +_("V2 attribute format always enabled on CRC enabled filesytems\n")); + usage(); + } + + /* 32 bit project quota always on */ + /* attr2 always on */ + if (projid16bit == 1) { + fprintf(stderr, +_("32 bit Project IDs always enabled on CRC enabled filesytems\n")); + usage(); + } + } + + /* + * The kernel doesn't currently support crc=0,finobt=1 filesystems. + * Catch it here, disable finobt and warn the user. + */ + if (finobt && !crcs_enabled) { + fprintf(stderr, +_("warning: finobt not supported without CRC support, disabled.\n")); + finobt = 0; + } + if (nsflag || nlflag) { if (dirblocksize < blocksize || dirblocksize > XFS_MAX_BLOCKSIZE) { @@ -1774,9 +1915,17 @@ inodelog = blocklog - libxfs_highbit32(inopblock); isize = 1 << inodelog; } else if (!ilflag && !isflag) { - inodelog = XFS_DINODE_DFL_LOG; + inodelog = crcs_enabled ? XFS_DINODE_DFL_CRC_LOG + : XFS_DINODE_DFL_LOG; isize = 1 << inodelog; } + if (crcs_enabled && inodelog < XFS_DINODE_DFL_CRC_LOG) { + fprintf(stderr, + _("Minimum inode size for CRCs is %d bytes\n"), + 1 << XFS_DINODE_DFL_CRC_LOG); + usage(); + } + if (xi.lisfile && (!logsize || !xi.logname)) { fprintf(stderr, _("if -l file then -l name and -l size are required\n")); @@ -1856,8 +2005,6 @@ int rswidth; __uint64_t rtextbytes; - rswidth = 0; - if (!norsflag && !xi.risfile && !(!rtsize && xi.disfile)) rswidth = ft.rtswidth; else @@ -1950,7 +2097,7 @@ } } - if (discard) { + if (discard && !Nflag) { discard_blocks(xi.ddev, xi.dsize); if (xi.rtdev) discard_blocks(xi.rtdev, xi.rtsize); @@ -2025,50 +2172,6 @@ sectorsize, xi.rtbsize); } - max_tr_res = max_trans_res(dirversion, - sectorlog, blocklog, inodelog, dirblocklog); - ASSERT(max_tr_res); - min_logblocks = max_tr_res * XFS_MIN_LOG_FACTOR; - min_logblocks = MAX(XFS_MIN_LOG_BLOCKS, min_logblocks); - if (!logsize && dblocks >= (1024*1024*1024) >> blocklog) - min_logblocks = MAX(min_logblocks, XFS_MIN_LOG_BYTES>>blocklog); - if (logsize && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) { - fprintf(stderr, -_("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), - logsize, (long long)DTOBT(xi.logBBsize)); - usage(); - } else if (!logsize && xi.logBBsize > 0) { - logblocks = DTOBT(xi.logBBsize); - } else if (logsize && !xi.logdev && !loginternal) { - fprintf(stderr, - _("size specified for non-existent log subvolume\n")); - usage(); - } else if (loginternal && logsize && logblocks >= dblocks) { - fprintf(stderr, _("size %lld too large for internal log\n"), - (long long)logblocks); - usage(); - } else if (!loginternal && !xi.logdev) { - logblocks = 0; - } else if (loginternal && !logsize) { - /* - * With a 2GB max log size, default to maximum size - * at 4TB. This keeps the same ratio from the older - * max log size of 128M at 256GB fs size. IOWs, - * the ratio of fs size to log size is 2048:1. - */ - logblocks = (dblocks << blocklog) / 2048; - logblocks = logblocks >> blocklog; - logblocks = MAX(min_logblocks, logblocks); - logblocks = MAX(logblocks, - MAX(XFS_DFL_LOG_SIZE, - max_tr_res * XFS_DFL_LOG_FACTOR)); - logblocks = MIN(logblocks, XFS_MAX_LOG_BLOCKS); - if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES) { - logblocks = XFS_MAX_LOG_BYTES >> blocklog; - } - } - validate_log_size(logblocks, blocklog, min_logblocks); - if (rtsize && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize)) { fprintf(stderr, _("size %s specified for rt subvolume is too large, " @@ -2090,25 +2193,6 @@ nbmblocks = 0; } - if (dasize) { /* User-specified AG size */ - /* - * Check specified agsize is a multiple of blocksize. - */ - if (agsize % blocksize) { - fprintf(stderr, - _("agsize (%lld) not a multiple of fs blk size (%d)\n"), - (long long)agsize, blocksize); - usage(); - } - agsize /= blocksize; - agcount = dblocks / agsize + (dblocks % agsize != 0); - - } else if (daflag) /* User-specified AG count */ - agsize = dblocks / agcount + (dblocks % agcount != 0); - else - calc_default_ag_geometry(blocklog, dblocks, - ft.dsunit | ft.dswidth, &agsize, &agcount); - if (!nodsflag) { if (dsunit) { if (ft.dsunit && ft.dsunit != dsunit) { @@ -2132,6 +2216,26 @@ } } /* else dsunit & dswidth can't be set if nodsflag is set */ + if (dasize) { /* User-specified AG size */ + /* + * Check specified agsize is a multiple of blocksize. + */ + if (agsize % blocksize) { + fprintf(stderr, + _("agsize (%lld) not a multiple of fs blk size (%d)\n"), + (long long)agsize, blocksize); + usage(); + } + agsize /= blocksize; + agcount = dblocks / agsize + (dblocks % agsize != 0); + + } else if (daflag) { /* User-specified AG count */ + agsize = dblocks / agcount + (dblocks % agcount != 0); + } else { + calc_default_ag_geometry(blocklog, dblocks, + dsunit | dswidth, &agsize, &agcount); + } + /* * If dsunit is a multiple of fs blocksize, then check that is a * multiple of the agsize too @@ -2276,6 +2380,68 @@ fprintf(stderr, _("log stripe unit adjusted to 32KiB\n")); } + min_logblocks = max_trans_res(crcs_enabled, dirversion, + sectorlog, blocklog, inodelog, dirblocklog, + logversion, lsunit); + ASSERT(min_logblocks); + min_logblocks = MAX(XFS_MIN_LOG_BLOCKS, min_logblocks); + if (!logsize && dblocks >= (1024*1024*1024) >> blocklog) + min_logblocks = MAX(min_logblocks, XFS_MIN_LOG_BYTES>>blocklog); + if (logsize && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) { + fprintf(stderr, +_("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), + logsize, (long long)DTOBT(xi.logBBsize)); + usage(); + } else if (!logsize && xi.logBBsize > 0) { + logblocks = DTOBT(xi.logBBsize); + } else if (logsize && !xi.logdev && !loginternal) { + fprintf(stderr, + _("size specified for non-existent log subvolume\n")); + usage(); + } else if (loginternal && logsize && logblocks >= dblocks) { + fprintf(stderr, _("size %lld too large for internal log\n"), + (long long)logblocks); + usage(); + } else if (!loginternal && !xi.logdev) { + logblocks = 0; + } else if (loginternal && !logsize) { + + if (dblocks < GIGABYTES(1, blocklog)) { + /* tiny filesystems get minimum sized logs. */ + logblocks = min_logblocks; + } else if (dblocks < GIGABYTES(16, blocklog)) { + + /* + * For small filesystems, we want to use the + * XFS_MIN_LOG_BYTES for filesystems smaller than 16G if + * at all possible, ramping up to 128MB at 256GB. + */ + logblocks = MIN(XFS_MIN_LOG_BYTES >> blocklog, + min_logblocks * XFS_DFL_LOG_FACTOR); + } else { + /* + * With a 2GB max log size, default to maximum size + * at 4TB. This keeps the same ratio from the older + * max log size of 128M at 256GB fs size. IOWs, + * the ratio of fs size to log size is 2048:1. + */ + logblocks = (dblocks << blocklog) / 2048; + logblocks = logblocks >> blocklog; + logblocks = MAX(min_logblocks, logblocks); + } + + /* make sure the log fits wholly within an AG */ + if (logblocks >= agsize) + logblocks = min_logblocks; + + /* and now clamp the size to the maximum supported size */ + logblocks = MIN(logblocks, XFS_MAX_LOG_BLOCKS); + if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES) + logblocks = XFS_MAX_LOG_BYTES >> blocklog; + + } + validate_log_size(logblocks, blocklog, min_logblocks); + protostring = setup_proto(protofile); bsize = 1 << (blocklog - BBSHIFT); mp = &mbuf; @@ -2284,9 +2450,34 @@ sbp->sb_blocklog = (__uint8_t)blocklog; sbp->sb_sectlog = (__uint8_t)sectorlog; sbp->sb_agblklog = (__uint8_t)libxfs_log2_roundup((unsigned int)agsize); + sbp->sb_agblocks = (xfs_agblock_t)agsize; mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT; mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT; + /* + * sb_versionnum and finobt flags must be set before we use + * XFS_PREALLOC_BLOCKS(). + */ + sbp->sb_features2 = XFS_SB_VERSION2_MKFS(crcs_enabled, lazy_sb_counters, + attrversion == 2, !projid16bit, 0, + (!crcs_enabled && dirftype)); + sbp->sb_versionnum = XFS_SB_VERSION_MKFS(crcs_enabled, iaflag, + dsunit != 0, + logversion == 2, attrversion == 1, + (sectorsize != BBSIZE || + lsectorsize != BBSIZE), + nci, sbp->sb_features2 != 0); + /* + * Due to a structure alignment issue, sb_features2 ended up in one + * of two locations, the second "incorrect" location represented by + * the sb_bad_features2 field. To avoid older kernels mounting + * filesystems they shouldn't, set both field to the same value. + */ + sbp->sb_bad_features2 = sbp->sb_features2; + + if (finobt) + sbp->sb_features_ro_compat = XFS_SB_FEAT_RO_COMPAT_FINOBT; + if (loginternal) { /* * Readjust the log size to fit within an AG if it was sized @@ -2294,7 +2485,10 @@ */ if (!logsize) { logblocks = MIN(logblocks, - agsize - XFS_PREALLOC_BLOCKS(mp)); + XFS_ALLOC_AG_MAX_USABLE(mp)); + + /* revalidate the log size is valid if we changed it */ + validate_log_size(logblocks, blocklog, min_logblocks); } if (logblocks > agsize - XFS_PREALLOC_BLOCKS(mp)) { fprintf(stderr, @@ -2302,6 +2496,7 @@ (long long)logblocks); usage(); } + if (laflag) { if (logagno >= agcount) { fprintf(stderr, @@ -2333,21 +2528,31 @@ } validate_log_size(logblocks, blocklog, min_logblocks); + /* + * dirent filetype field always enabled on v5 superblocks + */ + if (crcs_enabled) { + sbp->sb_features_incompat = XFS_SB_FEAT_INCOMPAT_FTYPE; + dirftype = 1; + } + if (!qflag || Nflag) { printf(_( "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n" " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" + " =%-22s crc=%-8u finobt=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" - "naming =version %-14u bsize=%-6u ascii-ci=%d\n" + "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n" "log =%-22s bsize=%-6d blocks=%lld, version=%d\n" " =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n" "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"), dfile, isize, (long long)agcount, (long long)agsize, - "", sectorsize, attrversion, projid32bit, + "", sectorsize, attrversion, !projid16bit, + "", crcs_enabled, finobt, "", blocksize, (long long)dblocks, imaxpct, "", dsunit, dswidth, - dirversion, dirblocksize, nci, + dirversion, dirblocksize, nci, dirftype, logfile, 1 << blocklog, (long long)logblocks, logversion, "", lsectorsize, lsunit, lazy_sb_counters, rtfile, rtextblocks << blocklog, @@ -2368,7 +2573,6 @@ sbp->sb_logstart = logstart; sbp->sb_rootino = sbp->sb_rbmino = sbp->sb_rsumino = NULLFSINO; sbp->sb_rextsize = rtextblocks; - sbp->sb_agblocks = (xfs_agblock_t)agsize; sbp->sb_agcount = (xfs_agnumber_t)agcount; sbp->sb_rbmblocks = nbmblocks; sbp->sb_logblocks = (xfs_extlen_t)logblocks; @@ -2388,7 +2592,7 @@ sbp->sb_fdblocks = dblocks - agcount * XFS_PREALLOC_BLOCKS(mp) - (loginternal ? logblocks : 0); sbp->sb_frextents = 0; /* will do a free later */ - sbp->sb_uquotino = sbp->sb_gquotino = 0; + sbp->sb_uquotino = sbp->sb_gquotino = sbp->sb_pquotino = 0; sbp->sb_qflags = 0; sbp->sb_unit = dsunit; sbp->sb_width = dswidth; @@ -2399,7 +2603,10 @@ } else sbp->sb_logsunit = 0; if (iaflag) { - sbp->sb_inoalignmt = XFS_INODE_BIG_CLUSTER_SIZE >> blocklog; + int cluster_size = XFS_INODE_BIG_CLUSTER_SIZE; + if (crcs_enabled) + cluster_size *= isize / XFS_DINODE_MIN_SIZE; + sbp->sb_inoalignmt = cluster_size >> blocklog; iaflag = sbp->sb_inoalignmt != 0; } else sbp->sb_inoalignmt = 0; @@ -2410,20 +2617,6 @@ sbp->sb_logsectlog = 0; sbp->sb_logsectsize = 0; } - sbp->sb_features2 = XFS_SB_VERSION2_MKFS(lazy_sb_counters, - attrversion == 2, projid32bit == 1, 0); - sbp->sb_versionnum = XFS_SB_VERSION_MKFS(iaflag, dsunit != 0, - logversion == 2, attrversion == 1, - (sectorsize != BBSIZE || - lsectorsize != BBSIZE), - nci, sbp->sb_features2 != 0); - /* - * Due to a structure alignment issue, sb_features2 ended up in one - * of two locations, the second "incorrect" location represented by - * the sb_bad_features2 field. To avoid older kernels mounting - * filesystems they shouldn't, set both field to the same value. - */ - sbp->sb_bad_features2 = sbp->sb_features2; if (force_overwrite) zero_old_xfs_structures(&xi, sbp); @@ -2434,16 +2627,19 @@ * swap (somewhere around the page size), jfs (32k), * ext[2,3] and reiserfs (64k) - and hopefully all else. */ - buf = libxfs_getbuf(xi.ddev, 0, BTOBB(WHACK_SIZE)); + libxfs_buftarg_init(mp, xi.ddev, xi.logdev, xi.rtdev); + buf = libxfs_getbuf(mp->m_ddev_targp, 0, BTOBB(WHACK_SIZE)); memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); libxfs_purgebuf(buf); /* OK, now write the superblock */ - buf = libxfs_getbuf(xi.ddev, XFS_SB_DADDR, XFS_FSS_TO_BB(mp, 1)); + buf = libxfs_getbuf(mp->m_ddev_targp, XFS_SB_DADDR, XFS_FSS_TO_BB(mp, 1)); + buf->b_ops = &xfs_sb_buf_ops; memset(XFS_BUF_PTR(buf), 0, sectorsize); libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp, XFS_SB_ALL_BITS); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); + libxfs_purgebuf(buf); /* * If the data area is a file, then grow it out to its final size @@ -2459,10 +2655,11 @@ /* * Zero out the end of the device, to obliterate any * old MD RAID (or other) metadata at the end of the device. - * (MD sb is ~64k from the end, take out a wider swath to be sure) + * (MD sb is ~64k from the end, take out a wider swath to be sure) */ if (!xi.disfile) { - buf = libxfs_getbuf(xi.ddev, (xi.dsize - BTOBB(WHACK_SIZE)), + buf = libxfs_getbuf(mp->m_ddev_targp, + (xi.dsize - BTOBB(WHACK_SIZE)), BTOBB(WHACK_SIZE)); memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); @@ -2470,29 +2667,36 @@ } /* - * Zero the log if there is one. + * Zero the log.... */ - if (loginternal) - xi.logdev = xi.ddev; - if (xi.logdev) - libxfs_log_clear(xi.logdev, XFS_FSB_TO_DADDR(mp, logstart), - (xfs_extlen_t)XFS_FSB_TO_BB(mp, logblocks), - &sbp->sb_uuid, logversion, lsunit, XLOG_FMT); + libxfs_log_clear(mp->m_logdev_targp, + XFS_FSB_TO_DADDR(mp, logstart), + (xfs_extlen_t)XFS_FSB_TO_BB(mp, logblocks), + &sbp->sb_uuid, logversion, lsunit, XLOG_FMT); - mp = libxfs_mount(mp, sbp, xi.ddev, xi.logdev, xi.rtdev, 1); + mp = libxfs_mount(mp, sbp, xi.ddev, xi.logdev, xi.rtdev, 0); if (mp == NULL) { fprintf(stderr, _("%s: filesystem failed to initialize\n"), progname); exit(1); } + /* + * XXX: this code is effectively shared with the kernel growfs code. + * These initialisations should be pulled into libxfs to keep the + * kernel/userspace header initialisation code the same. + */ for (agno = 0; agno < agcount; agno++) { + struct xfs_agfl *agfl; + int bucket; + /* * Superblock. */ - buf = libxfs_getbuf(xi.ddev, + buf = libxfs_getbuf(mp->m_ddev_targp, XFS_AG_DADDR(mp, agno, XFS_SB_DADDR), XFS_FSS_TO_BB(mp, 1)); + buf->b_ops = &xfs_sb_buf_ops; memset(XFS_BUF_PTR(buf), 0, sectorsize); libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp, XFS_SB_ALL_BITS); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); @@ -2500,9 +2704,10 @@ /* * AG header block: freespace */ - buf = libxfs_getbuf(mp->m_dev, + buf = libxfs_getbuf(mp->m_ddev_targp, XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), XFS_FSS_TO_BB(mp, 1)); + buf->b_ops = &xfs_agf_buf_ops; agf = XFS_BUF_TO_AGF(buf); memset(agf, 0, sectorsize); if (agno == agcount - 1) @@ -2521,6 +2726,9 @@ nbmblocks = (xfs_extlen_t)(agsize - XFS_PREALLOC_BLOCKS(mp)); agf->agf_freeblks = cpu_to_be32(nbmblocks); agf->agf_longest = cpu_to_be32(nbmblocks); + if (xfs_sb_version_hascrc(&mp->m_sb)) + platform_uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_uuid); + if (loginternal && agno == logagno) { be32_add_cpu(&agf->agf_freeblks, -logblocks); agf->agf_longest = cpu_to_be32(agsize - @@ -2531,12 +2739,33 @@ libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* + * AG freelist header block + */ + buf = libxfs_getbuf(mp->m_ddev_targp, + XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), + XFS_FSS_TO_BB(mp, 1)); + buf->b_ops = &xfs_agfl_buf_ops; + agfl = XFS_BUF_TO_AGFL(buf); + /* setting to 0xff results in initialisation to NULLAGBLOCK */ + memset(agfl, 0xff, sectorsize); + if (xfs_sb_version_hascrc(&mp->m_sb)) { + agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC); + agfl->agfl_seqno = cpu_to_be32(agno); + platform_uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_uuid); + for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++) + agfl->agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK); + } + + libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); + + /* * AG header block: inodes */ - buf = libxfs_getbuf(mp->m_dev, + buf = libxfs_getbuf(mp->m_ddev_targp, XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), XFS_FSS_TO_BB(mp, 1)); agi = XFS_BUF_TO_AGI(buf); + buf->b_ops = &xfs_agi_buf_ops; memset(agi, 0, sectorsize); agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC); agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION); @@ -2545,9 +2774,15 @@ agi->agi_count = 0; agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp)); agi->agi_level = cpu_to_be32(1); + if (finobt) { + agi->agi_free_root = cpu_to_be32(XFS_FIBT_BLOCK(mp)); + agi->agi_free_level = cpu_to_be32(1); + } agi->agi_freecount = 0; agi->agi_newino = cpu_to_be32(NULLAGINO); agi->agi_dirino = cpu_to_be32(NULLAGINO); + if (xfs_sb_version_hascrc(&mp->m_sb)) + platform_uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_uuid); for (c = 0; c < XFS_AGI_UNLINKED_BUCKETS; c++) agi->agi_unlinked[c] = cpu_to_be32(NULLAGINO); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); @@ -2555,16 +2790,19 @@ /* * BNO btree root block */ - buf = libxfs_getbuf(mp->m_dev, + buf = libxfs_getbuf(mp->m_ddev_targp, XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)), bsize); + buf->b_ops = &xfs_allocbt_buf_ops; block = XFS_BUF_TO_BLOCK(buf); memset(block, 0, blocksize); - block->bb_magic = cpu_to_be32(XFS_ABTB_MAGIC); - block->bb_level = 0; - block->bb_numrecs = cpu_to_be16(1); - block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); - block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); + if (xfs_sb_version_hascrc(&mp->m_sb)) + xfs_btree_init_block(mp, buf, XFS_ABTB_CRC_MAGIC, 0, 1, + agno, XFS_BTREE_CRC_BLOCKS); + else + xfs_btree_init_block(mp, buf, XFS_ABTB_MAGIC, 0, 1, + agno, 0); + arec = XFS_ALLOC_REC_ADDR(mp, block, 1); arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp)); if (loginternal && agno == logagno) { @@ -2591,23 +2829,35 @@ */ be32_add_cpu(&arec->ar_startblock, logblocks); } + /* + * Calculate the record block count and check for the case where + * the log might have consumed all available space in the AG. If + * so, reset the record count to 0 to avoid exposure of an invalid + * record start block. + */ arec->ar_blockcount = cpu_to_be32(agsize - be32_to_cpu(arec->ar_startblock)); + if (!arec->ar_blockcount) + block->bb_numrecs = 0; + libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* * CNT btree root block */ - buf = libxfs_getbuf(mp->m_dev, + buf = libxfs_getbuf(mp->m_ddev_targp, XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)), bsize); + buf->b_ops = &xfs_allocbt_buf_ops; block = XFS_BUF_TO_BLOCK(buf); memset(block, 0, blocksize); - block->bb_magic = cpu_to_be32(XFS_ABTC_MAGIC); - block->bb_level = 0; - block->bb_numrecs = cpu_to_be16(1); - block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); - block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); + if (xfs_sb_version_hascrc(&mp->m_sb)) + xfs_btree_init_block(mp, buf, XFS_ABTC_CRC_MAGIC, 0, 1, + agno, XFS_BTREE_CRC_BLOCKS); + else + xfs_btree_init_block(mp, buf, XFS_ABTC_MAGIC, 0, 1, + agno, 0); + arec = XFS_ALLOC_REC_ADDR(mp, block, 1); arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp)); if (loginternal && agno == logagno) { @@ -2624,30 +2874,61 @@ } be32_add_cpu(&arec->ar_startblock, logblocks); } + /* + * Calculate the record block count and check for the case where + * the log might have consumed all available space in the AG. If + * so, reset the record count to 0 to avoid exposure of an invalid + * record start block. + */ arec->ar_blockcount = cpu_to_be32(agsize - be32_to_cpu(arec->ar_startblock)); + if (!arec->ar_blockcount) + block->bb_numrecs = 0; + libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* * INO btree root block */ - buf = libxfs_getbuf(mp->m_dev, + buf = libxfs_getbuf(mp->m_ddev_targp, XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)), bsize); + buf->b_ops = &xfs_inobt_buf_ops; block = XFS_BUF_TO_BLOCK(buf); memset(block, 0, blocksize); - block->bb_magic = cpu_to_be32(XFS_IBT_MAGIC); - block->bb_level = 0; - block->bb_numrecs = 0; - block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); - block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); + if (xfs_sb_version_hascrc(&mp->m_sb)) + xfs_btree_init_block(mp, buf, XFS_IBT_CRC_MAGIC, 0, 0, + agno, XFS_BTREE_CRC_BLOCKS); + else + xfs_btree_init_block(mp, buf, XFS_IBT_MAGIC, 0, 0, + agno, 0); + libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); + + /* + * Free INO btree root block + */ + if (!finobt) + continue; + + buf = libxfs_getbuf(mp->m_ddev_targp, + XFS_AGB_TO_DADDR(mp, agno, XFS_FIBT_BLOCK(mp)), + bsize); + buf->b_ops = &xfs_inobt_buf_ops; + block = XFS_BUF_TO_BLOCK(buf); + memset(block, 0, blocksize); + if (xfs_sb_version_hascrc(&mp->m_sb)) + xfs_btree_init_block(mp, buf, XFS_FIBT_CRC_MAGIC, 0, 0, + agno, XFS_BTREE_CRC_BLOCKS); + else + xfs_btree_init_block(mp, buf, XFS_FIBT_MAGIC, 0, 0, + agno, 0); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); } /* * Touch last block, make fs the right size if it's a file. */ - buf = libxfs_getbuf(mp->m_dev, + buf = libxfs_getbuf(mp->m_ddev_targp, (xfs_daddr_t)XFS_FSB_TO_BB(mp, dblocks - 1LL), bsize); memset(XFS_BUF_PTR(buf), 0, blocksize); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); @@ -2655,8 +2936,8 @@ /* * Make sure we can write the last block in the realtime area. */ - if (mp->m_rtdev && rtblocks > 0) { - buf = libxfs_getbuf(mp->m_rtdev, + if (mp->m_rtdev_targp->dev && rtblocks > 0) { + buf = libxfs_getbuf(mp->m_rtdev_targp, XFS_FSB_TO_BB(mp, rtblocks - 1LL), bsize); memset(XFS_BUF_PTR(buf), 0, blocksize); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); @@ -2668,6 +2949,7 @@ for (agno = 0; agno < agcount; agno++) { xfs_alloc_arg_t args; xfs_trans_t *tp; + struct xfs_trans_res tres = {0}; memset(&args, 0, sizeof(args)); args.tp = tp = libxfs_trans_alloc(mp, 0); @@ -2675,8 +2957,10 @@ args.agno = agno; args.alignment = 1; args.pag = xfs_perag_get(mp,agno); - if ((c = libxfs_trans_reserve(tp, worst_freelist, 0, 0, 0, 0))) + c = libxfs_trans_reserve(tp, &tres, worst_freelist, 0); + if (c) res_failed(c); + libxfs_alloc_fix_freelist(&args, 0); xfs_perag_put(args.pag); libxfs_trans_commit(tp, 0); @@ -2685,7 +2969,6 @@ /* * Allocate the root inode and anything else in the proto file. */ - mp->m_rootip = NULL; parse_proto(mp, &fsx, &protostring); /* @@ -2709,7 +2992,7 @@ XFS_AGB_TO_DADDR(mp, mp->m_sb.sb_agcount-1, XFS_SB_DADDR), XFS_FSS_TO_BB(mp, 1), - LIBXFS_EXIT_ON_FAILURE); + LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops); XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64( mp->m_sb.sb_rootino); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); @@ -2721,7 +3004,7 @@ XFS_AGB_TO_DADDR(mp, (mp->m_sb.sb_agcount-1)/2, XFS_SB_DADDR), XFS_FSS_TO_BB(mp, 1), - LIBXFS_EXIT_ON_FAILURE); + LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops); XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64( mp->m_sb.sb_rootino); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); @@ -2733,7 +3016,6 @@ * Need to drop references to inodes we still hold, first. */ libxfs_rtmount_destroy(mp); - libxfs_icache_purge(); libxfs_bcache_purge(); /* @@ -2877,16 +3159,20 @@ { fprintf(stderr, _("Usage: %s\n\ /* blocksize */ [-b log=n|size=num]\n\ +/* metadata */ [-m crc=0|1,finobt=0|1]\n\ /* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\ - (sunit=value,swidth=value|su=num,sw=num),\n\ + (sunit=value,swidth=value|su=num,sw=num|noalign),\n\ sectlog=n|sectsize=num\n\ +/* force overwrite */ [-f]\n\ /* inode size */ [-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,\n\ projid32bit=0|1]\n\ +/* no discard */ [-K]\n\ /* log subvol */ [-l agnum=n,internal,size=num,logdev=xxx,version=n\n\ sunit=value|su=num,sectlog=n|sectsize=num,\n\ lazy-count=0|1]\n\ /* label */ [-L label (maximum 12 characters)]\n\ -/* naming */ [-n log=n|size=num,version=2|ci]\n\ +/* naming */ [-n log=n|size=num,version=2|ci,ftype=0|1]\n\ +/* no-op info only */ [-N]\n\ /* prototype file */ [-p fname]\n\ /* quiet */ [-q]\n\ /* realtime subvol */ [-r extsize=num,size=num,rtdev=xxx]\n\ diff -Nru xfsprogs-3.1.9ubuntu2/mkfs/xfs_mkfs.h xfsprogs-3.2.1ubuntu1/mkfs/xfs_mkfs.h --- xfsprogs-3.1.9ubuntu2/mkfs/xfs_mkfs.h 2010-11-09 11:17:04.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/mkfs/xfs_mkfs.h 2014-05-02 00:09:16.000000000 +0000 @@ -23,9 +23,9 @@ XFS_SB_VERSION_EXTFLGBIT | \ XFS_SB_VERSION_DIRV2BIT) -#define XFS_SB_VERSION_MKFS(ia,dia,log2,attr1,sflag,ci,more) (\ - ((ia)||(dia)||(log2)||(attr1)||(sflag)||(ci)||(more)) ? \ - ( XFS_SB_VERSION_4 | \ +#define XFS_SB_VERSION_MKFS(crc,ia,dia,log2,attr1,sflag,ci,more) (\ + ((crc)||(ia)||(dia)||(log2)||(attr1)||(sflag)||(ci)||(more)) ? \ + (((crc) ? XFS_SB_VERSION_5 : XFS_SB_VERSION_4) | \ ((ia) ? XFS_SB_VERSION_ALIGNBIT : 0) | \ ((dia) ? XFS_SB_VERSION_DALIGNBIT : 0) | \ ((log2) ? XFS_SB_VERSION_LOGV2BIT : 0) | \ @@ -36,15 +36,19 @@ XFS_DFL_SB_VERSION_BITS | \ 0 ) : XFS_SB_VERSION_1 ) -#define XFS_SB_VERSION2_MKFS(lazycount, attr2, projid32bit, parent) (\ +#define XFS_SB_VERSION2_MKFS(crc, lazycount, attr2, projid32bit, parent, \ + ftype) (\ ((lazycount) ? XFS_SB_VERSION2_LAZYSBCOUNTBIT : 0) | \ ((attr2) ? XFS_SB_VERSION2_ATTR2BIT : 0) | \ ((projid32bit) ? XFS_SB_VERSION2_PROJID32BIT : 0) | \ ((parent) ? XFS_SB_VERSION2_PARENTBIT : 0) | \ + ((crc) ? XFS_SB_VERSION2_CRCBIT : 0) | \ + ((ftype) ? XFS_SB_VERSION2_FTYPE : 0) | \ 0 ) #define XFS_DFL_BLOCKSIZE_LOG 12 /* 4096 byte blocks */ #define XFS_DINODE_DFL_LOG 8 /* 256 byte inodes */ +#define XFS_DINODE_DFL_CRC_LOG 9 /* 512 byte inodes for CRCs */ #define XFS_MIN_DATA_BLOCKS 100 #define XFS_MIN_INODE_PERBLOCK 2 /* min inodes per block */ #define XFS_DFL_IMAXIMUM_PCT 25 /* max % of space for inodes */ @@ -52,8 +56,7 @@ #define XFS_MIN_REC_DIRSIZE 12 /* 4096 byte dirblocks (V2) */ #define XFS_DFL_DIR_VERSION 2 /* default directory version */ #define XFS_DFL_LOG_SIZE 1000 /* default log size, blocks */ -#define XFS_MIN_LOG_FACTOR 3 /* min log size factor */ -#define XFS_DFL_LOG_FACTOR 16 /* default log size, factor */ +#define XFS_DFL_LOG_FACTOR 5 /* default log size, factor */ /* with max trans reservation */ #define XFS_MAX_INODE_SIG_BITS 32 /* most significant bits in an * inode number that we'll @@ -79,7 +82,8 @@ extern void res_failed (int err); /* maxtrres.c */ -extern int max_trans_res (int dirversion, - int sectorlog, int blocklog, int inodelog, int dirblocklog); +extern int max_trans_res (int crcs_enabled, int dirversion, + int sectorlog, int blocklog, int inodelog, int dirblocklog, + int logversion, int log_sunit); #endif /* __XFS_MKFS_H__ */ diff -Nru xfsprogs-3.1.9ubuntu2/po/de.po xfsprogs-3.2.1ubuntu1/po/de.po --- xfsprogs-3.1.9ubuntu2/po/de.po 2009-12-06 20:58:01.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/po/de.po 2014-05-02 00:21:38.000000000 +0000 @@ -11,6 +11,7 @@ "PO-Revision-Date: 2009-10-21 21:08+0100\n" "Last-Translator: Chris Leick \n" "Language-Team: German \n" +"Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff -Nru xfsprogs-3.1.9ubuntu2/po/pl.po xfsprogs-3.2.1ubuntu1/po/pl.po --- xfsprogs-3.1.9ubuntu2/po/pl.po 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/po/pl.po 2014-07-21 09:13:53.000000000 +0000 @@ -1,13 +1,13 @@ # Polish translation for xfsprogs. # This file is distributed under the same license as the xfsprogs package. -# Jakub Bogusz , 2006-2012. +# Jakub Bogusz , 2006-2014. # msgid "" msgstr "" -"Project-Id-Version: xfsprogs 3.1.8\n" +"Project-Id-Version: xfsprogs 3.2.0+git20140709\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-04 06:24+0100\n" -"PO-Revision-Date: 2012-03-04 07:30+0100\n" +"POT-Creation-Date: 2014-07-09 19:08+0200\n" +"PO-Revision-Date: 2014-07-09 20:45+0200\n" "Last-Translator: Jakub Bogusz \n" "Language-Team: Polish \n" "Language: pl\n" @@ -15,6612 +15,6906 @@ "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: .././rtcp/xfs_rtcp.c:30 +#: .././copy/xfs_copy.c:102 #, c-format -msgid "%s [-e extsize] [-p] source target\n" -msgstr "%s [-e rozm_fragmentu] [-p] źródło cel\n" +msgid "Check logfile \"%s\" for more details\n" +msgstr "Więcej szczegółów w pliku logu \"%s\"\n" -#: .././rtcp/xfs_rtcp.c:55 .././repair/xfs_repair.c:317 .././quota/init.c:131 -#: .././mkfs/xfs_mkfs.c:1623 .././logprint/logprint.c:196 .././io/init.c:183 -#: .././growfs/xfs_growfs.c:182 .././fsr/xfs_fsr.c:302 -#: .././estimate/xfs_estimate.c:141 .././db/init.c:93 .././copy/xfs_copy.c:543 +#: .././copy/xfs_copy.c:108 #, c-format -msgid "%s version %s\n" -msgstr "%s wersja %s\n" +msgid "%s: could not write to logfile \"%s\".\n" +msgstr "%s: nie udało się zapisać pliku logu \"%s\".\n" -#: .././rtcp/xfs_rtcp.c:69 +#: .././copy/xfs_copy.c:111 #, c-format -msgid "%s: must specify files to copy\n" -msgstr "%s: trzeba podać pliki do skopiowania\n" +msgid "Aborting XFS copy -- logfile error -- reason: %s\n" +msgstr "Przerwano XFS copy - błąd pliku logu - przyczyna: %s\n" -#: .././rtcp/xfs_rtcp.c:84 -#, c-format -msgid "%s: stat64 of %s failed\n" -msgstr "%s: stat64 na %s nie powiodło się\n" +#: .././copy/xfs_copy.c:126 .././copy/xfs_copy.c:267 .././copy/xfs_copy.c:546 +#: .././copy/xfs_copy.c:553 +msgid "Aborting XFS copy - reason" +msgstr "Przerwano XFS copy - przyczyna" -#: .././rtcp/xfs_rtcp.c:91 -#, c-format -msgid "%s: final argument is not directory\n" -msgstr "%s: ostatni argument nie jest katalogiem\n" +#: .././copy/xfs_copy.c:140 +msgid "THE FOLLOWING COPIES FAILED TO COMPLETE\n" +msgstr "NASTĘPUJĄCYCH KOPII NIE UDAŁO SIĘ UKOŃCZYĆ\n" -#: .././rtcp/xfs_rtcp.c:138 +#: .././copy/xfs_copy.c:144 +msgid "write error" +msgstr "błąd zapisu" + +#: .././copy/xfs_copy.c:146 +msgid "lseek64 error" +msgstr "błąd lseek64" + +#: .././copy/xfs_copy.c:147 #, c-format -msgid "%s: failed stat64 on %s: %s\n" -msgstr "%s: nie udało się wykonać stat64 na %s: %s\n" +msgid " at offset %lld\n" +msgstr " pod offsetem %lld\n" -#: .././rtcp/xfs_rtcp.c:159 +#: .././copy/xfs_copy.c:151 #, c-format -msgid "%s: %s filesystem has no realtime partition\n" -msgstr "%s: system plików %s nie ma partycji realtime\n" +msgid "All copies completed.\n" +msgstr "Wszystkie kopie ukończone.\n" -#: .././rtcp/xfs_rtcp.c:180 .././rtcp/xfs_rtcp.c:208 +#: .././copy/xfs_copy.c:154 #, c-format -msgid "%s: open of %s failed: %s\n" -msgstr "%s: otwarcie %s nie powiodło się: %s\n" +msgid "See \"%s\" for more details.\n" +msgstr "Więcej szczegółów w \"%s\".\n" -#: .././rtcp/xfs_rtcp.c:197 +#: .././copy/xfs_copy.c:236 #, c-format -msgid "%s: set attributes on %s failed: %s\n" -msgstr "%s: ustawienie atrybutów dla %s nie powiodło się: %s\n" +msgid "%s: write error on target %d \"%s\" at offset %lld\n" +msgstr "%s: błąd zapisu przy celu %d \"%s\" pod offsetem %lld\n" -#: .././rtcp/xfs_rtcp.c:215 +#: .././copy/xfs_copy.c:241 #, c-format -msgid "%s: get attributes of %s failed: %s\n" -msgstr "%s: pobranie atrybutów %s nie powiodło się: %s\n" +msgid "%s: lseek64 error on target %d \"%s\" at offset %lld\n" +msgstr "%s: błąd lseek64 przy celu %d \"%s\" pod offsetem %lld\n" -#: .././rtcp/xfs_rtcp.c:225 .././rtcp/xfs_rtcp.c:260 +#: .././copy/xfs_copy.c:247 #, c-format -msgid "%s: %s is not a realtime file.\n" -msgstr "%s: %s nie jest plikiem realtime.\n" +msgid "Aborting target %d - reason" +msgstr "Przerywano zapis celu %d - przyczyna" -#: .././rtcp/xfs_rtcp.c:234 +#: .././copy/xfs_copy.c:251 +msgid "Aborting XFS copy - no more targets.\n" +msgstr "Przerwano XFS copy - nie ma więcej celów.\n" + +#: .././copy/xfs_copy.c:262 #, c-format -msgid "%s: %s file extent size is %d, instead of %d.\n" -msgstr "%s: plik %s ma rozmiar ekstentu %d zamiast %d.\n" +msgid "%s: thread %d died unexpectedly, target \"%s\" incomplete\n" +msgstr "%s: wątek %d zmarł nieoczekiwanie, cel \"%s\" niekompletny\n" -#: .././rtcp/xfs_rtcp.c:246 .././rtcp/xfs_rtcp.c:269 +#: .././copy/xfs_copy.c:264 #, c-format -msgid "%s: open of %s source failed: %s\n" -msgstr "%s: otwarcie źródła %s nie powiodło się: %s\n" +msgid "%s: offset was probably %lld\n" +msgstr "%s: offset prawdopodobnie %lld\n" -#: .././rtcp/xfs_rtcp.c:283 +#: .././copy/xfs_copy.c:275 #, c-format -msgid "%s: couldn't get direct I/O information: %s\n" -msgstr "%s: nie udało się uzyskać informacji o bezpośrednim we/wy: %s\n" +msgid "%s: Unknown child died (should never happen!)\n" +msgstr "%s: Nieznany potomek zmarł (nie powinno się zdarzyć!)\n" -#: .././rtcp/xfs_rtcp.c:293 +#: .././copy/xfs_copy.c:285 #, c-format -msgid "%s: extent size %d not a multiple of %d.\n" -msgstr "%s: rozmiar ekstentu %d nie jest wielokrotnością %d.\n" +msgid "Usage: %s [-bdV] [-L logfile] source target [target ...]\n" +msgstr "Składnia: %s [-bdV] [-L plik_logu] źródło cel [cel ...]\n" -#: .././rtcp/xfs_rtcp.c:307 +#: .././copy/xfs_copy.c:367 #, c-format -msgid "The size of %s is not a multiple of %d.\n" -msgstr "Rozmiar %s nie jest wielokrotnością %d.\n" +msgid "%s: lseek64 failure at offset %lld\n" +msgstr "%s: niepowodzenie lseek64 pod offsetem %lld\n" -#: .././rtcp/xfs_rtcp.c:310 +#: .././copy/xfs_copy.c:382 #, c-format -msgid "%s will be padded to %lld bytes.\n" -msgstr "%s: zostanie dopełniony do %lld bajtów.\n" +msgid "assert error: buf->length = %d, buf->size = %d\n" +msgstr "błąd zapewnienia: buf->length = %d, buf->size = %d\n" -#: .././rtcp/xfs_rtcp.c:316 +#: .././copy/xfs_copy.c:388 #, c-format -msgid "Use the -p option to pad %s to a size which is a multiple of %d bytes.\n" -msgstr "Można użyć opcji -p do dopełnienia %s do rozmiaru będącego wielokrotnością %d bajtów.\n" +msgid "%s: read failure at offset %lld\n" +msgstr "%s: błąd odczytu pod offsetem %lld\n" -#: .././rtcp/xfs_rtcp.c:358 +#: .././copy/xfs_copy.c:418 +msgid "ag header buffer invalid!\n" +msgstr "błędny bufor nagłówka ag!\n" + +#: .././copy/xfs_copy.c:526 .././db/init.c:94 .././estimate/xfs_estimate.c:144 +#: .././fsr/xfs_fsr.c:300 .././growfs/xfs_growfs.c:182 .././io/init.c:190 +#: .././logprint/logprint.c:203 .././mkfs/xfs_mkfs.c:1703 +#: .././quota/init.c:131 .././repair/xfs_repair.c:319 .././rtcp/xfs_rtcp.c:55 #, c-format -msgid "%s: write error: %s\n" -msgstr "%s: błąd zapisu: %s\n" +msgid "%s version %s\n" +msgstr "%s wersja %s\n" -#: .././rtcp/xfs_rtcp.c:386 +#: .././copy/xfs_copy.c:544 #, c-format -msgid "%s: could not open %s: %s\n" -msgstr "%s: nie udało się otworzyć %s: %s\n" +msgid "%s: couldn't open log file \"%s\"\n" +msgstr "%s: nie udało się otworzyć pliku logu \"%s\"\n" -#: .././repair/xfs_repair.c:81 +#: .././copy/xfs_copy.c:551 #, c-format -msgid "" -"Usage: %s [options] device\n" -"\n" -"Options:\n" -" -f The device is a file\n" -" -L Force log zeroing. Do this as a last resort.\n" -" -l logdev Specifies the device where the external log resides.\n" -" -m maxmem Maximum amount of memory to be used in megabytes.\n" -" -n No modify mode, just checks the filesystem for damage.\n" -" -P Disables prefetching.\n" -" -r rtdev Specifies the device where the realtime section resides.\n" -" -v Verbose output.\n" -" -c subopts Change filesystem parameters - use xfs_admin.\n" -" -o subopts Override default behaviour, refer to man page.\n" -" -t interval Reporting interval in minutes.\n" -" -d Repair dangerously.\n" -" -V Reports version and exits.\n" -msgstr "" -"Składnia: %s [opcje] urządzenie\n" -"\n" -"Opcje:\n" -" -f Urządzenie jest plikiem\n" -" -L Wymuszenie wyzerowania logu. Wykonywać tylko w ostateczności.\n" -" -l urz_logu Określenie urządzenia z zewnętrznym logiem.\n" -" -m maks_pam Maksymalna ilość pamięci do użycia w megabajtach.\n" -" -n Tryb bez modyfikacji, tylko sprawdzenie systemu plików.\n" -" -P Wyłączenie prefetch.\n" -" -r urz_rt Określenie urządzenia z sekcją realtime.\n" -" -v Szczegółowe wyjście.\n" -" -c podopcje Zmiana parametrów systemu plików przy użyciu xfs_admina.\n" -" -o podopcje Zmiana domyślnego zachowania, więcej na stronie manuala.\n" -" -t czas Okres informowania o postępach w minutach.\n" -" -d Naprawianie w sposób niebezpieczny.\n" -" -V Wypisanie informacji o wersji i zakończenie.\n" +msgid "%s: couldn't set up logfile stream\n" +msgstr "%s: nie udało się ustanowić strumienia pliku logu\n" -#: .././repair/xfs_repair.c:107 -msgid "no error" -msgstr "brak błędu" +#: .././copy/xfs_copy.c:563 +msgid "Couldn't allocate target array\n" +msgstr "Nie udało się przydzielić tablicy celów\n" -#: .././repair/xfs_repair.c:108 -msgid "bad magic number" -msgstr "błędna liczba magiczna" +#: .././copy/xfs_copy.c:582 +#, c-format +msgid "%s: couldn't open source \"%s\"\n" +msgstr "%s: nie udało się otworzyć źródła \"%s\"\n" -#: .././repair/xfs_repair.c:109 -msgid "bad blocksize field" -msgstr "błędne pole blocksize" +#: .././copy/xfs_copy.c:588 +#, c-format +msgid "%s: couldn't stat source \"%s\"\n" +msgstr "%s: nie udało się wykonać stat na źródle \"%s\"\n" -#: .././repair/xfs_repair.c:110 -msgid "bad blocksize log field" -msgstr "błędne pole logu blocksize" +#: .././copy/xfs_copy.c:598 +#, c-format +msgid "%s: Cannot set direct I/O flag on \"%s\".\n" +msgstr "%s: Nie można ustawić flagi bezpośredniego we/wy na \"%s\".\n" -#: .././repair/xfs_repair.c:111 -msgid "bad or unsupported version" -msgstr "błędna lub nie obsługiwana wersja" +#: .././copy/xfs_copy.c:603 +#, c-format +msgid "%s: xfsctl on file \"%s\" failed.\n" +msgstr "%s: xfsctl na pliku \"%s\" nie powiodło się.\n" -#: .././repair/xfs_repair.c:113 -msgid "filesystem mkfs-in-progress bit set" -msgstr "ustawiony bit mkfs-in-progress systemu plików" +#: .././copy/xfs_copy.c:626 +#, c-format +msgid "%s: Warning -- a filesystem is mounted on the source device.\n" +msgstr "%s: Uwaga - system plików jest podmontowany na urządzeniu źródłowym.\n" -#: .././repair/xfs_repair.c:115 -msgid "inconsistent filesystem geometry information" -msgstr "niespójne informacje o geometrii systemu plików" +#: .././copy/xfs_copy.c:629 +msgid "\t\tGenerated copies may be corrupt unless the source is\n" +msgstr "\t\tWygenerowane kopie mogą być uszkodzone o ile źródło nie jest\n" -#: .././repair/xfs_repair.c:117 -msgid "bad inode size or inconsistent with number of inodes/block" -msgstr "błędny rozmiar i-węzła lub niespójność z liczbą i-węzłów/blok" +#: .././copy/xfs_copy.c:631 +msgid "\t\tunmounted or mounted read-only. Copy proceeding...\n" +msgstr "\t\todmontowane lub podmontowane tylko do odczytu. Kopiowanie w trakcie...\n" -#: .././repair/xfs_repair.c:118 -msgid "bad sector size" -msgstr "błędny rozmiar sektora" +#: .././copy/xfs_copy.c:648 +#, c-format +msgid "" +"%s: couldn't initialize XFS library\n" +"%s: Aborting.\n" +msgstr "" +"%s: nie udało się zainicjować biblioteki XFS\n" +"%s: Przerwano.\n" -#: .././repair/xfs_repair.c:120 -msgid "AGF geometry info conflicts with filesystem geometry" -msgstr "informacje o geometrii AGF są w konflikcie z geometrią systemu plików" +#: .././copy/xfs_copy.c:668 +#, c-format +msgid "%s: Cannot yet copy V5 fs without '-d'\n" +msgstr "%s: Nie można jeszcze kopiować systemu plików V5 bez '-d'\n" -#: .././repair/xfs_repair.c:122 -msgid "AGI geometry info conflicts with filesystem geometry" -msgstr "informacje o geometrii AGI są w konflikcie z geometrią systemu plików" +#: .././copy/xfs_copy.c:674 +#, c-format +msgid "" +"%s: %s filesystem failed to initialize\n" +"%s: Aborting.\n" +msgstr "" +"%s: Nie powiodła się inicjalizacja systemu plików %s\n" +"%s: Przerwano.\n" -#: .././repair/xfs_repair.c:124 -msgid "AG superblock geometry info conflicts with filesystem geometry" -msgstr "informacje o geometrii superbloku AG są w konflikcie z geometrią systemu plików" +#: .././copy/xfs_copy.c:678 +#, c-format +msgid "" +"%s %s filesystem failed to initialize\n" +"%s: Aborting.\n" +msgstr "" +"%s: Nie powiodła się inicjalizacja systemu plików %s\n" +"%s: Przerwano.\n" -#: .././repair/xfs_repair.c:125 -msgid "attempted to perform I/O beyond EOF" -msgstr "próbowano wykonać operację we/wy poza końcem pliku" +#: .././copy/xfs_copy.c:682 +#, c-format +msgid "" +"%s: %s has an external log.\n" +"%s: Aborting.\n" +msgstr "" +"%s: %s ma zewnętrzny log.\n" +"%s: Przerwano.\n" -#: .././repair/xfs_repair.c:127 -msgid "inconsistent filesystem geometry in realtime filesystem component" -msgstr "niespójna geometria systemu plików w składniku realtime" +#: .././copy/xfs_copy.c:686 +#, c-format +msgid "" +"%s: %s has a real-time section.\n" +"%s: Aborting.\n" +msgstr "" +"%s: %s ma sekcję real-time.\n" +"%s: Przerwano.\n" -#: .././repair/xfs_repair.c:129 -msgid "maximum indicated percentage of inodes > 100%" -msgstr "określono maksymalny procent i-węzłów > 100%" +#: .././copy/xfs_copy.c:711 +msgid "" +"Error: filesystem block size is smaller than the disk sectorsize.\n" +"Aborting XFS copy now.\n" +msgstr "" +"Błąd: rozmiar bloku systemu plików jest mniejszy niż rozmiar sektora dysku.\n" +"Przerwano XFS copy.\n" -#: .././repair/xfs_repair.c:131 -msgid "inconsistent inode alignment value" -msgstr "niespójna wartość wyrównania i-węzła" +#: .././copy/xfs_copy.c:732 +#, c-format +msgid "Creating file %s\n" +msgstr "Tworzenie pliku %s\n" -#: .././repair/xfs_repair.c:133 -msgid "not enough secondary superblocks with matching geometry" -msgstr "za mało zapasowych superbloków o pasującej geometrii" - -#: .././repair/xfs_repair.c:135 -msgid "bad stripe unit in superblock" -msgstr "błędna jednostka pasa w superbloku" - -#: .././repair/xfs_repair.c:137 -msgid "bad stripe width in superblock" -msgstr "błędna szerokość pasa w superbloku" +#: .././copy/xfs_copy.c:750 +#, c-format +msgid "" +"%s: a filesystem is mounted on target device \"%s\".\n" +"%s cannot copy to mounted filesystems. Aborting\n" +msgstr "" +"%s: na urządzeniu docelowym \"%s\" jest podmontowany system plików.\n" +"%s nie może kopiować na podmontowane systemy plików. Przerwano.\n" -#: .././repair/xfs_repair.c:139 -msgid "bad shared version number in superblock" -msgstr "błędny numer wersji współdzielenia w superbloku" +#: .././copy/xfs_copy.c:761 +#, c-format +msgid "%s: couldn't open target \"%s\"\n" +msgstr "%s: nie udało się otworzyć celu \"%s\"\n" -#: .././repair/xfs_repair.c:144 +#: .././copy/xfs_copy.c:771 #, c-format -msgid "bad error code - %d\n" -msgstr "błędny kod błędu - %d\n" +msgid "%s: cannot grow data section.\n" +msgstr "%s: nie można powiększyć sekcji danych.\n" -#: .././repair/xfs_repair.c:152 +#: .././copy/xfs_copy.c:779 #, c-format -msgid "-%c %s option cannot have a value\n" -msgstr "opcja -%c %s nie przyjmuje wartości\n" +msgid "%s: xfsctl on \"%s\" failed.\n" +msgstr "%s: xfsctl na \"%s\" nie powiodło się.\n" -#: .././repair/xfs_repair.c:162 .././mkfs/xfs_mkfs.c:2801 +#: .././copy/xfs_copy.c:798 #, c-format -msgid "option respecified\n" -msgstr "ponownie podana opcja\n" +msgid "%s: failed to write last block\n" +msgstr "%s: nie udało się zapisać ostatniego bloku\n" -#: .././repair/xfs_repair.c:169 .././mkfs/xfs_mkfs.c:2810 +#: .././copy/xfs_copy.c:800 #, c-format -msgid "unknown option -%c %s\n" -msgstr "nieznana opcja -%c %s\n" +msgid "\tIs target \"%s\" too small?\n" +msgstr "\tCzy cel \"%s\" jest zbyt mały?\n" -#: .././repair/xfs_repair.c:248 -msgid "-o bhash option cannot be used with -m option\n" -msgstr "opcja -o bhash nie może być użyta wraz z opcją -m\n" +#: .././copy/xfs_copy.c:810 +msgid "Couldn't initialize global thread mask\n" +msgstr "Nie udało się zainicjować globalnej maski wątków\n" -#: .././repair/xfs_repair.c:300 -msgid "-m option cannot be used with -o bhash option\n" -msgstr "opcja -m nie może być użyta wraz z opcją -o bhash\n" +#: .././copy/xfs_copy.c:817 +msgid "Error initializing wbuf 0\n" +msgstr "Błąd inicjalizacji wbuf 0\n" -#: .././repair/xfs_repair.c:342 -#, c-format -msgid "" -"\n" -"fatal error -- " -msgstr "" -"\n" -"błąd krytyczny - " +#: .././copy/xfs_copy.c:825 +msgid "Error initializing btree buf 1\n" +msgstr "Błąd inicjalizacji btree buf 1\n" -#: .././repair/xfs_repair.c:454 -#, c-format -msgid "sb root inode value % %sinconsistent with calculated value %u\n" -msgstr "wartość i-węzła głównego superbloku % %sniespójna z obliczoną wartością %u\n" +#: .././copy/xfs_copy.c:830 +msgid "Error creating first semaphore.\n" +msgstr "Błąd tworzenia pierwszego semafora.\n" -#: .././repair/xfs_repair.c:461 -#, c-format -msgid "resetting superblock root inode pointer to %u\n" -msgstr "przestawiono wskaźnik i-węzła głównego superbloku na %u\n" +#: .././copy/xfs_copy.c:845 +msgid "Couldn't malloc space for thread args\n" +msgstr "Nie udało się przydzielić miejsca na argumenty wątku\n" -#: .././repair/xfs_repair.c:465 +#: .././copy/xfs_copy.c:857 #, c-format -msgid "would reset superblock root inode pointer to %u\n" -msgstr "wskaźnik i-węzła głównego superbloku zostałby przestawiony na %u\n" +msgid "Error creating thread mutex %d\n" +msgstr "Błąd podczas tworzenia sekcji krytycznej %d wątku\n" -#: .././repair/xfs_repair.c:477 +#: .././copy/xfs_copy.c:874 #, c-format -msgid "sb realtime bitmap inode % %sinconsistent with calculated value %u\n" -msgstr "i-węzeł bitmapy realtime superbloku % %sniespójny z obliczoną wartością %u\n" +msgid "Error creating thread for target %d\n" +msgstr "Błąd podczas tworzenia wątku dla celu %d\n" -#: .././repair/xfs_repair.c:484 +#: .././copy/xfs_copy.c:928 #, c-format -msgid "resetting superblock realtime bitmap ino pointer to %u\n" -msgstr "przestawiono wskaźnik i-węzła bitmapy realtime superbloku na %u\n" +msgid "Error: current level %d >= btree levels %d\n" +msgstr "Błąd: bieżący poziom %d >= poziomów b-drzewa %d\n" -#: .././repair/xfs_repair.c:488 +#: .././copy/xfs_copy.c:947 #, c-format -msgid "would reset superblock realtime bitmap ino pointer to %u\n" -msgstr "wskaźnik i-węzła bitmapy realtime superbloku zostałby przestawiony na %u\n" +msgid "Bad btree magic 0x%x\n" +msgstr "Niewłaściwa liczba magiczna b-drzewa 0x%x\n" -#: .././repair/xfs_repair.c:500 -#, c-format -msgid "sb realtime summary inode % %sinconsistent with calculated value %u\n" -msgstr "i-węzeł opisu realtime superbloku % %sniespójny z obliczoną wartością %u\n" +#: .././copy/xfs_copy.c:974 +msgid "WARNING: source filesystem inconsistent.\n" +msgstr "UWAGA: źródłowy system plików niespójny.\n" -#: .././repair/xfs_repair.c:507 -#, c-format -msgid "resetting superblock realtime summary ino pointer to %u\n" -msgstr "przestawiono wskaźnik i-węzła opisu realtime superbloku na %u\n" +#: .././copy/xfs_copy.c:976 +msgid " A leaf btree rec isn't a leaf. Aborting now.\n" +msgstr " Liść rekordu b-drzewa nie jest liściem. Przerwano.\n" -#: .././repair/xfs_repair.c:511 -#, c-format -msgid "would reset superblock realtime summary ino pointer to %u\n" -msgstr "wskaźnik i-węzła opisu realtime superbloku zostałby przestawiony na %u\n" +#: .././db/addr.c:35 +msgid "[field-expression]" +msgstr "[wyrażenie-pól]" -#: .././repair/xfs_repair.c:554 -msgid "" -"Primary superblock would have been modified.\n" -"Cannot proceed further in no_modify mode.\n" -"Exiting now.\n" -msgstr "" -"Główny superblok zostałby zmodyfikowany.\n" -"Nie można kontynuować w trybie bez modyfikacji.\n" -"Zakończono.\n" +#: .././db/addr.c:36 +msgid "set current address" +msgstr "ustawienie bieżącego adresu" -#: .././repair/xfs_repair.c:577 +#: .././db/addr.c:42 msgid "" -"Cannot get host filesystem geometry.\n" -"Repair may fail if there is a sector size mismatch between\n" -"the image and the host filesystem.\n" +"\n" +" 'addr' uses the given field to set the filesystem address and type\n" +"\n" +" Examples:\n" +"\n" +" sb\n" +" a rootino - set the type to inode and set position to the root inode\n" +" a u.bmx[0].startblock (for inode with blockmap)\n" +"\n" msgstr "" -"Nie można pobrać geometrii systemu plików hosta.\n" -"Naprawienie może się nie powieść, jeśli istnieje niespójność rozmiaru\n" -"sektora między obrazem a systemem plików hosta.\n" +"\n" +" 'addr' wykorzystuje podane pole do ustawienia adresu w systemie plików i typu\n" +"\n" +" Przykłady:\n" +"\n" +" sb\n" +" a rootino - ustawienie typu na i-węzeł i pozycji na i-węzeł główny\n" +" a u.bmx[0].startblock (dla i-węzła z mapą bloków)\n" +"\n" -#: .././repair/xfs_repair.c:589 -msgid "" -"Sector size on host filesystem larger than image sector size.\n" -"Cannot turn off direct IO, so exiting.\n" -msgstr "" -"Rozmiar sektora na systemie plików hosta większy niż rozmiar sektora obrazu.\n" -"Nie można wyłączyć bezpośredniego we/wy - zakończono działanie.\n" +#: .././db/addr.c:72 .././db/attrset.c:86 .././db/attrset.c:189 +#: .././db/print.c:74 .././db/type.c:142 .././db/write.c:101 +msgid "no current type\n" +msgstr "brak bieżącego typu\n" -#: .././repair/xfs_repair.c:599 +#: .././db/addr.c:82 #, c-format -msgid "%s: cannot repair this filesystem. Sorry.\n" -msgstr "%s: niestety nie można naprawić tego systemu plików.\n" +msgid "no fields for type %s\n" +msgstr "brak pól dla typu %s\n" -#: .././repair/xfs_repair.c:624 -#, c-format -msgid " - reporting progress in intervals of %s\n" -msgstr " - informowanie o postępie w odstępach %s\n" +#: .././db/addr.c:94 +msgid "array not allowed for addr command\n" +msgstr "tablica nie jest dozwolona dla polecenia addr\n" -#: .././repair/xfs_repair.c:671 +#: .././db/addr.c:103 #, c-format -msgid " - max_mem = %lu, icount = %, imem = %, dblock = %, dmem = %\n" -msgstr " - max_mem = %lu, icount = %, imem = %, dblock = %, dmem = %\n" +msgid "no next type for field %s\n" +msgstr "brak następnego typu dla pola %s\n" -#: .././repair/xfs_repair.c:684 +#: .././db/addr.c:110 #, c-format -msgid "" -"Required memory for repair is greater that the maximum specified\n" -"with the -m option. Please increase it to at least %lu.\n" -msgstr "" -"Pamięć wymagana do naprawy przekracza maksimum określone opcją -m.\n" -"Proszę ją zwiększyć do co najmniej %lu.\n" +msgid "no addr function for field %s (type %s)\n" +msgstr "brak funkcji addr dla pola %s (typu %s)\n" -#: .././repair/xfs_repair.c:689 -#, c-format -msgid "" -"Not enough RAM available for repair to enable prefetching.\n" -"This will be _slow_.\n" -"You need at least %luMB RAM to run with prefetching enabled.\n" -msgstr "" -"Zbyt mało dostępnej pamięci RAM, żeby naprawiać z włączonym prefetch.\n" -"To będzie _wolne_.\n" -"Do włączenia prefetch potrzeba przynajmniej %luMB RAM.\n" +#: .././db/agf.c:35 .././db/agfl.c:36 .././db/agi.c:35 .././db/sb.c:42 +msgid "[agno]" +msgstr "[agno]" -#: .././repair/xfs_repair.c:707 -#, c-format -msgid " - block cache size set to %d entries\n" -msgstr " - rozmiar bufora bloku ustawiony na %d wpisów\n" +#: .././db/agf.c:36 +msgid "set address to agf header" +msgstr "ustawienie adresu na nagłówek agf" -#: .././repair/xfs_repair.c:736 -msgid "Found unsupported filesystem features. Exiting now.\n" -msgstr "Znaleziono nie obsługiwane cechy systemu plików. Zakończono.\n" +#: .././db/agf.c:82 +msgid "" +"\n" +" set allocation group free block list\n" +"\n" +" Example:\n" +"\n" +" agf 2 - move location to AGF in 2nd filesystem allocation group\n" +"\n" +" Located in the second sector of each allocation group, the AGF\n" +" contains the root of two different freespace btrees:\n" +" The 'cnt' btree keeps track freespace indexed on section size.\n" +" The 'bno' btree tracks sections of freespace indexed on block number.\n" +msgstr "" +"\n" +" ustawienie listy wolnych bloków grupy alokacji\n" +"\n" +" Przykład:\n" +"\n" +" agf 2 - zmiana pozycji na AGF w 2. grupie alokacji systemu plików\n" +"\n" +" Położony w drugim sektorze każdej grupy alokacji AGF zawiera korzeń\n" +" dwóch różnych b-drzew wolnej przestrzeni:\n" +" b-drzewo 'cnt' śledzi wolne miejsce indeksowane rozmiarem sekcji\n" +" b-drzewo 'bno' śledzi sekcje wolnego miejsca indeksowane numerem bloku.\n" -#: .././repair/xfs_repair.c:754 +#: .././db/agf.c:107 .././db/agfl.c:106 .././db/agi.c:94 .././db/sb.c:163 #, c-format -msgid "No modify flag set, skipping phase 5\n" -msgstr "Ustawiono flagę braku modyfikacji, pominięto fazę 5\n" - -#: .././repair/xfs_repair.c:773 -msgid "Inode allocation btrees are too corrupted, skipping phases 6 and 7\n" -msgstr "B-drzewa alokacji i-węzłów są zbyt uszkodzone, pominięto fazy 6 i 7\n" - -#: .././repair/xfs_repair.c:779 -msgid "Warning: no quota inodes were found. Quotas disabled.\n" -msgstr "Uwaga: nie znaleziono i-węzłów limitów (quot). Limity wyłączone.\n" - -#: .././repair/xfs_repair.c:782 -msgid "Warning: no quota inodes were found. Quotas would be disabled.\n" -msgstr "Uwaga: nie znaleziono i-węzłów limitów (quot). Limity zostałyby wyłączone.\n" - -#: .././repair/xfs_repair.c:787 -msgid "Warning: quota inodes were cleared. Quotas disabled.\n" -msgstr "Uwaga: i-węzły limitów (quot) były wyczyszczone. Limity wyłączone.\n" +msgid "bad allocation group number %s\n" +msgstr "błędny numer grupy alokacji %s\n" -#: .././repair/xfs_repair.c:790 -msgid "Warning: quota inodes would be cleared. Quotas would be disabled.\n" -msgstr "Uwaga: i-węzły limitów (quot) zostałyby wyczyszczone. Limity zostałyby wyłączone.\n" +#: .././db/agfl.c:37 +msgid "set address to agfl block" +msgstr "ustawienie adresu na blok agfl" -#: .././repair/xfs_repair.c:796 +#: .././db/agfl.c:79 msgid "" -"Warning: user quota information was cleared.\n" -"User quotas can not be enforced until limit information is recreated.\n" +"\n" +" set allocation group freelist\n" +"\n" +" Example:\n" +"\n" +" agfl 5\n" +" Located in the fourth sector of each allocation group,\n" +" the agfl freelist for internal btree space allocation is maintained\n" +" for each allocation group. This acts as a reserved pool of space\n" +" separate from the general filesystem freespace (not used for user data).\n" +"\n" msgstr "" -"Uwaga: informacje o limitach użytkowników były wyczyszczone.\n" -"Limity użytkowników nie mogą być wymuszone do czasu odtworzenia informacji.\n" +"\n" +" ustawienie listy wolnego miejsca grupy alokacji\n" +"\n" +" Przykład:\n" +"\n" +" agfl 5\n" +" Położona w 4. sektorze każdej grupy alokacji lista wolnego miejsca agfl\n" +" służąca do wewnętrznego przydzielania miejsca dla b-drzew jest utrzymywana\n" +" dla każdej grupy alokacji. Działa jako zarezerwowana pula miejsca oddzielona\n" +" od ogólnego wolnego miejsca w systemie plików (nie używana dla danych\n" +" użytkownika).\n" +"\n" -#: .././repair/xfs_repair.c:800 -msgid "" -"Warning: user quota information would be cleared.\n" -"User quotas could not be enforced until limit information was recreated.\n" -msgstr "" -"Uwaga: informacje o limitach użytkowników zostałyby wyczyszczone.\n" -"Limity użytkowników nie mogłyby być wymuszone do czasu odtworzenia informacji.\n" - -#: .././repair/xfs_repair.c:808 -msgid "" -"Warning: group quota information was cleared.\n" -"Group quotas can not be enforced until limit information is recreated.\n" -msgstr "" -"Uwaga: informacje o limitach grup były wyczyszczone.\n" -"Limity grup nie mogą być wymuszone do czasu odtworzenia informacji.\n" +#: .././db/agi.c:36 +msgid "set address to agi header" +msgstr "ustawienie adresu na nagłówek agi" -#: .././repair/xfs_repair.c:812 +#: .././db/agi.c:69 msgid "" -"Warning: group quota information would be cleared.\n" -"Group quotas could not be enforced until limit information was recreated.\n" +"\n" +" set allocation group inode btree\n" +"\n" +" Example:\n" +"\n" +" agi 3 (set location to 3rd allocation group inode btree and type to 'agi')\n" +"\n" +" Located in the 3rd 512 byte block of each allocation group,\n" +" the agi inode btree tracks all used/free inodes in the allocation group.\n" +" Inodes are allocated in 16k 'chunks', each btree entry tracks a 'chunk'.\n" +"\n" msgstr "" -"Uwaga: informacje o limitach grup zostałyby wyczyszczone.\n" -"Limity grup nie mogłyby być wymuszone do czasu odtworzenia informacji.\n" +"\n" +" ustawienie b-drzewa i-węzła grupy alokacji\n" +"\n" +" Przykład:\n" +"\n" +" agi 3 (ustawienie położenia na b-drzewo i-węzła 3. grupy alokacji i typu na 'agi')\n" +"\n" +" Położone w 3. 512-bajtowym bloku każdej grupy alokacji, b-drzewo i-węzła agi\n" +" śledzi wszystkie używane i wolne i-węzły w grupie alokacji.\n" +" I-węzły są przydzielane w 16k porcjach (chunk), każdy wpis b-drzewa śledzi\n" +" jedną.\n" +"\n" -#: .././repair/xfs_repair.c:820 -msgid "" -"Warning: project quota information was cleared.\n" -"Project quotas can not be enforced until limit information is recreated.\n" -msgstr "" -"Uwaga: informacje o limitach projektów były wyczyszczone.\n" -"Limity projektów nie mogą być wymuszone do czasu odtworzenia informacji.\n" +#: .././db/attr.c:556 +msgid "Unknown attribute buffer type!\n" +msgstr "Nieznany typ bufora atrybutów!\n" + +#: .././db/attr.c:568 +msgid "Writing unknown attribute buffer type!\n" +msgstr "Zapis nieznanego typu bufora atrybutów!\n" -#: .././repair/xfs_repair.c:824 -msgid "" -"Warning: project quota information would be cleared.\n" -"Project quotas could not be enforced until limit information was recreated.\n" -msgstr "" -"Uwaga: informacje o limitach projektów zostałyby wyczyszczone.\n" -"Limity projektów nie mogłyby być wymuszone do czasu odtworzenia informacji.\n" +#: .././db/attrset.c:38 +msgid "[-r|-s|-p|-u] [-n] [-R|-C] [-v n] name" +msgstr "[-r|-s|-p|-u] [-n] [-R|-C] [-v n] nazwa" -#: .././repair/xfs_repair.c:835 -msgid "No modify flag set, skipping filesystem flush and exiting.\n" -msgstr "Flaga braku modyfikacji ustawiona, pominięto zrzucanie systemu plików, zakończono.\n" +#: .././db/attrset.c:39 +msgid "set the named attribute on the current inode" +msgstr "ustawienie atrybutu o podanej nazwie w bieżącym i-węźle" -#: .././repair/xfs_repair.c:849 .././repair/phase5.c:1360 -msgid "couldn't get superblock\n" -msgstr "nie udało się pobrać superbloku\n" +#: .././db/attrset.c:42 +msgid "[-r|-s|-p|-u] [-n] name" +msgstr "[-r|-s|-p|-u] [-n] nazwa" -#: .././repair/xfs_repair.c:854 -msgid "Note - quota info will be regenerated on next quota mount.\n" -msgstr "Uwaga - informacje o limitach zostaną ponownie wygenerowane przy następnym montowaniu.\n" +#: .././db/attrset.c:43 +msgid "remove the named attribute from the current inode" +msgstr "usunięcie atrybutu o podanej nazwie z bieżącego i-węzła" -#: .././repair/xfs_repair.c:862 -#, c-format +#: .././db/attrset.c:49 msgid "" -"Note - stripe unit (%d) and width (%d) fields have been reset.\n" -"Please set with mount -o sunit=,swidth=\n" +"\n" +" The 'attr_set' and 'attr_remove' commands provide interfaces for debugging\n" +" the extended attribute allocation and removal code.\n" +" Both commands require an attribute name to be specified, and the attr_set\n" +" command allows an optional value length (-v) to be provided as well.\n" +" There are 4 namespace flags:\n" +" -r -- 'root'\n" +" -u -- 'user'\t\t(default)\n" +" -s -- 'secure'\n" +"\n" +" For attr_set, these options further define the type of set operation:\n" +" -C -- 'create' - create attribute, fail if it already exists\n" +" -R -- 'replace' - replace attribute, fail if it does not exist\n" +" The backward compatibility mode 'noattr2' can be emulated (-n) also.\n" +"\n" msgstr "" -"Uwaga - pola jednostki pasa (%d) i szerokości pasa (%d) zostały przestawione.\n" -"Proszę ustawić przy użyciu mount -o sunit=,swidth=\n" - -#: .././repair/xfs_repair.c:885 -msgid "done\n" -msgstr "gotowe\n" +"\n" +" Polecenia 'attr_set' i 'attr_remove' udostępniają interfejsy do diagnostyki\n" +" kodu przydzielania i usuwania rozszerzonych atrybutów.\n" +" Oba polecenia wymagają podania nazwy atrybutu, a polecenie attr_set\n" +" pozwala dodatkowo podać opcjonalną długość wartości (-v).\n" +" Są 4 flagi przestrzeni nazw:\n" +" -r - 'root'\n" +" -u - 'user' (domyślna)\n" +" -s - 'secure'\n" +"\n" +" Dla attr_set poniższe opcje określają rodzaj operacji ustawiania:\n" +" -C - 'create' - utworzenie atrybutu; nie powiedzie się, jeśli już istnieje\n" +" -R - 'replace' - zastąpienie atrybutu; nie powiedzie się, jeśli nie istnieje\n" +" Możliwa jest także emulacja trybu kompatybilności wstecznej 'noattr2' (-n).\n" +"\n" -#: .././repair/avl64.c:1032 .././repair/avl.c:1011 -#, c-format -msgid "avl_insert: Warning! duplicate range [%llu,%llu]\n" -msgstr "avl_insert: Uwaga! powtórzony przedział [%llu,%llu]\n" +#: .././db/attrset.c:90 .././db/attrset.c:193 +msgid "current type is not inode\n" +msgstr "bieżący typ nie jest i-węzłem\n" -#: .././repair/avl64.c:1227 .././repair/avl.c:1206 +#: .././db/attrset.c:125 #, c-format -msgid "Command [fpdir] : " -msgstr "Polecenie [fpdir] : " +msgid "bad attr_set valuelen %s\n" +msgstr "błędna długość wartości %s dla attr_set\n" -#: .././repair/avl64.c:1236 .././repair/avl.c:1215 -#, c-format -msgid "end of range ? " -msgstr "koniec przedziału? " +#: .././db/attrset.c:131 +msgid "bad option for attr_set command\n" +msgstr "błędna opcja dla polecenia attr_set\n" -#: .././repair/avl64.c:1247 .././repair/avl.c:1226 -#, c-format -msgid "Cannot find %d\n" -msgstr "Nie można odnaleźć %d\n" +#: .././db/attrset.c:137 +msgid "too few options for attr_set (no name given)\n" +msgstr "za mało opcji dla attr_set (nie podano nazwy)\n" -#: .././repair/avl64.c:1260 .././repair/avl.c:1239 +#: .././db/attrset.c:146 #, c-format -msgid "size of range ? " -msgstr "rozmiar przedziału? " +msgid "cannot allocate buffer (%d)\n" +msgstr "nie udało się przydzielić bufora (%d)\n" -#: .././repair/avl64.c:1271 .././repair/avl.c:1250 +#: .././db/attrset.c:155 .././db/attrset.c:230 #, c-format -msgid "End of range ? " -msgstr "Koniec przedziału? " +msgid "failed to iget inode %llu\n" +msgstr "operacja iget na i-węźle %llu nie powiodła się\n" -#: .././repair/avl64.c:1275 .././repair/avl.c:1254 +#: .././db/attrset.c:162 #, c-format -msgid "checklen 0/1 ? " -msgstr "checklen 0/1 ? " +msgid "failed to set attr %s on inode %llu\n" +msgstr "ustawianie atrybutu %s w i-węźle %llu nie powiodło się\n" -#: .././repair/avl64.c:1282 .././repair/avl.c:1261 -#, c-format -msgid "Found something\n" -msgstr "Znaleziono coś\n" +#: .././db/attrset.c:217 +msgid "bad option for attr_remove command\n" +msgstr "błędna opcja dla polecenia attr_remove\n" -#: .././repair/phase7.c:43 -#, c-format -msgid "resetting inode % nlinks from %u to %u\n" -msgstr "przestawiono nlinks i-węzła % z %u na %u\n" +#: .././db/attrset.c:223 +msgid "too few options for attr_remove (no name given)\n" +msgstr "za mało opcji dla attr_remove (nie podano nazwy)\n" -#: .././repair/phase7.c:49 +#: .././db/attrset.c:236 #, c-format -msgid "nlinks %u will overflow v1 ino, ino % will be converted to version 2\n" -msgstr "nlinks %u przepełni i-węzeł v1, i-węzeł % będzie skonwertowany do wersji 2\n" +msgid "failed to remove attr %s from inode %llu\n" +msgstr "usunięcie atrybutu %s z i-węzła %llu nie powiodło się\n" -#: .././repair/phase7.c:56 -#, c-format -msgid "would have reset inode % nlinks from %u to %u\n" -msgstr "nlinks i-węzła % zostałoby przestawione z %u na %u\n" +#: .././db/block.c:43 .././db/block.c:49 +msgid "filoff" +msgstr "filoff" -#: .././repair/phase7.c:85 .././repair/phase6.c:3267 .././repair/phase6.c:3271 -#, c-format -msgid "couldn't map inode %, err = %d\n" -msgstr "nie udało się odwzorować i-węzła %, błąd = %d\n" +#: .././db/block.c:44 +msgid "set address to file offset (attr fork)" +msgstr "ustawienie adresu na offset w pliku (gałąź atrybutów)" -#: .././repair/phase7.c:89 -#, c-format -msgid "couldn't map inode %, err = %d, can't compare link counts\n" -msgstr "nie udało się odwzorować i-węzła %, błąd %d, nie można porównać liczby dowiązań\n" +#: .././db/block.c:46 +msgid "[d]" +msgstr "[d]" -#: .././repair/phase7.c:128 -msgid "Phase 7 - verify and correct link counts...\n" -msgstr "Faza 7 - sprawdzanie i poprawianie liczby dowiązań...\n" +#: .././db/block.c:47 +msgid "set address to daddr value" +msgstr "ustawienie adresu na wartość daddr" -#: .././repair/phase7.c:130 -msgid "Phase 7 - verify link counts...\n" -msgstr "Faza 7 - sprawdzanie liczby dowiązań...\n" +#: .././db/block.c:50 +msgid "set address to file offset (data fork)" +msgstr "ustawienie adresu na offset w pliku (gałąź danych)" -#: .././repair/threads.c:90 -#, c-format -msgid "cannot create worker threads, error = [%d] %s\n" -msgstr "nie można utworzyć wątków pracujących, błąd: [%d] %s\n" +#: .././db/block.c:52 +msgid "[fsb]" +msgstr "[fsb]" -#: .././repair/threads.c:108 -#, c-format -msgid "cannot allocate worker item, error = [%d] %s\n" -msgstr "nie można przydzielić elementu pracującego, błąd: [%d] %s\n" +#: .././db/block.c:53 +msgid "set address to fsblock value" +msgstr "ustawienie adresu na wartość fsblock" -#: .././repair/prefetch.c:465 -msgid "prefetch corruption\n" -msgstr "uszkodzenie prefetch\n" +#: .././db/block.c:59 +msgid "" +"\n" +" Example:\n" +"\n" +" 'ablock 23' - sets the file position to the 23rd filesystem block in\n" +" the inode's attribute fork. The filesystem block size is specified in\n" +" the superblock.\n" +"\n" +msgstr "" +"\n" +" Przykład:\n" +"\n" +" 'ablock 23' ustawia pozycję w pliku na 23. blok systemu plików w gałęzi\n" +" atrybutów i-węzła. Rozmiar bloku systemu plików jest określony w superbloku.\n" +"\n" -#: .././repair/prefetch.c:611 .././repair/prefetch.c:711 +#: .././db/block.c:82 .././db/block.c:177 #, c-format -msgid "failed to create prefetch thread: %s\n" -msgstr "nie udało się utworzyć wątku prefetch: %s\n" - -#: .././repair/prefetch.c:748 -msgid "failed to initialize prefetch mutex\n" -msgstr "nie udało się zainicjować muteksu prefetch\n" - -#: .././repair/prefetch.c:750 .././repair/prefetch.c:752 -msgid "failed to initialize prefetch cond var\n" -msgstr "nie udało się zainicjować zmiennej warunkowej prefetch\n" +msgid "bad block number %s\n" +msgstr "błędny numer bloku %s\n" -#: .././repair/phase5.c:211 -msgid "could not set up btree block array\n" -msgstr "nie udało się utworzyć tablicy bloków b-drzewa\n" +#: .././db/block.c:90 +msgid "no attribute data for file\n" +msgstr "brak danych atrybutów dla pliku\n" -#: .././repair/phase5.c:223 -msgid "error - not enough free space in filesystem\n" -msgstr "błąd - za mało wolnego miejsca w systemie plików\n" +#: .././db/block.c:96 +msgid "file attr block is unmapped\n" +msgstr "blok atrybutów pliku nie ma odwzorowania\n" -#: .././repair/phase5.c:438 -#, c-format -msgid "can't rebuild fs trees -- not enough free space on ag %u\n" -msgstr "nie można przebudować drzew systemu plików - za mało wolnego miejsca w ag %u\n" +#: .././db/block.c:119 +msgid "" +"\n" +" Example:\n" +"\n" +" 'daddr 102' - sets position to the 102nd absolute disk block\n" +" (512 byte block).\n" +msgstr "" +"\n" +" Przykład:\n" +"\n" +" 'daddr 102' ustawia pozycję na 102. (bezwzględnie) blok dysku\n" +" (blok 512-bajtowy).\n" -#: .././repair/phase5.c:462 +#: .././db/block.c:135 #, c-format -msgid "ag %u - not enough free space to build freespace btrees\n" -msgstr "ag %u - za mało wolnego miejsca na przebudowanie b-drzew wolnego miejsca\n" +msgid "current daddr is %lld\n" +msgstr "bieżący daddr to %lld\n" -#: .././repair/phase5.c:497 +#: .././db/block.c:141 #, c-format -msgid "not enough free blocks left to describe all free blocks in AG %u\n" -msgstr "za mało wolnych bloków na opisanie wszystkich wolnych bloków w AG %u\n" +msgid "bad daddr %s\n" +msgstr "błędny daddr %s\n" -#: .././repair/phase5.c:1310 -#, c-format -msgid "lost %d blocks in ag %u\n" -msgstr "utracono %d bloków w ag %u\n" +#: .././db/block.c:153 +msgid "" +"\n" +" Example:\n" +"\n" +" 'dblock 23' - sets the file position to the 23rd filesystem block in\n" +" the inode's data fork. The filesystem block size is specified in the\n" +" superblock.\n" +"\n" +msgstr "" +"\n" +" Przykład:\n" +"\n" +" 'dblock 23' ustawia pozycję w pliku na 23. blok systemu plików w gałęzi\n" +" danych i-węzła. Rozmiar bloku systemu plików jest określony w superbloku.\n" +"\n" + +#: .././db/block.c:185 +msgid "no type for file data\n" +msgstr "brak typu dla danych pliku\n" + +#: .././db/block.c:192 +msgid "file data block is unmapped\n" +msgstr "blok danych plików nie ma odwzorowania\n" + +#: .././db/block.c:210 +msgid "" +"\n" +" Example:\n" +"\n" +" 'fsblock 1023' - sets the file position to the 1023rd filesystem block.\n" +" The filesystem block size is specified in the superblock and set during\n" +" mkfs time. Offset is absolute (not AG relative).\n" +"\n" +msgstr "" +"\n" +" Przykład:\n" +"\n" +" 'fsblock 1023' ustawia pozycję w pliku na 1023. blok systemu plików.\n" +" Rozmiar bloku systemu plików jest określony w superbloku i ustawiany w\n" +" trakcie wykonywania mkfs. Offset jest bezwzględny (nie względem AG).\n" +"\n" -#: .././repair/phase5.c:1313 +#: .././db/block.c:229 #, c-format -msgid "thought we were going to lose %d blocks in ag %u, actually lost %d\n" -msgstr "przewidywano utracenie %d bloków w ag %u, a utracono %d\n" +msgid "current fsblock is %lld\n" +msgstr "bieżący fsblock to %lld\n" -#: .././repair/phase5.c:1409 .././repair/phase3.c:76 .././repair/phase4.c:125 -#: .././repair/phase6.c:3624 +#: .././db/block.c:235 .././db/block.c:241 #, c-format -msgid " - agno = %d\n" -msgstr " - agno = %d\n" +msgid "bad fsblock %s\n" +msgstr "błędny fsblock %s\n" + +#: .././db/bmap.c:39 +msgid "[-ad] [block [len]]" +msgstr "[-ad] [blok [długość]]" + +#: .././db/bmap.c:40 +msgid "show block map for current file" +msgstr "pokazanie mapy bloków dla bieżącego pliku" + +#: .././db/bmap.c:152 .././db/inode.c:417 +msgid "no current inode\n" +msgstr "brak bieżącego i-węzła\n" + +#: .././db/bmap.c:165 +msgid "bad option for bmap command\n" +msgstr "błędna opcja dla polecenia bmap\n" -#: .././repair/phase5.c:1432 +#: .././db/bmap.c:182 #, c-format -msgid "unable to rebuild AG %u. Not enough free space in on-disk AG.\n" -msgstr "nie udało się przebudować AG %u. Za mało wolnego miejsca w AG na dysku.\n" +msgid "bad block number for bmap %s\n" +msgstr "błędny numer bloku dla bmap %s\n" -#: .././repair/phase5.c:1467 +#: .././db/bmap.c:190 #, c-format -msgid "unable to rebuild AG %u. No free space.\n" -msgstr "nie udało się przebudować AG %u. Brak wolnego miejsca.\n" +msgid "bad len for bmap %s\n" +msgstr "błędna długość dla bmap %s\n" -#: .././repair/phase5.c:1494 +#: .././db/bmap.c:213 #, c-format -msgid "lost %d blocks in agno %d, sorry.\n" -msgstr "niestety utracono %d bloków w agno %d.\n" +msgid "%s offset %lld startblock %llu (%u/%u) count %llu flag %u\n" +msgstr "%s oofset %lld blok-pocz %llu (%u/%u) liczba %llu flaga %u\n" -#: .././repair/phase5.c:1563 -msgid "Phase 5 - rebuild AG headers and trees...\n" -msgstr "Faza 5 - przebudowywanie nagłówków i drzew AG...\n" +#: .././db/bmap.c:215 .././db/check.c:2136 .././db/check.c:2148 +#: .././db/check.c:2175 .././repair/dinode.c:50 +msgid "data" +msgstr "danych" -#: .././repair/phase5.c:1593 -msgid "cannot alloc sb_icount_ag buffers\n" -msgstr "nie można przydzielić buforów sb_icount_ag\n" +#: .././db/bmap.c:215 .././db/check.c:2136 .././db/check.c:2148 +#: .././db/check.c:2175 .././repair/dinode.c:51 +msgid "attr" +msgstr "atrybutów" -#: .././repair/phase5.c:1597 -msgid "cannot alloc sb_ifree_ag buffers\n" -msgstr "nie można przydzielić buforów sb_ifree_ag\n" +#: .././db/check.c:362 +msgid "free block usage information" +msgstr "informacje o wykorzystaniu wolnych bloków" -#: .././repair/phase5.c:1601 -msgid "cannot alloc sb_fdblocks_ag buffers\n" -msgstr "nie można przydzielić buforów sb_fdblocks_ag\n" +#: .././db/check.c:365 +msgid "[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..." +msgstr "[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..." -#: .././repair/phase5.c:1620 -msgid " - generate realtime summary info and bitmap...\n" -msgstr " - generowanie opisu i bitmapy realtime...\n" +#: .././db/check.c:366 +msgid "get block usage and check consistency" +msgstr "uzyskanie informacji o wykorzystaniu bloków i sprawdzenie spójności" -#: .././repair/phase5.c:1625 -msgid " - reset superblock...\n" -msgstr " - przestawianie superbloku...\n" +#: .././db/check.c:369 +msgid "[-n count] [-x minlen] [-y maxlen] [-s seed] [-0123] [-t type] ..." +msgstr "[-n liczba] [-x minlen] [-y maxlen] [-s seed] [-0123] [-t typ] ..." + +#: .././db/check.c:370 +msgid "trash randomly selected block(s)" +msgstr "zaśmiecenie losowo wybranych bloków" + +#: .././db/check.c:373 +msgid "[-n] [-c blockcount]" +msgstr "[-n] [-c liczba-bloków]" + +#: .././db/check.c:374 +msgid "print usage for current block(s)" +msgstr "wypisanie wykorzystania bieżących bloków" + +#: .././db/check.c:377 +msgid "[-s] [-i ino] ..." +msgstr "[-s] [-i ino] ..." + +#: .././db/check.c:378 +msgid "print inode-name pairs" +msgstr "wypisanie par i-węzeł - nazwa" -#: .././repair/agheader.c:35 +#: .././db/check.c:398 #, c-format -msgid "bad magic # 0x%x for agf %d\n" -msgstr "błędna liczba magiczna 0x%x dla agf %d\n" +msgid "-i %lld bad inode number\n" +msgstr "-i %lld - błędny numer i-węzła\n" -#: .././repair/agheader.c:44 +#: .././db/check.c:410 #, c-format -msgid "bad version # %d for agf %d\n" -msgstr "błędny numer wersji %d dla agf %d\n" +msgid "inode %lld add link, now %u\n" +msgstr "i-węzeł %lld - dodano dowiązanie, teraz %u\n" -#: .././repair/agheader.c:53 +#: .././db/check.c:437 #, c-format -msgid "bad sequence # %d for agf %d\n" -msgstr "błędny numer sekwencji %d dla agf %d\n" +msgid "inode %lld parent %lld\n" +msgstr "i-węzeł %lld - rodzic %lld\n" + +#: .././db/check.c:750 +msgid "block usage information not allocated\n" +msgstr "informacja o wykorzystaniu bloków nie przydzielona\n" + +#: .././db/check.c:788 +msgid "already have block usage information\n" +msgstr "już istnieje informacja o wykorzystaniu bloków\n" + +#: .././db/check.c:818 .././db/check.c:926 +msgid "WARNING: this may be a newer XFS filesystem.\n" +msgstr "UWAGA: to może być nowszy system plików XFS.\n" -#: .././repair/agheader.c:63 +#: .././db/check.c:854 #, c-format -msgid "bad length %d for agf %d, should be %d\n" -msgstr "błędna długość %d dla agf %d, powinno być %d\n" +msgid "sb_icount %lld, counted %lld\n" +msgstr "sb_icount %lld, naliczono %lld\n" -#: .././repair/agheader.c:76 +#: .././db/check.c:860 #, c-format -msgid "bad length %d for agf %d, should be %\n" -msgstr "błędna długość %d dla agf %d, powinno być %\n" +msgid "sb_ifree %lld, counted %lld\n" +msgstr "sb_ifree %lld, naliczono %lld\n" -#: .././repair/agheader.c:90 +#: .././db/check.c:866 #, c-format -msgid "flfirst %d in agf %d too large (max = %zu)\n" -msgstr "flfirst %d w agf %d zbyt duże (maksimum = %zu)\n" +msgid "sb_fdblocks %lld, counted %lld\n" +msgstr "sb_fdblocks %lld, naliczono %lld\n" -#: .././repair/agheader.c:98 +#: .././db/check.c:872 #, c-format -msgid "fllast %d in agf %d too large (max = %zu)\n" -msgstr "fllast %d w agf %d zbyt duże (maksimum = %zu)\n" +msgid "sb_fdblocks %lld, aggregate AGF count %lld\n" +msgstr "sb_fdblocks %lld, łączny licznik AGF %lld\n" -#: .././repair/agheader.c:120 +#: .././db/check.c:878 #, c-format -msgid "bad magic # 0x%x for agi %d\n" -msgstr "błędna liczba magiczna 0x%x dla agi %d\n" +msgid "sb_frextents %lld, counted %lld\n" +msgstr "sb_frextents %lld, naliczono %lld\n" -#: .././repair/agheader.c:129 +#: .././db/check.c:885 #, c-format -msgid "bad version # %d for agi %d\n" -msgstr "błędny numer wersji %d dla agi %d\n" +msgid "sb_features2 (0x%x) not same as sb_bad_features2 (0x%x)\n" +msgstr "sb_features2 (0x%x) różni się od sb_bad_features2 (0x%x)\n" -#: .././repair/agheader.c:138 +#: .././db/check.c:894 #, c-format -msgid "bad sequence # %d for agi %d\n" -msgstr "błędny numer sekwencji %d dla agi %d\n" +msgid "sb versionnum missing attr bit %x\n" +msgstr "sb versionnum - brak bitu atrybutu %x\n" -#: .././repair/agheader.c:148 +#: .././db/check.c:901 #, c-format -msgid "bad length # %d for agi %d, should be %d\n" -msgstr "błędna długość %d dla agi %d, powinno być %d\n" +msgid "sb versionnum missing nlink bit %x\n" +msgstr "sb versionnum - brak bitu nlink %x\n" -#: .././repair/agheader.c:161 +#: .././db/check.c:908 #, c-format -msgid "bad length # %d for agi %d, should be %\n" -msgstr "błędna długość %d dla agi %d, powinno być %\n" +msgid "sb versionnum missing quota bit %x\n" +msgstr "sb versionnum - brak bitu quota %x\n" -#: .././repair/agheader.c:271 +#: .././db/check.c:915 #, c-format -msgid "zeroing unused portion of %s superblock (AG #%u)\n" -msgstr "zerowanie nieużywanej części superbloku %s (AG #%u)\n" +msgid "sb versionnum extra align bit %x\n" +msgstr "sb versionnum - nadmiarowy bit align %x\n" -#: .././repair/agheader.c:272 .././repair/agheader.c:278 -msgid "primary" -msgstr "głównego" +#: .././db/check.c:955 +msgid "zeroed" +msgstr "wyzerowano" -#: .././repair/agheader.c:272 .././repair/agheader.c:278 -msgid "secondary" -msgstr "zapasowego" +#: .././db/check.c:955 +msgid "set" +msgstr "ustawiono" -#: .././repair/agheader.c:277 -#, c-format -msgid "would zero unused portion of %s superblock (AG #%u)\n" -msgstr "nieużywana część superbloku %s (AG #%u) zostałaby wyzerowana\n" +#: .././db/check.c:955 +msgid "flipped" +msgstr "przełączono" -#: .././repair/agheader.c:296 -#, c-format -msgid "bad flags field in superblock %d\n" -msgstr "błędne pole flag w superbloku %d\n" +#: .././db/check.c:955 +msgid "randomized" +msgstr "ulosowiono" -#: .././repair/agheader.c:313 +#: .././db/check.c:965 #, c-format -msgid "non-null user quota inode field in superblock %d\n" -msgstr "niezerowe pole i-węzła limitów użytkowników w superbloku %d\n" +msgid "can't read block %u/%u for trashing\n" +msgstr "nie można odczytać bloku %u/%u w celu zaśmiecenia\n" -#: .././repair/agheader.c:326 +#: .././db/check.c:995 #, c-format -msgid "non-null group quota inode field in superblock %d\n" -msgstr "niezerowe pole i-węzła limitów grup w superbloku %d\n" +msgid "blocktrash: %u/%u %s block %d bit%s starting %d:%d %s\n" +msgstr "blocktrash: %u/%u %s blok %d bit%s początek %d:%d %s\n" -#: .././repair/agheader.c:338 -#, c-format -msgid "non-null quota flags in superblock %d\n" -msgstr "niezerowe flagi limitów w superbloku %d\n" +#: .././db/check.c:1027 .././db/check.c:1185 +msgid "must run blockget first\n" +msgstr "najpierw trzeba wykonać blockget\n" -#: .././repair/agheader.c:356 +#: .././db/check.c:1071 #, c-format -msgid "bad shared version number in superblock %d\n" -msgstr "błędny numer wersji dzielonej w superbloku %d\n" +msgid "bad blocktrash count %s\n" +msgstr "błędna liczba bloków do zaśmiecenia %s\n" -#: .././repair/agheader.c:368 +#: .././db/check.c:1085 #, c-format -msgid "bad inode alignment field in superblock %d\n" -msgstr "błędne pole wyrównania i-węzłów w superbloku %d\n" +msgid "bad blocktrash type %s\n" +msgstr "błędny typ zaśmiecania %s\n" -#: .././repair/agheader.c:381 +#: .././db/check.c:1094 #, c-format -msgid "bad stripe unit/width fields in superblock %d\n" -msgstr "błędne pola jednostki/szerokości pasa w superbloku %d\n" +msgid "bad blocktrash min %s\n" +msgstr "błędny początek zaśmiecania %s\n" -#: .././repair/agheader.c:399 +#: .././db/check.c:1102 #, c-format -msgid "bad log/data device sector size fields in superblock %d\n" -msgstr "błędne pola rozmiaru sektora urządzenia logu/danych w superbloku %d\n" +msgid "bad blocktrash max %s\n" +msgstr "błędny koniec zaśmiecania %s\n" -#: .././repair/agheader.c:430 -#, c-format -msgid "bad on-disk superblock %d - %s\n" -msgstr "błędny superblok %d na dysku - %s\n" +#: .././db/check.c:1107 +msgid "bad option for blocktrash command\n" +msgstr "błędna opcja polecenia blocktrash\n" -#: .././repair/agheader.c:437 -#, c-format -msgid "primary/secondary superblock %d conflict - %s\n" -msgstr "konflikt głównego/zapasowego superbloku %d - %s\n" +#: .././db/check.c:1112 +msgid "bad min/max for blocktrash command\n" +msgstr "błędny początek/koniec polecenia blocktrash\n" -#: .././repair/versions.c:73 -#, c-format -msgid "bogus quota flags 0x%x set in superblock" -msgstr "niepoprawne flagi limitów 0x%x ustawione w superbloku" +#: .././db/check.c:1138 +msgid "blocktrash: no matching blocks\n" +msgstr "blocktrash: brak pasujących bloków\n" -#: .././repair/versions.c:86 -msgid ", bogus flags will be cleared\n" -msgstr ", błędne flagi zostaną wyczyszczone\n" +#: .././db/check.c:1142 +#, c-format +msgid "blocktrash: seed %u\n" +msgstr "blocktash: zarodek %u\n" -#: .././repair/versions.c:88 -msgid ", bogus flags would be cleared\n" -msgstr ", błędne flagi zostałyby wyczyszczone\n" +#: .././db/check.c:1200 +#, c-format +msgid "bad blockuse count %s\n" +msgstr "błędna liczba bloków dla blockuse: %s\n" -#: .././repair/versions.c:141 -msgid "This filesystem has uninitialized extent flags.\n" -msgstr "Ten system plików ma niezainicjowane flagi ekstentów.\n" +#: .././db/check.c:1206 .././db/check.c:1892 +msgid "must run blockget -n first\n" +msgstr "najpierw trzeba wykonać blockget -n\n" -#: .././repair/versions.c:149 -msgid "This filesystem is marked shared.\n" -msgstr "Ten system plików jest oznaczony jako współdzielony.\n" +#: .././db/check.c:1212 +msgid "bad option for blockuse command\n" +msgstr "błędna opcja dla polecenia blockuse\n" -#: .././repair/versions.c:155 -msgid "" -"This filesystem uses feature(s) not yet supported in this release.\n" -"Please run a more recent version of xfs_repair.\n" -msgstr "" -"Ten system plików używa możliwości jeszcze nie obsługiwanych w tym wydaniu.\n" -"Proszę uruchomić nowszą wersję xfs_repair.\n" +#: .././db/check.c:1219 +#, c-format +msgid "block %llu (%u/%u) type %s" +msgstr "blok %llu (%u/%u) typu %s" -#: .././repair/versions.c:161 +#: .././db/check.c:1223 #, c-format -msgid "WARNING: unknown superblock version %d\n" -msgstr "UWAGA: nieznana wersja superbloku %d\n" +msgid " inode %lld" +msgstr " i-węzeł %lld" -#: .././repair/versions.c:164 -msgid "This filesystem contains features not understood by this program.\n" -msgstr "Ten system plików zawiera cechę nie rozumianą przez ten program.\n" +#: .././db/check.c:1261 +#, c-format +msgid "block %u/%u expected type %s got %s\n" +msgstr "blok %u/%u: oczekiwano typu %s, otrzymano %s\n" -#: .././repair/versions.c:172 -msgid "" -"WARNING: you have disallowed superblock-feature-bits-allowed\n" -"\tbut this superblock has feature bits. The superblock\n" -"\twill be downgraded. This may cause loss of filesystem meta-data\n" -msgstr "" -"UWAGA: zabroniono superblock-feature-bits-allowed, ale ten\n" -"\tsuperblok ma ustawione bity cech. Superblok zostanie zdegradowany.\n" -"\tMoże to spowodować utratę metadanych systemu plików.\n" +#: .././db/check.c:1293 +#, c-format +msgid "blocks %u/%u..%u claimed by inode %lld\n" +msgstr "blok %u/%u..%u przypisany do i-węzła %lld\n" -#: .././repair/versions.c:177 -msgid "" -"WARNING: you have disallowed superblock-feature-bits-allowed\n" -"\tbut this superblock has feature bits. The superblock\n" -"\twould be downgraded. This might cause loss of filesystem\n" -"\tmeta-data.\n" -msgstr "" -"UWAGA: zabroniono superblock-feature-bits-allowed, ale ten\n" -"\tsuperblok ma ustawione bity cech. Superblok zostałby zdegradowany.\n" -"\tMogłoby to spowodować utratę metadanych systemu plików.\n" +#: .././db/check.c:1301 +#, c-format +msgid "block %u/%u claimed by inode %lld, previous inum %lld\n" +msgstr "blok %u/%u przypisany do i-węzła %lld, poprzedni inum %lld\n" -#: .././repair/versions.c:191 -msgid "" -"WARNING: you have disallowed attributes but this filesystem\n" -"\thas attributes. The filesystem will be downgraded and\n" -"\tall attributes will be removed.\n" -msgstr "" -"UWAGA: zabroniono używania atrybutów, ale ten system plików zawiera\n" -"\tatrybuty. System plików zostanie zdegradowany, a wszystkie\n" -"\tatrybuty usunięte.\n" +#: .././db/check.c:1330 +#, c-format +msgid "link count mismatch for inode %lld (name %s), nlink %d, counted %d\n" +msgstr "niezgodność liczby dowiązań dla i-węzła %lld (nazwa %s), nlink %d, naliczono %d\n" -#: .././repair/versions.c:196 -msgid "" -"WARNING: you have disallowed attributes but this filesystem\n" -"\thas attributes. The filesystem would be downgraded and\n" -"\tall attributes would be removed.\n" -msgstr "" -"UWAGA: zabroniono używania atrybutów, ale ten system plików zawiera\n" -"\tatrybuty. System plików zostałby zdegradowany, a wszystkie\n" -"\tatrybuty usunięte.\n" +#: .././db/check.c:1338 +#, c-format +msgid "disconnected inode %lld, nlink %d\n" +msgstr "odłączony i-węzeł %lld, nlink %d\n" -#: .././repair/versions.c:209 -msgid "" -"WARNING: you have disallowed attr2 attributes but this filesystem\n" -"\thas attributes. The filesystem will be downgraded and\n" -"\tall attr2 attributes will be removed.\n" -msgstr "" -"UWAGA: zabroniono używania atrybutów attr2, ale ten system plików\n" -"\tzawiera atrybuty. System plików zostanie zdegradowany, a wszystkie\n" -"\tatrybuty attr2 usunięte.\n" +#: .././db/check.c:1342 +#, c-format +msgid "allocated inode %lld has 0 link count\n" +msgstr "przydzielony i-węzeł %lld ma zerową liczbę dowiązań\n" -#: .././repair/versions.c:214 -msgid "" -"WARNING: you have disallowed attr2 attributes but this filesystem\n" -"\thas attributes. The filesystem would be downgraded and\n" -"\tall attr2 attributes would be removed.\n" -msgstr "" -"UWAGA: zabroniono używania atrybutów attr2, ale ten system plików\n" -"\tzawiera atrybuty. System plików zostałby zdegradowany, a wszystkie\n" -"\tatrybuty attr2 usunięte.\n" +#: .././db/check.c:1352 +#, c-format +msgid "inode %lld name %s\n" +msgstr "i-węzeł %lld o nazwie %s\n" -#: .././repair/versions.c:227 -msgid "" -"WARNING: you have disallowed version 2 inodes but this filesystem\n" -"\thas version 2 inodes. The filesystem will be downgraded and\n" -"\tall version 2 inodes will be converted to version 1 inodes.\n" -"\tThis may cause some hard links to files to be destroyed\n" -msgstr "" -"UWAGA: zabroniono używania i-węzłów w wersji 2, ale ten system plików\n" -"\tzawiera i-węzły w wersji 2. System plików zostanie zdegradowany,\n" -"\ta wszystkie i-węzły w wersji 2 zostaną przekonwertowane do wersji 1.\n" -"\tMoże to spowodować zniszczenie niektórych twardych dowiązań do\n" -"\tplików.\n" +#: .././db/check.c:1386 .././db/check.c:1401 +#, c-format +msgid "block %u/%u out of range\n" +msgstr "blok %u/%u poza zakresem\n" -#: .././repair/versions.c:233 -msgid "" -"WARNING: you have disallowed version 2 inodes but this filesystem\n" -"\thas version 2 inodes. The filesystem would be downgraded and\n" -"\tall version 2 inodes would be converted to version 1 inodes.\n" -"\tThis might cause some hard links to files to be destroyed\n" -msgstr "" -"UWAGA: zabroniono używania i-węzłów w wersji 2, ale ten system plików\n" -"\tzawiera i-węzły w wersji 2. System plików zostałby zdegradowany,\n" -"\ta wszystkie i-węzły w wersji 2 zostałyby przekonwertowane do\n" -"\twersji 1. Mogłoby to spowodować zniszczenie niektórych twardych\n" -"\tdowiązań do plików.\n" +#: .././db/check.c:1389 .././db/check.c:1404 +#, c-format +msgid "blocks %u/%u..%u out of range\n" +msgstr "bloki %u/%u..%u poza zakresem\n" -#: .././repair/versions.c:247 -msgid "" -"WARNING: you have disallowed quotas but this filesystem\n" -"\thas quotas. The filesystem will be downgraded and\n" -"\tall quota information will be removed.\n" -msgstr "" -"UWAGA: zabroniono używania limitów (quot), ale ten system plików\n" -"\tzawiera limity. System plików zostanie zdegradowany, a wszystkie\n" -"\tinformacje o limitach usunięte.\n" +#: .././db/check.c:1427 +#, c-format +msgid "rtblock %llu expected type %s got %s\n" +msgstr "rtblok %llu - oczekiwano typu %s, otrzymano %s\n" -#: .././repair/versions.c:252 -msgid "" -"WARNING: you have disallowed quotas but this filesystem\n" -"\thas quotas. The filesystem would be downgraded and\n" -"\tall quota information would be removed.\n" -msgstr "" -"UWAGA: zabroniono używania limitów (quot), ale ten system plików\n" -"\tzawiera limity. System plików zostałby zdegradowany, a wszystkie\n" -"\tinformacje o limitach usunięte.\n" +#: .././db/check.c:1447 +#, c-format +msgid "rtblocks %llu..%llu claimed by inode %lld\n" +msgstr "rtbloki %llu..%llu przypisane do i-węzła %lld\n" -#: .././repair/versions.c:276 -msgid "" -"WARNING: you have disallowed aligned inodes but this filesystem\n" -"\thas aligned inodes. The filesystem will be downgraded.\n" -"\tThis will permanently degrade the performance of this filesystem.\n" -msgstr "" -"UWAGA: zabroniono używania wyrównanych i-węzłów, ale ten system plików\n" -"\tzawiera wyrównane i-węzły. System plików zostanie zdegradowany.\n" -"\tTrwale zdegraduje to wydajność tego systemu plików.\n" +#: .././db/check.c:1456 +#, c-format +msgid "rtblock %llu claimed by inode %lld, previous inum %lld\n" +msgstr "rtblok %llu przypisany do i-węzłą %lld, poprzedni inum %lld\n" -#: .././repair/versions.c:281 -msgid "" -"WARNING: you have disallowed aligned inodes but this filesystem\n" -"\thas aligned inodes. The filesystem would be downgraded.\n" -"\tThis would permanently degrade the performance of this filesystem.\n" -msgstr "" -"UWAGA: zabroniono używania wyrównanych i-węzłów, ale ten system plików\n" -"\tzawiera wyrównane i-węzły. System plików zostałby zdegradowany.\n" -"\tTrwale zdegradowałoby to wydajność tego systemu plików.\n" +#: .././db/check.c:1474 +#, c-format +msgid "root inode %lld is missing\n" +msgstr "brak głównego i-węzła %lld\n" -#: .././repair/init.c:47 +#: .././db/check.c:1479 #, c-format -msgid "getrlimit(RLIMIT_FSIZE) failed!\n" -msgstr "getrlimit(RLIMIT_FSIZE) nie powiodło się!\n" +msgid "root inode %lld is not a directory\n" +msgstr "główny i-węzeł %lld nie jest katalogiem\n" -#: .././repair/init.c:55 +#: .././db/check.c:1495 #, c-format -msgid "setrlimit failed - current: %lld, max: %lld\n" -msgstr "setrlimit nie powiodło się - bieżący: %lld, max: %lld\n" +msgid "rtblock %llu out of range\n" +msgstr "rtblok %llu poza zakresem\n" -#: .././repair/init.c:102 -msgid "couldn't initialize XFS library\n" -msgstr "nie udało się zainicjować biblioteki XFS\n" +#: .././db/check.c:1519 +#, c-format +msgid "blocks %u/%u..%u claimed by block %u/%u\n" +msgstr "bloki %u/%u..%u przypisane do bloku %u/%u\n" -#: .././repair/phase1.c:28 -msgid "Sorry, could not find valid secondary superblock\n" -msgstr "Niestety nie znaleziono poprawnego zapasowego superbloku\n" +#: .././db/check.c:1528 +#, c-format +msgid "setting block %u/%u to %s\n" +msgstr "ustawianie bloku %u/%u na %s\n" -#: .././repair/phase1.c:29 -msgid "Exiting now.\n" -msgstr "Zakończono.\n" +#: .././db/check.c:1551 +#, c-format +msgid "setting rtblock %llu to %s\n" +msgstr "ustawianie rtbloku %llu na %s\n" -#: .././repair/phase1.c:40 +#: .././db/check.c:1572 .././repair/rt.c:151 #, c-format -msgid "could not allocate ag header buffer (%d bytes)\n" -msgstr "nie udało się przydzielić bufora nagłówka ag (%d bajtów)\n" +msgid "rt summary mismatch, size %d block %llu, file: %d, computed: %d\n" +msgstr "opis rt nie zgadza się, rozmiar %d bloku %llu, plik: %d, obliczono: %d\n" -#: .././repair/phase1.c:58 -msgid "Phase 1 - find and verify superblock...\n" -msgstr "Faza 1 - szukanie i sprawdzanie superbloku...\n" +#: .././db/check.c:1597 +#, c-format +msgid "block %u/%u type %s not expected\n" +msgstr "blok %u/%u typu %s nie oczekiwany\n" -#: .././repair/phase1.c:74 -msgid "error reading primary superblock\n" -msgstr "błąd podczas odczytu głównego superbloku\n" +#: .././db/check.c:1618 +#, c-format +msgid "rtblock %llu type %s not expected\n" +msgstr "rtblok %llu typu %s nie oczekiwany\n" -#: .././repair/phase1.c:80 +#: .././db/check.c:1655 #, c-format -msgid "bad primary superblock - %s !!!\n" -msgstr "błędny główny superblok - %s!!!\n" +msgid "dir ino %lld missing leaf entry for %x/%x\n" +msgstr "i-węzeł katalogu %lld - brak wpisu liścia dla %x/%x\n" -#: .././repair/phase1.c:87 +#: .././db/check.c:1774 #, c-format -msgid "couldn't verify primary superblock - %s !!!\n" -msgstr "nie udało się sprawdzić głównego superbloku - %s!!!\n" +msgid "bad superblock magic number %x, giving up\n" +msgstr "błędna liczba magiczna superbloku %x, poddaję się\n" -#: .././repair/phase1.c:105 -msgid "superblock has a features2 mismatch, correcting\n" -msgstr "superblok ma niepasujące features2, poprawianie\n" +#: .././db/check.c:1828 +msgid "bad option for blockget command\n" +msgstr "błędna opcja dla polecenia blockget\n" -#: .././repair/phase1.c:122 +#: .././db/check.c:1909 #, c-format -msgid "Enabling lazy-counters\n" -msgstr "Włączanie leniwych liczników\n" +msgid "bad option -%c for ncheck command\n" +msgstr "błędna opcja -%c dla polecenia ncheck\n" -#: .././repair/phase1.c:127 +#: .././db/check.c:1983 #, c-format -msgid "Disabling lazy-counters\n" -msgstr "Wyłączanie leniwych liczników\n" +msgid "block 0 for directory inode %lld is missing\n" +msgstr "brak bloku 0 dla i-węzła katalogu %lld\n" -#: .././repair/phase1.c:130 +#: .././db/check.c:2003 #, c-format -msgid "Lazy-counters are already %s\n" -msgstr "Leniwe liczniki już są %s\n" - -#: .././repair/phase1.c:131 -msgid "enabled" -msgstr "włączone" - -#: .././repair/phase1.c:131 -msgid "disabled" -msgstr "wyłączone" - -#: .././repair/phase1.c:138 -msgid "writing modified primary superblock\n" -msgstr "zapisano zmodyfikowany główny superblok\n" - -#: .././repair/phase1.c:141 -msgid "would write modified primary superblock\n" -msgstr "zmodyfikowany główny superblok zostałby zapisany\n" +msgid "can't read block 0 for directory inode %lld\n" +msgstr "nie można odczytać bloku 0 dla i-węzła katalogu %lld\n" -#: .././repair/incore.c:230 +#: .././db/check.c:2049 #, c-format -msgid "couldn't allocate realtime block map, size = %\n" -msgstr "nie udało się przydzielić mapy bloków realtime, size = %\n" - -#: .././repair/incore.c:295 -msgid "couldn't allocate block map btree roots\n" -msgstr "nie udało się przydzielić korzeni b-drzewa mapy bloków\n" - -#: .././repair/incore.c:299 -msgid "couldn't allocate block map locks\n" -msgstr "nie udało się przydzielić blokad mapy bloków\n" +msgid "inode %lld extent [%lld,%lld,%lld,%d]\n" +msgstr "ekstent i-węzła %lld [%lld,%lld,%lld,%d]\n" -#: .././repair/dino_chunks.c:58 +#: .././db/check.c:2052 #, c-format -msgid "cannot read agbno (%u/%u), disk block %\n" -msgstr "nie można odczytać agbno (%u/%u), blok dysku %\n" +msgid "bmap rec out of order, inode %lld entry %d\n" +msgstr "błędna kolejność bmap rec - i-węzeł %lld, wpis %d\n" -#: .././repair/dino_chunks.c:149 +#: .././db/check.c:2058 #, c-format -msgid "uncertain inode block %d/%d already known\n" -msgstr "niepewny blok i-węzła %d/%d już znany\n" +msgid "inode %lld bad rt block number %lld, offset %lld\n" +msgstr "i-węzeł %lld - błędny numer bloku rt %lld, offset %lld\n" -#: .././repair/dino_chunks.c:165 .././repair/dino_chunks.c:437 -#: .././repair/dino_chunks.c:496 +#: .././db/check.c:2068 .././db/check.c:2074 #, c-format -msgid "inode block %d/%d multiply claimed, (state %d)\n" -msgstr "blok i-węzła %d/%d już przypisany (stan %d)\n" +msgid "inode %lld bad block number %lld [%d,%d], offset %lld\n" +msgstr "i-węzeł %lld - błędny numer bloku %lld [%d,%d], offset %lld\n" -#: .././repair/dino_chunks.c:172 .././repair/dino_chunks.c:501 +#: .././db/check.c:2092 .././db/check.c:2106 #, c-format -msgid "inode block %d/%d bad state, (state %d)\n" -msgstr "blok i-węzła (%d/%d) w błędnym stanie (stan %d)\n" +msgid "inode %lld block %lld at offset %lld\n" +msgstr "i-węzeł %lld: blok %lld pod offsetem %lld\n" -#: .././repair/dino_chunks.c:444 +#: .././db/check.c:2133 #, c-format -msgid "uncertain inode block overlap, agbno = %d, ino = %\n" -msgstr "niepewny blok i-węzła pokrywa się, agbno = %d, i-węzeł %\n" +msgid "level for ino %lld %s fork bmap root too large (%u)\n" +msgstr "i-węzeł %lld: poziom bmap root odgałęzienia %s zbyt duży (%u)\n" -#: .././repair/dino_chunks.c:483 +#: .././db/check.c:2145 #, c-format -msgid "uncertain inode block % already known\n" -msgstr "niepewny blok i-węzła % już znany\n" +msgid "numrecs for ino %lld %s fork bmap root too large (%u)\n" +msgstr "i-węzeł %lld: liczba rekordów bmap root odgałęzienia %s zbyt duża (%u)\n" -#: .././repair/dino_chunks.c:620 +#: .././db/check.c:2172 #, c-format -msgid "failed to allocate %zd bytes of memory\n" -msgstr "nie udało się przydzielić %zd bajtów pamięci\n" +msgid "extent count for ino %lld %s fork too low (%d) for file format\n" +msgstr "i-węzeł %lld: liczba ekstentów dla odgałęzienia %s zbyt mała (%d) dla formatu pliku\n" -#: .././repair/dino_chunks.c:631 +#: .././db/check.c:2222 .././db/check.c:3153 #, c-format -msgid "cannot read inode %, disk block %, cnt %d\n" -msgstr "nie można odczytać i-węzła %, blok dysku %, cnt %d\n" +msgid "bad directory data magic # %#x for dir ino %lld block %d\n" +msgstr "błędna liczba magiczna danych katalogu %#x dla i-węzła katalogu %lld, blok %d\n" -#: .././repair/dino_chunks.c:747 .././repair/dino_chunks.c:922 +#: .././db/check.c:2239 #, c-format -msgid "bad state in block map %d\n" -msgstr "błędny stan w mapie bloku %d\n" +msgid "bad block directory tail for dir ino %lld\n" +msgstr "błędny koniec katalogu bloku dla i-węzła katalogu %lld\n" -#: .././repair/dino_chunks.c:751 .././repair/dino_chunks.c:928 +#: .././db/check.c:2284 #, c-format -msgid "inode block % multiply claimed, state was %d\n" -msgstr "blok i-węzła % wielokrotnie przydzielony, stan był %d\n" +msgid "dir %lld block %d bad free entry at %d\n" +msgstr "katalog %lld, blok %d: błędny wolny wpis pod %d\n" -#: .././repair/dino_chunks.c:788 +#: .././db/check.c:2308 #, c-format -msgid "imap claims in-use inode % is free, " -msgstr "imap twierdzi, że używany i-węzeł % jest wolny, " - -#: .././repair/dino_chunks.c:793 -msgid "correcting imap\n" -msgstr "poprawiono imap\n" - -#: .././repair/dino_chunks.c:795 -msgid "would correct imap\n" -msgstr "imap zostałoby poprawione\n" +msgid "dir %lld block %d zero length entry at %d\n" +msgstr "katalog %lld, blok %d: wpis zerowej długości pod %d\n" -#: .././repair/dino_chunks.c:841 +#: .././db/check.c:2317 #, c-format -msgid "cleared root inode %\n" -msgstr "wyczyszczono główny i-węzeł %\n" +msgid "dir %lld block %d bad entry at %d\n" +msgstr "katalog %lld, blok %d: błędny wpis pod %d\n" -#: .././repair/dino_chunks.c:845 +#: .././db/check.c:2335 #, c-format -msgid "would clear root inode %\n" -msgstr "główny węzeł % zostałby wyczyszczony\n" +msgid "dir %lld block %d entry %*.*s %lld\n" +msgstr "katalog %lld, blok %d, wpis %*.*s %lld\n" -#: .././repair/dino_chunks.c:853 +#: .././db/check.c:2342 #, c-format -msgid "cleared realtime bitmap inode %\n" -msgstr "wyczyszczono i-węzeł bitmapy realtime %\n" +msgid "dir %lld block %d entry %*.*s bad inode number %lld\n" +msgstr "katalog %lld, blokd %d, epis %*.*s: błędny number i-węzła %lld\n" -#: .././repair/dino_chunks.c:857 +#: .././db/check.c:2352 #, c-format -msgid "would clear realtime bitmap inode %\n" -msgstr "i-węzeł bitmapy realtime % zostałby wyczyszczony\n" +msgid "multiple .. entries in dir %lld (%lld, %lld)\n" +msgstr "wiele wpisów .. w katalogu %lld (%lld, %lld)\n" -#: .././repair/dino_chunks.c:865 +#: .././db/check.c:2369 #, c-format -msgid "cleared realtime summary inode %\n" -msgstr "wyczyszczono i-węzeł opisu realtime %\n" +msgid "dir %lld entry . inode number mismatch (%lld)\n" +msgstr "katalog %lld, wpis .: niezgodność numeru i-węzła (%lld)\n" -#: .././repair/dino_chunks.c:869 +#: .././db/check.c:2382 #, c-format -msgid "would clear realtime summary inode %\n" -msgstr "i-węzeł opisu realtime % zostałby wyczyszczony\n" +msgid "dir %lld block %d bad count %u\n" +msgstr "katalog %lld, blok %d: błędny licznik %u\n" -#: .././repair/dino_chunks.c:873 +#: .././db/check.c:2393 .././db/check.c:3167 #, c-format -msgid "cleared inode %\n" -msgstr "wyczyszczono i-węzeł %\n" +msgid "dir %lld block %d extra leaf entry %x %x\n" +msgstr "katalog %lld, blok %d: nadmiarowy wpis liścia %x %x\n" -#: .././repair/dino_chunks.c:876 +#: .././db/check.c:2405 #, c-format -msgid "would have cleared inode %\n" -msgstr "i-węzeł % zostałby wyczyszczony\n" - -#: .././repair/dino_chunks.c:1083 .././repair/dino_chunks.c:1118 -#: .././repair/dino_chunks.c:1232 -msgid "found inodes not in the inode allocation tree\n" -msgstr "znaleziono i-węzły nieobecne w drzewie alokacji i-węzłów\n" +msgid "dir %lld block %d bad bestfree data\n" +msgstr "katalog %lld, blok %d: błędne dane bestfree\n" -#: .././repair/dinode.c:46 +#: .././db/check.c:2412 #, c-format -msgid "clearing inode % attributes\n" -msgstr "wyczyszczono atrybuty i-węzła %\n" +msgid "dir %lld block %d bad block tail count %d (stale %d)\n" +msgstr "katalog %lld, blok %d: błędny licznik końca bloku %d (stale %d)\n" -#: .././repair/dinode.c:49 +#: .././db/check.c:2421 #, c-format -msgid "would have cleared inode % attributes\n" -msgstr "atrybuty i-węzła % zostałyby wyczyszczone\n" +msgid "dir %lld block %d bad stale tail count %d\n" +msgstr "katalog %lld, blok %d: błędny licznik końca stale %d\n" -#: .././repair/dinode.c:424 +#: .././db/check.c:2427 #, c-format -msgid "inode % - bad rt extent start block number %, offset %\n" -msgstr "i-węzeł % - błędny numer bloku początkowego ekstentu rt %, offset %\n" +msgid "dir %lld block %d consecutive free entries\n" +msgstr "katalog %lld, blok %d: kolejne wolne wpisy\n" -#: .././repair/dinode.c:432 +#: .././db/check.c:2433 #, c-format -msgid "inode % - bad rt extent last block number %, offset %\n" -msgstr "i-węzeł % - błędny numer bloku końcowego ekstentu rt %, offset %\n" +msgid "dir %lld block %d entry/unused tag mismatch\n" +msgstr "katalog %lld, blok %d: niezgodność znacznika wpis/nieużywany\n" -#: .././repair/dinode.c:440 +#: .././db/check.c:2482 #, c-format -msgid "inode % - bad rt extent overflows - start %, end %, offset %\n" -msgstr "i-węzeł % - błędne przepełnienie ekstentu rt - początek %, koniec %, offset %\n" +msgid "no . entry for directory %lld\n" +msgstr "brak wpisu . dla katalogu %lld\n" -#: .././repair/dinode.c:457 +#: .././db/check.c:2487 #, c-format -msgid "malformed rt inode extent [% %] (fs rtext size = %u)\n" -msgstr "zniekształcony ekstent i-węzła rt [% %] (rozmiar fs rtext = %u)\n" +msgid "no .. entry for directory %lld\n" +msgstr "brak wpisu .. dla katalogu %lld\n" -#: .././repair/dinode.c:478 +#: .././db/check.c:2491 #, c-format -msgid "data fork in rt ino % claims dup rt extent,off - %, start - %, count %\n" -msgstr "gałąź danych w i-węźle rt % odwołuje się do powtórzonego ekstentu rt, offset %, początek %, liczba %\n" +msgid ". and .. same for non-root directory %lld\n" +msgstr ". i .. są takie same dla katalogu %lld (nie będącego głównym)\n" -#: .././repair/dinode.c:497 +#: .././db/check.c:2496 #, c-format -msgid "bad state in rt block map %\n" -msgstr "błędny stan w mapie bloku rt %\n" +msgid "root directory %lld has .. %lld\n" +msgstr "główny katalog %lld ma .. %lld\n" -#: .././repair/dinode.c:503 +#: .././db/check.c:2529 #, c-format -msgid "data fork in rt inode % found metadata block % in rt bmap\n" -msgstr "gałąź danych w i-węźle rt % - znaleziono blok metadanych % w bmapie rt\n" +msgid "bad size (%lld) or format (%d) for directory inode %lld\n" +msgstr "błędny rozmiar (%lld) lub format (%d) dla i-węzła katalogu %lld\n" -#: .././repair/dinode.c:511 +#: .././db/check.c:2557 #, c-format -msgid "data fork in rt inode % claims used rt block %\n" -msgstr "gałąź danych w i-węźle rt % odwołuje się do używanego bloku rt %\n" +msgid "bad number of extents %d for inode %lld\n" +msgstr "błędna liczba ekstentów %d dla i-węzła %lld\n" -#: .././repair/dinode.c:517 +#: .././db/check.c:2629 #, c-format -msgid "illegal state %d in rt block map %\n" -msgstr "niedozwolony stan %d w mapie bloku rt %\n" - -#: .././repair/dinode.c:568 .././repair/dinode.c:1135 .././repair/scan.c:184 -#: .././db/check.c:2130 .././db/check.c:2142 .././db/check.c:2169 -#: .././db/bmap.c:216 -msgid "data" -msgstr "danych" - -#: .././repair/dinode.c:570 .././repair/dinode.c:1137 .././repair/scan.c:186 -#: .././db/check.c:2130 .././db/check.c:2142 .././db/check.c:2169 -#: .././db/bmap.c:216 -msgid "attr" -msgstr "atrybutów" - -#: .././repair/dinode.c:573 -msgid "real-time" -msgstr "realtime" +msgid "bad magic number %#x for inode %lld\n" +msgstr "błędna liczba magiczna %#x dla i-węzła %lld\n" -#: .././repair/dinode.c:575 -msgid "regular" -msgstr "zwykłym" +#: .././db/check.c:2636 +#, c-format +msgid "bad version number %#x for inode %lld\n" +msgstr "błędny numer wersji %#x dla i-węzła %lld\n" -#: .././repair/dinode.c:585 +#: .././db/check.c:2644 #, c-format -msgid "bmap rec out of order, inode % entry %d [o s c] [% % %], %d [% % %]\n" -msgstr "rekord bmap uszkodzony, i-węzeł % wpis %d [o s c] [% % %], %d [% % %]\n" +msgid "bad nblocks %lld for free inode %lld\n" +msgstr "błędna liczba bloków %lld dla wolnego i-węzła %lld\n" -#: .././repair/dinode.c:601 +#: .././db/check.c:2655 #, c-format -msgid "zero length extent (off = %, fsbno = %) in ino %\n" -msgstr "ekstent zerowej długości (off = %, fsbno = %) w i-węźle %\n" +msgid "bad nlink %d for free inode %lld\n" +msgstr "błądna liczba dowiązań %d dla wolnego i-węzła %lld\n" -#: .././repair/dinode.c:632 +#: .././db/check.c:2661 #, c-format -msgid "inode % - bad extent starting block number %, offset %\n" -msgstr "i-węzeł % - błędny numer bloku początkowego ekstentu %, offset %\n" +msgid "bad mode %#o for free inode %lld\n" +msgstr "błędne uprawnienia %#o dla wolnego i-węzła %lld\n" -#: .././repair/dinode.c:640 +#: .././db/check.c:2670 #, c-format -msgid "inode % - bad extent last block number %, offset %\n" -msgstr "i-węzeł % - błędny numer bloku końcowego ekstentu %, offset %\n" +msgid "bad next unlinked %#x for inode %lld\n" +msgstr "błędny następny niedowiązany %#x dla i-węzła %lld\n" -#: .././repair/dinode.c:648 +#: .././db/check.c:2680 #, c-format -msgid "inode % - bad extent overflows - start %, end %, offset %\n" -msgstr "i-węzeł % - błędne przepełnienie ekstentu - początek %, koniec %, offset %\n" +msgid "bad format %d for inode %lld type %#o\n" +msgstr "błędny format %d dla i-węzła %lld typu %#o\n" -#: .././repair/dinode.c:658 +#: .././db/check.c:2688 #, c-format -msgid "inode % - extent offset too large - start %, count %, offset %\n" -msgstr "i-węzeł % - offset ekstentu zbyt duży - początek %, liczba %, offset %\n" +msgid "bad fork offset %d for inode %lld\n" +msgstr "błędny offset odgałęzienia %d dla i-węzła %lld\n" -#: .././repair/dinode.c:678 +#: .././db/check.c:2695 #, c-format -msgid "" -"Fatal error: inode % - blkmap_set_ext(): %s\n" -"\t%s fork, off - %, start - %, cnt %\n" -msgstr "" -"Błąd krytyczny: i-węzeł % - blkmap_set_ext(): %s\n" -"\tgałąź %s, offset %, początek %, liczba %\n" +msgid "bad attribute format %d for inode %lld\n" +msgstr "błędny format atrybutu %d dla i-węzła %lld\n" -#: .././repair/dinode.c:709 +#: .././db/check.c:2701 #, c-format -msgid "%s fork in ino % claims dup extent, off - %, start - %, cnt %\n" -msgstr "gałąź %s w i-węźle % odwołuje się do powtórzonego ekstentu, offset %, początek %, liczba %\n" +msgid "inode %lld mode %#o fmt %s afmt %s nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n" +msgstr "i-węzeł %lld mode %#o fmt %s afmt %s nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n" -#: .././repair/dinode.c:728 +#: .././db/check.c:2822 #, c-format -msgid "%s fork in ino % claims free block %\n" -msgstr "gałąź %s w i-węźle % odwołuje się do wolnego bloku %\n" +msgid "bad nblocks %lld for inode %lld, counted %lld\n" +msgstr "błędna liczba bloków %lld dla i-węzła %lld, naliczono %lld\n" -#: .././repair/dinode.c:736 +#: .././db/check.c:2829 #, c-format -msgid "bad state in block map %\n" -msgstr "błędny stan w mapie bloku %\n" +msgid "bad nextents %d for inode %lld, counted %d\n" +msgstr "błędna liczba ekstentów %d dla i-węzła %lld, naliczono %d\n" -#: .././repair/dinode.c:742 +#: .././db/check.c:2835 #, c-format -msgid "%s fork in inode % claims metadata block %\n" -msgstr "gałąź %s w i-węźle % odwołuje się do bloku metadanych %\n" +msgid "bad anextents %d for inode %lld, counted %d\n" +msgstr "błędne anextents %d dla i-węzła %lld, naliczono %d\n" -#: .././repair/dinode.c:750 +#: .././db/check.c:2887 #, c-format -msgid "%s fork in %s inode % claims used block %\n" -msgstr "gałąź %s w i-węźle %s % odwołuje się do używanego bloku %\n" +msgid "local inode %lld data is too large (size %lld)\n" +msgstr "dane lokalnego i-węzła %lld zbyt duże (rozmiar %lld)\n" -#: .././repair/dinode.c:756 +#: .././db/check.c:2896 #, c-format -msgid "illegal state %d in block map %\n" -msgstr "niedozwolony stan %d w mapie bloku %\n" +msgid "local inode %lld attr is too large (size %d)\n" +msgstr "atrybuty lokalnego i-węzła %lld zbyt duże (rozmiar %d)\n" -#: .././repair/dinode.c:769 +#: .././db/check.c:2945 #, c-format -msgid "correcting nextents for inode %\n" -msgstr "poprawiono nextents dla i-węzła %\n" +msgid "dir inode %lld block %u=%llu\n" +msgstr "i-węzeł katalogu %lld, blok %u=%llu\n" -#: .././repair/dinode.c:841 +#: .././db/check.c:2957 #, c-format -msgid "cannot read inode (%u/%u), disk block %\n" -msgstr "nie można odczytać i-węzła (%u/%u), blok dysku %\n" +msgid "can't read block %u for directory inode %lld\n" +msgstr "nie można odczytać bloku %u dla i-węzła katalogu %lld\n" -#: .././repair/dinode.c:952 .././repair/dinode.c:1009 +#: .././db/check.c:2971 #, c-format -msgid "cannot read bmap block %\n" -msgstr "nie można odczytać bloku bmap %\n" +msgid "multiple .. entries in dir %lld\n" +msgstr "wiele wpisów .. w katalogu %lld\n" -#: .././repair/dinode.c:973 +#: .././db/check.c:2993 #, c-format -msgid "# of bmap records in inode % exceeds max (%u, max - %u)\n" -msgstr "liczba rekordów bmap w i-węźle % przekracza maksimum (%u, maksimum %u)\n" +msgid "missing free index for data block %d in dir ino %lld\n" +msgstr "brak indeksu wolnego miejsca dla bloku danych %d w i-węźle katalogu %lld\n" -#: .././repair/dinode.c:981 +#: .././db/check.c:3019 #, c-format -msgid "- # of bmap records in inode % less than minimum (%u, min - %u), proceeding ...\n" -msgstr "- liczba rekordów bmap w i-węźle % mniejsza niż minimum (%u, minimum %u), kontynuacja...\n" +msgid "bad free block magic # %#x for dir ino %lld block %d\n" +msgstr "błędna liczba magiczna wolnego bloku %#x dla i-węzła katalogu %lld, blok %d\n" -#: .././repair/dinode.c:1023 +#: .././db/check.c:3029 #, c-format -msgid "# of bmap records in inode % greater than maximum (%u, max - %u)\n" -msgstr "liczba rekordów bmap w i-węźle % większa niż maksimum (%u, maksimum %u)\n" +msgid "bad free block firstdb %d for dir ino %lld block %d\n" +msgstr "błędne firstdb wolnego bloku %d dla i-węzła katalogu %lld, blok %d\n" -#: .././repair/dinode.c:1030 +#: .././db/check.c:3042 #, c-format -msgid "- # of bmap records in inode % less than minimum (%u, min - %u), continuing...\n" -msgstr "- liczba rekordów bmap w i-węźle % mniejsza niż minimum (%u, minimum %u), kontynuacja...\n" +msgid "bad free block nvalid/nused %d/%d for dir ino %lld block %d\n" +msgstr "błędne liczby nvalid/nused (%d/%d) wolnych bloków w i-węźle katalogu %lld, blok %d\n" -#: .././repair/dinode.c:1046 +#: .././db/check.c:3056 #, c-format -msgid "could not map block %\n" -msgstr "nie udało się odwzorować bloku %\n" +msgid "bad free block ent %d is %d should be %d for dir ino %lld block %d\n" +msgstr "błędna liczba ent %d (równa %d, powinna być %d) wolnego bloku w i-węźle katalogu %lld, blok %d\n" -#: .././repair/dinode.c:1080 +#: .././db/check.c:3070 #, c-format -msgid "get_bmapi() called for local inode %\n" -msgstr "get_bmapi() wywołano dla lokalnego i-węzła %\n" +msgid "bad free block nused %d should be %d for dir ino %lld block %d\n" +msgstr "błędna liczba nused (%d, powinna być %d) wolnego bloku w i-węźle katalogu %lld, blok %d\n" -#: .././repair/dinode.c:1088 +#: .././db/check.c:3100 #, c-format -msgid "bad inode format for inode %\n" -msgstr "błędny format i-węzła dla i-węzła %\n" +msgid "bad leaf block forw/back pointers %d/%d for dir ino %lld block %d\n" +msgstr "błędne wskaźniki przód/tył (%d/%d) bloku liścia w i-węźle katalogu %lld, blok %d\n" -#: .././repair/dinode.c:1152 +#: .././db/check.c:3109 #, c-format -msgid "bad level %d in inode % bmap btree root block\n" -msgstr "błędny poziom %d w bloku głównym bmap btree i-węzła %\n" +msgid "single leaf block for dir ino %lld block %d should be at block %d\n" +msgstr "blok pojedynczego liścia dla i-węzłu katalogu %lld, blok %d powinien być w bloku %d\n" -#: .././repair/dinode.c:1158 +#: .././db/check.c:3121 #, c-format -msgid "bad numrecs 0 in inode % bmap btree root block\n" -msgstr "błędne numrecs 0 w bloku głównym bmap btree i-węzła %\n" +msgid "bestfree %d for dir ino %lld block %d doesn't match table value %d\n" +msgstr "bestfree %d dla i-węzła katalogu %lld, blok %d nie zgadza się z wartością w tablicy %d\n" -#: .././repair/dinode.c:1167 +#: .././db/check.c:3144 #, c-format -msgid "indicated size of %s btree root (%d bytes) greater than space in inode % %s fork\n" -msgstr "oznaczony rozmiar korzenia b-drzewa %s (%d bajtów) większy niż miejsce w i-węźle % gałęzi %s\n" +msgid "bad node block level %d for dir ino %lld block %d\n" +msgstr "błędny poziom bloku węzła %d dla i-węzła katalogu %lld, blok %d\n" -#: .././repair/dinode.c:1187 .././repair/scan.c:406 +#: .././db/check.c:3176 #, c-format -msgid "bad bmap btree ptr 0x%llx in ino %\n" -msgstr "błędny wskaźnik bmap btree 0x%llx w i-węźle %\n" +msgid "dir %lld block %d stale mismatch %d/%d\n" +msgstr "katalog %lld, blok %d: niezgodność liczby stale %d/%d\n" -#: .././repair/dinode.c:1206 +#: .././db/check.c:3232 #, c-format -msgid "correcting key in bmbt root (was %llu, now %) in inode % %s fork\n" -msgstr "poprawiono klucz w korzeniu bmbt (był %llu, jest %) w i-węźle % gałęzi %s\n" +msgid "can't read block %lld for %s quota inode (fsblock %lld)\n" +msgstr "nie można odczytać bloku %lld i-węzła limitów %s (blok fs %lld)\n" -#: .././repair/dinode.c:1218 +#: .././db/check.c:3242 #, c-format -msgid "bad key in bmbt root (is %llu, would reset to %) in inode % %s fork\n" -msgstr "błędny klucz w korzeniu bmbt (jest %llu, zostałby przestawiony na %) w i-węźle % gałęzi %s\n" +msgid "%s dqblk %lld entry %d id %u bc %lld ic %lld rc %lld\n" +msgstr "%s dqblk %lld wpis %d id %u bc %lld ic %lld rc %lld\n" -#: .././repair/dinode.c:1235 +#: .././db/check.c:3250 #, c-format -msgid "out of order bmbt root key % in inode % %s fork\n" -msgstr "niepoprawny klucz korzenia bmbt % w i-węźle % gałęzi %s\n" +msgid "bad magic number %#x for %s dqblk %lld entry %d id %u\n" +msgstr "błędna liczba magiczna %#x dla dqblk %s %lld, wpis %d, id %u\n" -#: .././repair/dinode.c:1252 +#: .././db/check.c:3259 #, c-format -msgid "extent count for ino % %s fork too low (%) for file format\n" -msgstr "i-węzeł %: liczba ekstentów dla odgałęzienia %s zbyt mała (%) dla formatu pliku\n" +msgid "bad version number %#x for %s dqblk %lld entry %d id %u\n" +msgstr "błędny numer wersji %#x dla dqblk %s %lld, wpis %d, id %u\n" -#: .././repair/dinode.c:1263 +#: .././db/check.c:3269 #, c-format -msgid "bad fwd (right) sibling pointer (saw % should be NULLDFSBNO)\n" -msgstr "błędny wskaźnik fwd (prawy) (widziano %, powinno być NULLDFSBNO)\n" +msgid "bad flags %#x for %s dqblk %lld entry %d id %u\n" +msgstr "błędne flagi %#x dla dqblk %s %lld, wpis %d, id %u\n" -#: .././repair/dinode.c:1266 +#: .././db/check.c:3278 #, c-format -msgid "\tin inode % (%s fork) bmap btree block %\n" -msgstr "\tw i-węźle % (gałęzi %s) bloku bmap btree %\n" +msgid "bad id %u for %s dqblk %lld entry %d id %u\n" +msgstr "błędne id %u dla dqblk %s %lld, wpis %d, id %u\n" -#: .././repair/dinode.c:1339 +#: .././db/check.c:3324 #, c-format -msgid "local inode % data fork is too large (size = %lld, max = %d)\n" -msgstr "gałąź danych lokalnego i-węzła % zbyt duża (rozmiar = %lld, maksimum = %d)\n" +msgid "block %lld for rtbitmap inode is missing\n" +msgstr "brak bloku %lld dla i-węzła rtbitmapy\n" -#: .././repair/dinode.c:1347 +#: .././db/check.c:3335 #, c-format -msgid "local inode % attr fork too large (size %d, max = %d)\n" -msgstr "gałąź atrybutów lokalnego i-węzła % zbyt duża (rozmiar %d, maksimum = %d)\n" +msgid "can't read block %lld for rtbitmap inode\n" +msgstr "nie można odczytać bloku %lld dla i-węzła rtbitmapy\n" -#: .././repair/dinode.c:1354 +#: .././db/check.c:3391 #, c-format -msgid "local inode % attr too small (size = %d, min size = %zd)\n" -msgstr "gałąź atrybutów lokalnego i-węzła % zbyt mała (rozmiar = %d, minimum = %zd)\n" +msgid "block %lld for rtsummary inode is missing\n" +msgstr "brak bloku %lld dla i-węzła rtsummary\n" -#: .././repair/dinode.c:1378 +#: .././db/check.c:3402 #, c-format -msgid "mismatch between format (%d) and size (%) in symlink ino %\n" -msgstr "niezgodność między formatem (%d) a rozmiarem (%) w i-węźle dowiązania symbolicznego %\n" +msgid "can't read block %lld for rtsummary inode\n" +msgstr "nie można odczytać bloku %lld dla i-węzła rtsummary\n" -#: .././repair/dinode.c:1385 +#: .././db/check.c:3435 #, c-format -msgid "mismatch between format (%d) and size (%) in symlink inode %\n" -msgstr "niezgodność między formatem (%d) a rozmiarem (%) w i-węźle dowiązania symbolicznego %\n" +msgid "dir %lld entry . %lld\n" +msgstr "katalog %lld, wpis . %lld\n" -#: .././repair/dinode.c:1400 +#: .././db/check.c:3443 #, c-format -msgid "bad number of extents (%d) in symlink % data fork\n" -msgstr "błędna liczba ekstentów (%d) w gałęzi danych dowiązania symbolicznego %\n" +msgid "dir %llu bad size in entry at %d\n" +msgstr "katalog %llu: błędny rozmiar we wpisie przy %d\n" -#: .././repair/dinode.c:1413 +#: .././db/check.c:3455 #, c-format -msgid "bad extent #%d offset (%) in symlink % data fork\n" -msgstr "błędny offset ekstentu %d (%) w gałęzi danych dowiązania symbolicznego %\n" +msgid "dir %lld entry %*.*s bad inode number %lld\n" +msgstr "katalog %lld wpis %*.*s: błędny numer i-węzła %lld\n" -#: .././repair/dinode.c:1419 +#: .././db/check.c:3467 #, c-format -msgid "bad extent #%d count (%) in symlink % data fork\n" -msgstr "błędna liczba ekstentów #%d (%) w gałęzi danych dowiązania symbolicznego %\n" +msgid "dir %lld entry %*.*s offset %d %lld\n" +msgstr "katalog %lld wpis %*.*s offset %d %lld\n" -#: .././repair/dinode.c:1474 +#: .././db/check.c:3472 #, c-format -msgid "symlink in inode % too long (%llu chars)\n" -msgstr "dowiązanie symboliczne w i-węźle % zbyt długie (%llu znaków)\n" +msgid "dir %lld entry %*.*s bad offset %d\n" +msgstr "katalog %lld wpis %*.*s błędny offset %d\n" -#: .././repair/dinode.c:1507 +#: .././db/check.c:3485 #, c-format -msgid "cannot read inode %, file block %d, disk block %\n" -msgstr "nie można odczytać i-węzła %, blok pliku %d, blok dysku %\n" +msgid "dir %llu size is %lld, should be %u\n" +msgstr "katalog %llu: rozmiar %lld, powinien być %u\n" -#: .././repair/dinode.c:1529 +#: .././db/check.c:3493 #, c-format -msgid "found illegal null character in symlink inode %\n" -msgstr "znaleziono niedozwolony znak null w i-węźle dowiązania symbolicznego %\n" +msgid "dir %llu offsets too high\n" +msgstr "katalog %llu: offsety zbyt duże\n" -#: .././repair/dinode.c:1543 .././repair/dinode.c:1553 +#: .././db/check.c:3504 #, c-format -msgid "component of symlink in inode % too long\n" -msgstr "składnik dowiązania symbolicznego w i-węźle % zbyt długi\n" +msgid "dir %lld entry .. bad inode number %lld\n" +msgstr "katalog %lld wpis .. - błędny numer i-węzła %lld\n" -#: .././repair/dinode.c:1579 +#: .././db/check.c:3509 #, c-format -msgid "inode % has bad inode type (IFMNT)\n" -msgstr "i-węzeł % ma błędny typ i-węzła (IFMNT)\n" +msgid "dir %lld entry .. %lld\n" +msgstr "katalog %lld wpis .. %lld\n" -#: .././repair/dinode.c:1590 +#: .././db/check.c:3512 #, c-format -msgid "size of character device inode % != 0 (% bytes)\n" -msgstr "rozmiar i-węzła urządzenia znakowego % != 0 (% bajtów)\n" +msgid "dir %lld i8count mismatch is %d should be %d\n" +msgstr "katalog %lld: niezgodność i8count: jest %d, powinno być %d\n" -#: .././repair/dinode.c:1595 +#: .././db/check.c:3594 #, c-format -msgid "size of block device inode % != 0 (% bytes)\n" -msgstr "rozmiar i-węzła urządzenia blokowego % != 0 (% bajtów)\n" +msgid "%s quota id %u, have/exp" +msgstr "limit %s id %u: jest/exp" -#: .././repair/dinode.c:1600 +#: .././db/check.c:3597 #, c-format -msgid "size of socket inode % != 0 (% bytes)\n" -msgstr "rozmiar i-węzła gniazda % != 0 (% bajtów)\n" +msgid " bc %lld/%lld" +msgstr " bc %lld/%lld" -#: .././repair/dinode.c:1605 +#: .././db/check.c:3601 #, c-format -msgid "size of fifo inode % != 0 (% bytes)\n" -msgstr "rozmiar i-węzła potoku % != 0 (% bajtów)\n" +msgid " ic %lld/%lld" +msgstr " ic %lld/%lld" -#: .././repair/dinode.c:1609 +#: .././db/check.c:3605 #, c-format -msgid "Internal error - process_misc_ino_types, illegal type %d\n" -msgstr "Błąd wewnętrzny - process_misc_ino_types, niedozwolony typ %d\n" +msgid " rc %lld/%lld" +msgstr " rc %lld/%lld" -#: .././repair/dinode.c:1636 +#: .././db/check.c:3661 #, c-format -msgid "size of character device inode % != 0 (% blocks)\n" -msgstr "rozmiar i-węzła urządzenia znakowego % != 0 (% bloków)\n" +msgid "can't read superblock for ag %u\n" +msgstr "nie można odczytać superbloku dla ag %u\n" -#: .././repair/dinode.c:1641 +#: .././db/check.c:3670 #, c-format -msgid "size of block device inode % != 0 (% blocks)\n" -msgstr "rozmiar i-węzła urządzenia blokowego % != 0 (% bloków)\n" +msgid "bad sb magic # %#x in ag %u\n" +msgstr "błędna liczba magiczna %#x superbloku w ag %u\n" -#: .././repair/dinode.c:1646 +#: .././db/check.c:3676 #, c-format -msgid "size of socket inode % != 0 (% blocks)\n" -msgstr "rozmiar i-węzła gniazda % != 0 (% bloków)\n" +msgid "bad sb version # %#x in ag %u\n" +msgstr "błędny numer wersji %#x superbloku w ag %u\n" -#: .././repair/dinode.c:1651 -#, c-format -msgid "size of fifo inode % != 0 (% blocks)\n" -msgstr "rozmiar i-węzła potoku % != 0 (% bloków)\n" +#: .././db/check.c:3686 .././db/sb.c:213 +msgid "mkfs not completed successfully\n" +msgstr "mkfs nie zakończony pomyślnie\n" -#: .././repair/dinode.c:1729 +#: .././db/check.c:3698 .././db/frag.c:366 #, c-format -msgid "root inode % has bad type 0x%x\n" -msgstr "i-węzeł główny % ma błędny typ 0x%x\n" - -#: .././repair/dinode.c:1733 -msgid "resetting to directory\n" -msgstr "przestawiono na katalog\n" - -#: .././repair/dinode.c:1737 -msgid "would reset to directory\n" -msgstr "zostałby przestawiony na katalog\n" +msgid "can't read agf block for ag %u\n" +msgstr "nie można odczytać bloku agf dla ag %u\n" -#: .././repair/dinode.c:1743 +#: .././db/check.c:3704 #, c-format -msgid "user quota inode % has bad type 0x%x\n" -msgstr "i-węzeł limitu użytkownika % ma błędny typ 0x%x\n" +msgid "bad agf magic # %#x in ag %u\n" +msgstr "błędna liczba magiczna agf %#x w ag %u\n" -#: .././repair/dinode.c:1752 +#: .././db/check.c:3710 #, c-format -msgid "group quota inode % has bad type 0x%x\n" -msgstr "i-węzeł limitu grupy % ma błędny typ 0x%x\n" +msgid "bad agf version # %#x in ag %u\n" +msgstr "błędny numer wersji agf %#x w ag %u\n" -#: .././repair/dinode.c:1762 +#: .././db/check.c:3726 .././db/frag.c:375 #, c-format -msgid "realtime summary inode % has bad type 0x%x, " -msgstr "i-węzeł opisu realtime % ma błędny typ 0x%x, " - -#: .././repair/dinode.c:1765 .././repair/dinode.c:1786 -msgid "resetting to regular file\n" -msgstr "przestawiono na zwykły plik\n" +msgid "can't read agi block for ag %u\n" +msgstr "nie można odczytać bloku agi w ag %u\n" -#: .././repair/dinode.c:1769 .././repair/dinode.c:1790 -msgid "would reset to regular file\n" -msgstr "zostałby przestawiony na zwykły plik\n" +#: .././db/check.c:3732 +#, c-format +msgid "bad agi magic # %#x in ag %u\n" +msgstr "błędna liczba magiczna agi %#x w ag %u\n" -#: .././repair/dinode.c:1774 +#: .././db/check.c:3738 #, c-format -msgid "bad # of extents (%u) for realtime summary inode %\n" -msgstr "błędna liczba ekstentów (%u) dla i-węzłą opisu realtime %\n" +msgid "bad agi version # %#x in ag %u\n" +msgstr "błędny numer wersji agi # %#x w ag %u\n" -#: .././repair/dinode.c:1783 +#: .././db/check.c:3763 .././repair/scan.c:1383 #, c-format -msgid "realtime bitmap inode % has bad type 0x%x, " -msgstr "i-węzeł bitmapy realtime % ma błędny typ 0x%x, " +msgid "agf_freeblks %u, counted %u in ag %u\n" +msgstr "agf_freeblks %u, naliczono %u w ag %u\n" -#: .././repair/dinode.c:1795 +#: .././db/check.c:3770 .././repair/scan.c:1388 #, c-format -msgid "bad # of extents (%u) for realtime bitmap inode %\n" -msgstr "błędna liczba ekstentów (%u) dla i-węzłą bitmapy realtime %\n" +msgid "agf_longest %u, counted %u in ag %u\n" +msgstr "agf_longest %u, naliczono %u w ag %u\n" -#: .././repair/dinode.c:1830 +#: .././db/check.c:3778 #, c-format -msgid "mismatch between format (%d) and size (%) in directory ino %\n" -msgstr "niezgodność między formatem (%d) a rozmiarem (%) w i-węźle katalogu %\n" +msgid "agf_btreeblks %u, counted %u in ag %u\n" +msgstr "agf_btreeblks %u, naliczono %u w ag %u\n" -#: .././repair/dinode.c:1836 +#: .././db/check.c:3786 .././repair/scan.c:1436 #, c-format -msgid "directory inode % has bad size %\n" -msgstr "i-węzeł katalogu % ma błędny rozmiar %\n" +msgid "agi_count %u, counted %u in ag %u\n" +msgstr "agi_count %u, naliczono %u w ag %u\n" -#: .././repair/dinode.c:1844 +#: .././db/check.c:3793 .././repair/scan.c:1441 #, c-format -msgid "bad data fork in symlink %\n" -msgstr "błędna gałąź danych w dowiązaniu symbolicznym %\n" +msgid "agi_freecount %u, counted %u in ag %u\n" +msgstr "agi_freecount %u, naliczono %u w ag %u\n" -#: .././repair/dinode.c:1865 +#: .././db/check.c:3802 #, c-format -msgid "found inode % claiming to be a real-time file\n" -msgstr "znaleziono i-węzeł % twierdzący, że należy do pliku realtime\n" +msgid "agi unlinked bucket %d is %u in ag %u (inode=%lld)\n" +msgstr "agi unlinked bucket %d is %u in ag %u (inode=%lld)\n" -#: .././repair/dinode.c:1874 +#: .././db/check.c:3840 #, c-format -msgid "realtime bitmap inode % has bad size % (should be %)\n" -msgstr "i-węzeł bitmapy realtime % ma błędny rozmiar % (powinien być %)\n" +msgid "can't read agfl block for ag %u\n" +msgstr "nie można odczytać bloku agfl dla ag %u\n" -#: .././repair/dinode.c:1885 +#: .././db/check.c:3850 .././db/freesp.c:255 .././repair/scan.c:1319 #, c-format -msgid "realtime summary inode % has bad size % (should be %d)\n" -msgstr "i-węzeł opisu realtime % ma błędny rozmiar % (powinien być %d)\n" +msgid "agf %d freelist blocks bad, skipping freelist scan\n" +msgstr "błędne bloki listy wolnych agf %d, pominięto przeszukanie listy wolnych\n" -#: .././repair/dinode.c:1913 +#: .././db/check.c:3872 #, c-format -msgid "bad attr fork offset %d in dev inode %, should be %d\n" -msgstr "błędny offset gałęzi atrybutów %d w i-węźle urządzenia %, powinien być %d\n" +msgid "freeblk count %u != flcount %u in ag %u\n" +msgstr "liczba freeblk %u != flcount %u w ag %u\n" -#: .././repair/dinode.c:1924 +#: .././db/check.c:3901 .././db/check.c:3929 .././db/frag.c:398 +#: .././db/frag.c:421 .././db/freesp.c:289 #, c-format -msgid "bad attr fork offset %d in inode %, max=%d\n" -msgstr "błędny offset gałęzi atrybutów %d w i-węźle %, maksimum=%d\n" +msgid "can't read btree block %u/%u\n" +msgstr "nie można odczytać bloku b-drzewa %u/%u\n" -#: .././repair/dinode.c:1931 +#: .././db/check.c:3962 #, c-format -msgid "unexpected inode format %d\n" -msgstr "nieoczekiwany format i-węzła %d\n" +msgid "bad magic # %#x in inode %lld bmbt block %u/%u\n" +msgstr "błędna liczba magiczna %#x w i-węźle %lld, blok bmbt %u/%u\n" -#: .././repair/dinode.c:1952 +#: .././db/check.c:3969 #, c-format -msgid "correcting nblocks for inode %, was %llu - counted %\n" -msgstr "poprawiono nblocks dla i-węzła % - było %llu, naliczono %\n" +msgid "expected level %d got %d in inode %lld bmbt block %u/%u\n" +msgstr "oczekiwano poziomu %d, a uzyskano %d w i-węźle %lld, blok bmbt %u/%u\n" -#: .././repair/dinode.c:1959 +#: .././db/check.c:3981 .././db/check.c:3998 #, c-format -msgid "bad nblocks %llu for inode %, would reset to %\n" -msgstr "błędne nblocks %llu dla i-węzła %, zostałoby przestawione na %\n" +msgid "bad btree nrecs (%u, min=%u, max=%u) in inode %lld bmap block %lld\n" +msgstr "błędna liczba rekordów b-drzewa (%u, min=%u, max=%u) w i-węźle %lld, blok bitmapy %lld\n" -#: .././repair/dinode.c:1967 +#: .././db/check.c:4026 #, c-format -msgid "too many data fork extents (%) in inode %\n" -msgstr "zbyt dużo ekstentów gałęzi danych (%) w i-węźle %\n" +msgid "bad magic # %#x in btbno block %u/%u\n" +msgstr "błędna liczba magiczna %#x w bloku btbno %u/%u\n" -#: .././repair/dinode.c:1974 +#: .././db/check.c:4035 #, c-format -msgid "correcting nextents for inode %, was %d - counted %\n" -msgstr "poprawiono nextents dla i-węzła % - było %d, naliczono %\n" +msgid "expected level %d got %d in btbno block %u/%u\n" +msgstr "oczekiwano poziomu %d, a uzyskano %d w bloku btbno %u/%u\n" -#: .././repair/dinode.c:1982 +#: .././db/check.c:4044 .././db/check.c:4072 .././db/check.c:4117 +#: .././db/check.c:4148 #, c-format -msgid "bad nextents %d for inode %, would reset to %\n" -msgstr "błędne nextents %d dla i-węzła %, zostałoby przestawione na %\n" +msgid "bad btree nrecs (%u, min=%u, max=%u) in btbno block %u/%u\n" +msgstr "błędna liczba rekordów b-drzewa (%u, min=%u, max=%u) w bloku btbno %u/%u\n" -#: .././repair/dinode.c:1990 +#: .././db/check.c:4059 .././repair/scan.c:630 #, c-format -msgid "too many attr fork extents (%) in inode %\n" -msgstr "zbyt dużo ekstentów gałęzi atrybutów (%) w i-węźle %\n" +msgid "out-of-order bno btree record %d (%u %u) block %u/%u\n" +msgstr "rekord b-drzewa bno poza kolejnością: %d (%u %u), blok %u/%u\n" -#: .././repair/dinode.c:1997 +#: .././db/check.c:4099 #, c-format -msgid "correcting anextents for inode %, was %d - counted %\n" -msgstr "poprawiono anextents dla i-węzła % - było %d, naliczono %\n" +msgid "bad magic # %#x in btcnt block %u/%u\n" +msgstr "błędna liczba magiczna %#x w bloku btcbt %u/%u\n" -#: .././repair/dinode.c:2004 +#: .././db/check.c:4108 #, c-format -msgid "bad anextents %d for inode %, would reset to %\n" -msgstr "błędne anextents %d dla i-węzła %, zostałoby przestawione na %\n" +msgid "expected level %d got %d in btcnt block %u/%u\n" +msgstr "oczekiwano poziomu %d, a uzyskano %d w bloku btcnt %u/%u\n" -#: .././repair/dinode.c:2016 +#: .././db/check.c:4136 .././repair/scan.c:642 #, c-format -msgid "nblocks (%) smaller than nextents for inode %\n" -msgstr "nblocks (%) mniejsze niż nextents dla i-węzła %\n" +msgid "out-of-order cnt btree record %d (%u %u) block %u/%u\n" +msgstr "rekord b-drzewa cnt poza kolejnością: %d (%u %u), blok %u/%u\n" -#: .././repair/dinode.c:2069 .././repair/dinode.c:2107 +#: .././db/check.c:4179 #, c-format -msgid "unknown format %d, ino % (mode = %d)\n" -msgstr "nieznany format %d, i-węzeł % (tryb = %d)\n" +msgid "bad magic # %#x in inobt block %u/%u\n" +msgstr "błędna liczba magiczna %#x w bloku inobt %u/%u\n" -#: .././repair/dinode.c:2074 +#: .././db/check.c:4186 #, c-format -msgid "bad data fork in inode %\n" -msgstr "błędna gałąź danych w i-węźle %\n" +msgid "expected level %d got %d in inobt block %u/%u\n" +msgstr "oczekiwano poziomu %d, a uzyskano %d w bloku inobt %u/%u\n" -#: .././repair/dinode.c:2145 +#: .././db/check.c:4195 .././db/check.c:4261 #, c-format -msgid "bad attribute format %d in inode %, " -msgstr "błędny format atrybutów %d w i-węźle %, " - -#: .././repair/dinode.c:2148 -msgid "resetting value\n" -msgstr "przestawiono wartość\n" - -#: .././repair/dinode.c:2152 -msgid "would reset value\n" -msgstr "wartość zostałaby przestawiona\n" +msgid "bad btree nrecs (%u, min=%u, max=%u) in inobt block %u/%u\n" +msgstr "błędna liczba rekordów b-drzewa (%u, min=%u, max=%u) w bloku inobt %u/%u\n" -#: .././repair/dinode.c:2182 .././repair/attr_repair.c:994 +#: .././db/check.c:4230 .././db/frag.c:490 #, c-format -msgid "illegal attribute format %d, ino %\n" -msgstr "niedozwolony format atrybutu %d, i-węzeł %\n" +msgid "can't read inode block %u/%u\n" +msgstr "nie można odczytać bloku i-węzła %u/%u\n" -#: .././repair/dinode.c:2197 +#: .././db/check.c:4248 #, c-format -msgid "bad attribute fork in inode %" -msgstr "błędna gałąź atrybutów w i-węźle %" - -#: .././repair/dinode.c:2201 -msgid ", clearing attr fork\n" -msgstr ", wyczyszczono gałąź atrybutów\n" - -#: .././repair/dinode.c:2210 -msgid ", would clear attr fork\n" -msgstr ", gałąź atrybutów zostałaby wyczyszczona\n" +msgid "ir_freecount/free mismatch, inode chunk %u/%u, freecount %d nfree %d\n" +msgstr "niezgodność ir_freecount/free, porcja i-węzłów %u/%u, freecount %d nfree %d\n" -#: .././repair/dinode.c:2238 +#: .././db/check.c:4303 #, c-format -msgid "illegal attribute fmt %d, ino %\n" -msgstr "niedozwolony format atrybutów %d, i-węzeł %\n" +msgid "setting inode to %lld for block %u/%u\n" +msgstr "ustawianie i-węzła na %lld dla bloku %u/%u\n" -#: .././repair/dinode.c:2258 +#: .././db/check.c:4335 #, c-format -msgid "problem with attribute contents in inode %\n" -msgstr "problem z zawartością atrybutu w i-węźle %\n" - -#: .././repair/dinode.c:2266 -msgid "would clear attr fork\n" -msgstr "gałąź atrybutów zostałaby wyczyszczona\n" +msgid "setting inode to %lld for rtblock %llu\n" +msgstr "ustawianie i-węzła na %lld dla rtbloku %llu\n" -#: .././repair/dinode.c:2309 +#: .././db/check.c:4351 #, c-format -msgid "version 2 inode % claims > %u links, " -msgstr "i-węzeł % w wersji 2 odwołuje się do > %u dowiązań, " - -#: .././repair/dinode.c:2313 -msgid "updating superblock version number\n" -msgstr "uaktualniono numer wersji superbloku\n" - -#: .././repair/dinode.c:2316 -msgid "would update superblock version number\n" -msgstr "numer wersji superbloku zostałby uaktualniony\n" +msgid "inode %lld nlink %u %s dir\n" +msgstr "i-węzeł %lld nlink %u katalog %s\n" -#: .././repair/dinode.c:2324 +#: .././db/command.c:82 .././db/help.c:56 .././libxcmd/help.c:49 #, c-format -msgid "WARNING: version 2 inode % claims > %u links, " -msgstr "UWAGA: i-węzeł % w wersji 2 odwołuje się do > %u dowiązań, " +msgid "command %s not found\n" +msgstr "nie znaleziono polecenia %s\n" -#: .././repair/dinode.c:2327 +#: .././db/command.c:86 #, c-format -msgid "" -"converting back to version 1,\n" -"this may destroy %d links\n" -msgstr "" -"przekształcanie z powrotem do wersji 1,\n" -"może to zniszczyć %d dowiązań\n" +msgid "bad argument count %d to %s, expected " +msgstr "błędny argument liczby %d dla %s, oczekiwano " -#: .././repair/dinode.c:2337 +#: .././db/command.c:88 #, c-format -msgid "" -"would convert back to version 1,\n" -"\tthis might destroy %d links\n" -msgstr "" -"zostałby przekształcony z powrotem do wersji 1,\n" -"\tco mogłoby zniszczyć %d dowiązań\n" +msgid "at least %d" +msgstr "przynajmniej %d" -#: .././repair/dinode.c:2352 +#: .././db/command.c:92 #, c-format -msgid "found version 2 inode %, " -msgstr "znaleziono i-węzeł % w wersji 2, " +msgid "between %d and %d" +msgstr "od %d do %d" -#: .././repair/dinode.c:2354 -msgid "converting back to version 1\n" -msgstr "przekształcono z powrotem do wersji 1\n" +#: .././db/command.c:93 +msgid " arguments\n" +msgstr " argumentów\n" -#: .././repair/dinode.c:2360 -msgid "would convert back to version 1\n" -msgstr "zostałby przekształcony z powrotem do wersji 1\n" +#: .././db/convert.c:171 +#, c-format +msgid "bad argument count %d to convert, expected 3,5,7,9 arguments\n" +msgstr "błędna liczba argumentów %d do konwersji, oczekiwano 3,5,7,9 argumentów\n" -#: .././repair/dinode.c:2374 +#: .././db/convert.c:176 .././db/convert.c:183 #, c-format -msgid "clearing obsolete nlink field in version 2 inode %, was %d, now 0\n" -msgstr "wyczyszczono przestarzałe pole nlink w i-węźle % w wersji 2 - było %d, jest 0\n" +msgid "unknown conversion type %s\n" +msgstr "nieznany rodzaj konwersji %s\n" + +#: .././db/convert.c:187 +msgid "result type same as argument\n" +msgstr "typ wyniku taki sam jak argument\n" -#: .././repair/dinode.c:2380 +#: .././db/convert.c:191 #, c-format -msgid "would clear obsolete nlink field in version 2 inode %, currently %d\n" -msgstr "przestarzałe pole nlink w i-węźle % w wersji 2 zostałoby wyczyszczone, aktualnie %d\n" +msgid "conflicting conversion type %s\n" +msgstr "konflikt typu konwersji %s\n" -#: .././repair/dinode.c:2449 +#: .././db/convert.c:269 #, c-format -msgid "bad magic number 0x%x on inode %%c" -msgstr "błędna liczba magiczna 0x%x w i-węźle %%c" +msgid "%s is not a number\n" +msgstr "%s nie jest liczbą\n" -#: .././repair/dinode.c:2454 -msgid " resetting magic number\n" -msgstr " przestawiono liczbę magiczną\n" +#: .././db/debug.c:27 +msgid "[flagbits]" +msgstr "[bity flag]" -#: .././repair/dinode.c:2458 -msgid " would reset magic number\n" -msgstr " liczba magiczna zostałaby przestawiona\n" +#: .././db/debug.c:28 +msgid "set debug option bits" +msgstr "ustawienie bitów opcji diagnostycznych" -#: .././repair/dinode.c:2466 +#: .././db/debug.c:42 #, c-format -msgid "bad version number 0x%x on inode %%c" -msgstr "błędny numer wersji 0x%x w i-węźle %%c" +msgid "bad value for debug %s\n" +msgstr "błędna wartość diagnostyki %s\n" -#: .././repair/dinode.c:2471 -msgid " resetting version number\n" -msgstr " przestawiono numer wersji\n" +#: .././db/dir2.c:1019 +msgid "Unknown directory buffer type!\n" +msgstr "Nieznany typ bufora katalogu!\n" + +#: .././db/dir2.c:1031 +msgid "Writing unknown directory buffer type!\n" +msgstr "Zapis nieznanego typu bufora katalogu!\n" -#: .././repair/dinode.c:2475 -msgid " would reset version number\n" -msgstr " numer wersji zostałby przestawiony\n" +#: .././db/dquot.c:37 +msgid "[projid|gid|uid]" +msgstr "[projid|gid|uid]" -#: .././repair/dinode.c:2485 -#, c-format -msgid "bad (negative) size % on inode %\n" -msgstr "błędny (ujemny) rozmiar % w i-węźle %\n" +#: .././db/dquot.c:38 +msgid "set current address to project, group or user quota block" +msgstr "ustawienie bieżącego adresu na blok limitu projektu, grupy lub użytkownika" -#: .././repair/dinode.c:2518 -#, c-format -msgid "imap claims a free inode % is in use, " -msgstr "imap odwołuje się do wolnego bloku %, który jest w użyciu, " +#: .././db/dquot.c:127 +msgid "bad option for dquot command\n" +msgstr "błędna opcja dla polecenia dquot\n" -#: .././repair/dinode.c:2520 -msgid "correcting imap and clearing inode\n" -msgstr "poprawiono imap i wyczyszczono i-węzeł\n" +#: .././db/dquot.c:131 +msgid "project" +msgstr "projekt" -#: .././repair/dinode.c:2524 -msgid "would correct imap and clear inode\n" -msgstr "poprawiono by imap i wyczyszczono by i-węzeł\n" +#: .././db/dquot.c:131 +msgid "group" +msgstr "grupę" -#: .././repair/dinode.c:2541 -#, c-format -msgid "bad inode format in inode %\n" -msgstr "błędny format i-węzła w i-węźle %\n" +#: .././db/dquot.c:131 +msgid "user" +msgstr "użytkownika" -#: .././repair/dinode.c:2557 +#: .././db/dquot.c:133 #, c-format -msgid "Bad flags set in inode %\n" -msgstr "Błędne flagi ustawione w i-węźle %\n" +msgid "dquot command requires one %s id argument\n" +msgstr "polecenie dquot wymaga jednego argumentu identyfikującego %s\n" -#: .././repair/dinode.c:2568 +#: .././db/dquot.c:143 #, c-format -msgid "inode % has RT flag set but there is no RT device\n" -msgstr "i-węzeł % ma ustawioną flagę RT, ale nie ma urządzenia RT\n" +msgid "no %s quota inode present\n" +msgstr "i-węzeł limitów na %s nie jest dostępny\n" -#: .././repair/dinode.c:2580 +#: .././db/dquot.c:148 #, c-format -msgid "inode % not rt bitmap\n" -msgstr "i-węzeł % nie jest bitmapą rt\n" +msgid "bad %s id for dquot %s\n" +msgstr "błędna liczba identyfikująca %s dla dquot %s\n" -#: .././repair/dinode.c:2594 +#: .././db/dquot.c:160 #, c-format -msgid "directory flags set on non-directory inode %\n" -msgstr "flagi katalogu ustawione dla nie będącego katalogiem i-węzła %\n" +msgid "no %s quota data for id %d\n" +msgstr "brak danych limitów na %s dla id %d\n" -#: .././repair/dinode.c:2608 -#, c-format -msgid "file flags set on non-file inode %\n" -msgstr "flagi pliku ustawione dla nie będącego plikiem i-węzła %\n" +#: .././db/echo.c:27 +msgid "[args]..." +msgstr "[argumenty]..." -#: .././repair/dinode.c:2617 -msgid ", fixing bad flags.\n" -msgstr ", poprawiono błędne flagi.\n" +#: .././db/echo.c:28 +msgid "echo arguments" +msgstr "wypisanie argumentów" -#: .././repair/dinode.c:2621 -msgid ", would fix bad flags.\n" -msgstr ", poprawionoby błędne flagi.\n" +#: .././db/faddr.c:40 .././db/faddr.c:63 +msgid "no current allocation group, cannot set new addr\n" +msgstr "brak bieżącej grupy alokacji, nie można ustawić nowego adresu\n" -#: .././repair/dinode.c:2672 -#, c-format -msgid "bad inode type %#o inode %\n" -msgstr "błędny typ i-węzła %#o w i-węźle %\n" +#: .././db/faddr.c:45 .././db/faddr.c:117 .././db/faddr.c:148 +#: .././db/faddr.c:180 .././db/faddr.c:202 .././db/faddr.c:232 +#: .././db/faddr.c:262 .././db/faddr.c:316 .././db/faddr.c:335 +msgid "null block number, cannot set new addr\n" +msgstr "pusty numer bloku, nie można ustawić nowego adresu\n" -#: .././repair/dinode.c:2696 -#, c-format -msgid "bad non-zero extent size %u for non-realtime/extsize inode %, " -msgstr "błędny niezerowy rozmiar ekstentu %u dla extsize i-węzła nie-realtime %, " +#: .././db/faddr.c:68 .././db/faddr.c:353 .././db/faddr.c:371 +#: .././db/faddr.c:389 +msgid "null inode number, cannot set new addr\n" +msgstr "pusty numer i-węzła, nie można ustawić nowego adresu\n" -#: .././repair/dinode.c:2699 -msgid "resetting to zero\n" -msgstr "przestawiono na zero\n" +#: .././db/faddr.c:88 +msgid "null attribute block number, cannot set new addr\n" +msgstr "pusty number bloku atrybutów, nie można ustawić nowego adresu\n" -#: .././repair/dinode.c:2703 -msgid "would reset to zero\n" -msgstr "zostałby przestawiony na zero\n" +#: .././db/faddr.c:94 +msgid "attribute block is unmapped\n" +msgstr "blok atrybutów jest nieodwzorowany\n" + +#: .././db/faddr.c:123 .././db/faddr.c:155 .././db/faddr.c:208 +#: .././db/faddr.c:239 +msgid "file block is unmapped\n" +msgstr "blok pliku jest nieodwzorowany\n" + +#: .././db/faddr.c:285 +msgid "null directory block number, cannot set new addr\n" +msgstr "pusty numer bloku katalogu, nie można ustawić nowego adresu\n" + +#: .././db/faddr.c:292 +msgid "directory block is unmapped\n" +msgstr "blok katalogu jest nieodwzorowany\n" -#: .././repair/dinode.c:2759 +#: .././db/flist.c:149 #, c-format -msgid "problem with directory contents in inode %\n" -msgstr "problem z zawartością katalogu w i-węźle %\n" +msgid "field %s not found\n" +msgstr "nie znaleziono pola %s\n" -#: .././repair/dinode.c:2767 +#: .././db/flist.c:159 #, c-format -msgid "problem with symbolic link in inode %\n" -msgstr "problem z dowiązaniem symbolicznym w i-węźle %\n" +msgid "no elements in %s\n" +msgstr "brak elementów w %s\n" -#: .././repair/dinode.c:2862 +#: .././db/flist.c:165 #, c-format -msgid "processing inode %d/%d\n" -msgstr "analiza i-węzła %d/%d\n" +msgid "indices %d-%d for field %s out of range %d-%d\n" +msgstr "indeksy %d-%d dla pola %s są poza zakresem %d-%d\n" -#: .././repair/sb.c:100 -msgid "" -"\n" -"attempting to find secondary superblock...\n" -msgstr "" -"\n" -"próba odnalezienia zapasowego superbloku...\n" +#: .././db/flist.c:173 +#, c-format +msgid "index %d for field %s out of range %d-%d\n" +msgstr "indeks %d dla pola %s jest poza zakresem %d-%d\n" -#: .././repair/sb.c:105 -msgid "error finding secondary superblock -- failed to memalign buffer\n" -msgstr "błąd podczas szukania zapasowego superbloku - nie udało się memalign bufora\n" +#: .././db/flist.c:187 +#, c-format +msgid "field %s is not an array\n" +msgstr "pole %s nie jest tablicą\n" -#: .././repair/sb.c:142 -msgid "found candidate secondary superblock...\n" -msgstr "znaleziono potencjalny zapasowy superblok...\n" +#: .././db/flist.c:200 +#, c-format +msgid "field %s has no subfields\n" +msgstr "pole %s nie ma podpól\n" -#: .././repair/sb.c:154 -msgid "verified secondary superblock...\n" -msgstr "sprawdzono zapasowy superblok...\n" - -#: .././repair/sb.c:159 -msgid "unable to verify superblock, continuing...\n" -msgstr "nie udało się sprawdzić superbloku, kontynuacja...\n" - -#: .././repair/sb.c:457 -msgid "failed to memalign superblock buffer\n" -msgstr "nie udało się wykonać memalign dla bufora superbloku\n" - -#: .././repair/sb.c:464 -msgid "couldn't seek to offset 0 in filesystem\n" -msgstr "nie udało się wykonać seek na offset 0 w systemie plików\n" - -#: .././repair/sb.c:472 -msgid "primary superblock write failed!\n" -msgstr "zapis głównego superbloku nie powiódł się!\n" - -#: .././repair/sb.c:490 +#: .././db/flist.c:220 #, c-format -msgid "error reading superblock %u -- failed to memalign buffer\n" -msgstr "błąd podczas odczytu superbloku %u - nie udało się wykonać memalign dla bufora\n" +msgid "fl@%p:\n" +msgstr "fl@%p:\n" -#: .././repair/sb.c:500 +#: .././db/flist.c:221 #, c-format -msgid "error reading superblock %u -- seek to offset % failed\n" -msgstr "błąd podczas odczytu superbloku %u - seek na offset % nie powiódł się\n" +msgid "\tname=%s, fld=%p, child=%p, sibling=%p\n" +msgstr "\tnazwa=%s, fld=%p, child=%p, sibling=%p\n" -#: .././repair/sb.c:508 +#: .././db/flist.c:223 #, c-format -msgid "superblock read failed, offset %, size %d, ag %u, rval %d\n" -msgstr "odczyt superbloku nie powiódł się, offset %, rozmiar %d, ag %u, rval %d\n" - -#: .././repair/sb.c:554 -msgid "couldn't malloc geometry structure\n" -msgstr "nie udało się przydzielić struktury geometrii\n" - -#: .././repair/sb.c:706 -msgid "calloc failed in verify_set_primary_sb\n" -msgstr "calloc nie powiodło się w verify_set_primary_sb\n" +msgid "\tlow=%d, high=%d, flags=%d (%s%s), offset=%d\n" +msgstr "\tlow=%d, high=%d, flagi=%d (%s%s), offset=%d\n" -#: .././repair/sb.c:777 -msgid "" -"Only two AGs detected and they do not match - cannot validate filesystem geometry.\n" -"Use the -o force_geometry option to proceed.\n" -msgstr "" -"Wykryto tylko dwie AG i nie zgadzają się - nie można sprawdzić poprawności geometrii systemu plików.\n" -"Proszę użyć opcji -o force_geometry, aby kontynuować.\n" +#: .././db/flist.c:225 +msgid "oklow " +msgstr "oklow " -#: .././repair/sb.c:793 -msgid "" -"Only one AG detected - cannot validate filesystem geometry.\n" -"Use the -o force_geometry option to proceed.\n" -msgstr "" -"Wykryto tylko dwie AG - nie można sprawdzić poprawności geometrii systemu plików.\n" -"Proszę użyć opcji -o force_geometry, aby kontynuować.\n" +#: .././db/flist.c:226 +msgid "okhigh" +msgstr "okhigh" -#: .././repair/sb.c:808 -msgid "Not enough matching superblocks - cannot proceed.\n" -msgstr "Za mało pasujących superbloków - nie można kontynuować.\n" +#: .././db/flist.c:227 +#, c-format +msgid "\tfld->name=%s, fld->ftyp=%d (%s)\n" +msgstr "\tfld->name=%s, fld->ftyp=%d (%s)\n" -#: .././repair/sb.c:823 -msgid "could not read superblock\n" -msgstr "nie udało się odczytać superbloku\n" +#: .././db/flist.c:230 +#, c-format +msgid "\tfld->flags=%d (%s%s%s%s%s)\n" +msgstr "\tfld->flags=%d (%s%s%s%s%s)\n" -#: .././repair/phase3.c:45 +#: .././db/flist.c:322 #, c-format -msgid "cannot read agi block % for ag %u\n" -msgstr "nie można odczytać bloku agi % dla ag %u\n" +msgid "bad syntax in field name %s\n" +msgstr "błędna składnia w nazwie pola %s\n" -#: .././repair/phase3.c:127 -msgid "Phase 3 - for each AG...\n" -msgstr "Faza 3 - dla każdej AG...\n" +#: .././db/flist.c:378 +#, c-format +msgid "missing closing quote %s\n" +msgstr "brak cudzysłowu zamykającego %s\n" -#: .././repair/phase3.c:129 -msgid " - scan and clear agi unlinked lists...\n" -msgstr " - przeszukiwanie i czyszczenie odłączonych list agi...\n" +#: .././db/flist.c:395 +#, c-format +msgid "bad character in field %s\n" +msgstr "błędny znak w polu %s\n" -#: .././repair/phase3.c:131 -msgid " - scan (but don't clear) agi unlinked lists...\n" -msgstr " - przeszukiwanie (ale nie czyszczenie) odłączonych list agi...\n" +#: .././db/fprint.c:99 +msgid "null" +msgstr "nic" -#: .././repair/phase3.c:151 -msgid " - process known inodes and perform inode discovery...\n" -msgstr " - przetwarzanie znanych i-węzłów i rozpoznawanie i-węzłów...\n" +#: .././db/frag.c:173 +#, c-format +msgid "actual %llu, ideal %llu, fragmentation factor %.2f%%\n" +msgstr "obecnie %llu, idealnie %llu, współczynnik fragmentacji %.2f%%\n" -#: .././repair/phase3.c:162 -msgid " - process newly discovered inodes...\n" -msgstr " - przetwarzanie nowo rozpoznanych i-węzłów...\n" +#: .././db/frag.c:214 +msgid "bad option for frag command\n" +msgstr "błędna opcja dla polecenia frag\n" -#: .././repair/scan.c:90 .././repair/scan.c:135 +#: .././db/frag.c:350 #, c-format -msgid "can't read btree block %d/%d\n" -msgstr "nie można odczytać bloku b-drzewa %d/%d\n" +msgid "inode %lld actual %lld ideal %lld\n" +msgstr "i-węzeł %lld obecnie %lld idealnie %lld\n" -#: .././repair/scan.c:197 +#: .././db/frag.c:444 .././db/frag.c:454 #, c-format -msgid "bad magic # %#x in inode % (%s fork) bmbt block %\n" -msgstr "błędna liczba magiczna %#x w i-węźle % (gałąź %s) blok bmbt %\n" +msgid "invalid numrecs (%u) in %s block\n" +msgstr "błędne numrecs (%u) w bloku %s\n" -#: .././repair/scan.c:203 +#: .././db/freesp.c:110 #, c-format -msgid "expected level %d got %d in inode %, (%s fork) bmbt block %\n" -msgstr "oczekiwano poziomu %d, a uzyskano %d w i-węźle %, (gałęzi %s) blok bmbt %\n" +msgid "total free extents %lld\n" +msgstr "razem wolnych ekstentów: %lld\n" -#: .././repair/scan.c:223 +#: .././db/freesp.c:111 #, c-format -msgid "" -"bad fwd (right) sibling pointer (saw % parent block says %)\n" -"\tin inode % (%s fork) bmap btree block %\n" -msgstr "" -"błędny wskaźnik w przód (prawy) (widziano %, blok nadrzędny mówi %)\n" -"\tw i-węźle % (gałęzi %s) bloku bmap btree %\n" +msgid "total free blocks %lld\n" +msgstr "razem wolnych bloków: %lld\n" -#: .././repair/scan.c:233 +#: .././db/freesp.c:112 #, c-format -msgid "" -"bad back (left) sibling pointer (saw %llu parent block says %)\n" -"\tin inode % (%s fork) bmap btree block %\n" -msgstr "" -"błędny wskaźnik wstecz (lewy) (widziano %llu, blok nadrzędny mówi %)\n" -"\tw i-węźle % (gałęzi %s) bloku bmap btree %\n" +msgid "average free extent size %g\n" +msgstr "średni rozmiar wolnego ekstentu: %g\n" -#: .././repair/scan.c:248 -#, c-format -msgid "" -"bad back (left) sibling pointer (saw %llu should be NULL (0))\n" -"\tin inode % (%s fork) bmap btree block %\n" -msgstr "" -"błędny wskaźnik wstecz (lewy) (widziano %llu, powinien być NULL (0))\n" -"\tw i-węźle % (gałęzi %s) bloku bmap btree %\n" +#: .././db/freesp.c:203 +msgid "freesp arguments: [-bcds] [-a agno] [-e binsize] [-h h1]... [-m binmult]\n" +msgstr "argumenty freesp: [-bcds] [-a agno] [-e binsize] [-h h1]... [-m binmult]\n" -#: .././repair/scan.c:289 -#, c-format -msgid "inode 0x%bmap block 0x% claimed, state is %d\n" -msgstr "i-węzeł 0x% blok bmap 0x% przypisany, stan to %d\n" +#: .././db/freesp.c:427 +msgid "from" +msgstr "od" -#: .././repair/scan.c:296 -#, c-format -msgid "inode 0x% bmap block 0x% claimed, state is %d\n" -msgstr "i-węzeł 0x% blok bmap 0x% przypisany, stan to %d\n" +#: .././db/freesp.c:427 +msgid "to" +msgstr "do" -#: .././repair/scan.c:311 -#, c-format -msgid "bad state %d, inode % bmap block 0x%\n" -msgstr "błędny stan %d, i-węzeł % blok bmap 0x%\n" +#: .././db/freesp.c:427 .././repair/progress.c:26 +msgid "extents" +msgstr "ekstentów" -#: .././repair/scan.c:338 .././repair/scan.c:389 -#, c-format -msgid "inode % bad # of bmap records (%u, min - %u, max - %u)\n" -msgstr "błędna liczba rekordów bmap w i-węźle % (%u, minimum - %u, maksimum - %u)\n" +#: .././db/freesp.c:427 .././repair/progress.c:18 +msgid "blocks" +msgstr "bloków" -#: .././repair/scan.c:368 -#, c-format -msgid "out-of-order bmap key (file offset) in inode %, %s fork, fsbno %\n" -msgstr "uszkodzony klucz bmap (offset pliku) w i-węźle %, gałęzi %s, fsbno %\n" +#: .././db/freesp.c:427 +msgid "pct" +msgstr "proc." -#: .././repair/scan.c:433 -#, c-format +#: .././db/hash.c:30 +msgid "string" +msgstr "łańcuch" + +#: .././db/hash.c:31 +msgid "calculate hash value" +msgstr "obliczenie wartości skrótu" + +#: .././db/hash.c:37 msgid "" -"correcting bt key (was %llu, now %) in inode %\n" -"\t\t%s fork, btree block %\n" +"\n" +" 'hash' prints out the calculated hash value for a string using the\n" +"directory/attribute code hash function.\n" +"\n" +" Usage: \"hash \"\n" +"\n" msgstr "" -"poprawiono klucz bt (było %llu, jest %) w i-węźle %\n" -"\t\tgałąź %s, blok b-drzewa %\n" +"\n" +" 'hash' wypisuje wartość skrótu dla łańcucha obliczoną przy użyciu funkcji\n" +" haszującej dla katalogów/atrybutów.\n" +"\n" +" Składnia: \"hash <łańcuch>\"\n" +"\n" + +#: .././db/help.c:30 .././db/io.c:48 .././libxcmd/help.c:92 +msgid "[command]" +msgstr "[polecenie]" -#: .././repair/scan.c:445 +#: .././db/help.c:31 .././libxcmd/help.c:93 +msgid "help for one or all commands" +msgstr "opis dla jednego lub wszystkich poleceń" + +#: .././db/help.c:40 .././libxcmd/help.c:33 #, c-format msgid "" -"bad btree key (is %llu, should be %) in inode %\n" -"\t\t%s fork, btree block %\n" +"\n" +"Use 'help commandname' for extended help.\n" msgstr "" -"błędny klucz b-drzewa (jest %llu, powinno być %) w i-węźle %\n" -"\t\tgałąź %s, blok b-drzewa %\n" +"\n" +"Rozszerzony opis można uzyskać przez 'help nazwa_polecenia'.\n" + +#: .././db/help.c:89 +#, c-format +msgid "(or %s) " +msgstr "(lub %s) " -#: .././repair/scan.c:463 +#: .././db/init.c:47 #, c-format +msgid "Usage: %s [-ifFrxV] [-p prog] [-l logdev] [-c cmd]... device\n" +msgstr "Składnia: %s [-ifFrxV] [-p prog] [-l urz-log] [-c polecenie]... urządzenie\n" + +#: .././db/init.c:114 msgid "" -"bad fwd (right) sibling pointer (saw % should be NULLDFSBNO)\n" -"\tin inode % (%s fork) bmap btree block %\n" +"\n" +"fatal error -- couldn't initialize XFS library\n" msgstr "" -"błędny wskaźnik w przód (prawy) (widziano %, powinien być NULLDFSBNO)\n" -"\tw i-węźle % (gałęzi %s) bloku bmap btree %\n" +"\n" +"błąd krytyczny - nie udało się zainicjować biblioteki XFS\n" -#: .././repair/scan.c:537 +#: .././db/init.c:129 #, c-format -msgid "bad magic # %#x in bt%s block %d/%d\n" -msgstr "błędna liczba magiczna %#x w bloku bt%s %d/%d\n" +msgid "%s: %s is invalid (cannot read first 512 bytes)\n" +msgstr "%s: %s jest nieprawidłowy (nie można odczytać pierwszych 512 bajtów)\n" -#: .././repair/scan.c:555 +#: .././db/init.c:141 #, c-format -msgid "expected level %d got %d in bt%s block %d/%d\n" -msgstr "oczekiwano poziomu %d, a uzyskano %d w bloku bt%s %d/%d\n" +msgid "%s: %s is not a valid XFS filesystem (unexpected SB magic number 0x%08x)\n" +msgstr "%s: %s nie jest poprawnym systemem plików XFS (nieoczekiwana liczba magiczna SB 0x%08x)\n" -#: .././repair/scan.c:569 +#: .././db/init.c:144 #, c-format -msgid "%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n" -msgstr "blok b-drzewa wolnego miejsca %s przypisany (stan %d), agno %d, bno %d, podejrzany %d\n" +msgid "Use -F to force a read attempt.\n" +msgstr "Opcja -F pozwala wymusić próbę odczytu.\n" -#: .././repair/scan.c:589 .././repair/scan.c:688 +#: .././db/init.c:153 #, c-format -msgid "bad btree nrecs (%u, min=%u, max=%u) in bt%s block %u/%u\n" -msgstr "błędna liczba rekordów b-drzewa (%u, min=%u, max=%u) w bt%s, blok %u/%u\n" +msgid "%s: device %s unusable (not an XFS filesystem?)\n" +msgstr "%s: urządzenie %s nie nadaje się do użycia (to nie jest system plików XFS?)\n" -#: .././repair/scan.c:607 +#: .././db/init.c:167 #, c-format -msgid "invalid start block %u in record %u of %s btree block %u/%u\n" -msgstr "błędny blok początkowy %u w rekordzie %u bloku b-drzewa %s %u/%u\n" +msgid "%s: cannot init perag data (%d). Continuing anyway.\n" +msgstr "%s: nie można zainicjować danych perag (%d). Kontynuacja mimo wszystko.\n" -#: .././repair/scan.c:613 +#: .././db/inode.c:412 #, c-format -msgid "invalid length %u in record %u of %s btree block %u/%u\n" -msgstr "błędna długość %u w rekordzie %u bloku b-drzewa %s %u/%u\n" +msgid "bad value for inode number %s\n" +msgstr "błędna wartość numeru i-węzła %s\n" -#: .././repair/scan.c:621 .././db/check.c:4315 +#: .././db/inode.c:419 #, c-format -msgid "out-of-order bno btree record %d (%u %u) block %u/%u\n" -msgstr "rekord b-drzewa bno poza kolejnością: %d (%u %u), blok %u/%u\n" +msgid "current inode number is %lld\n" +msgstr "numer bieżącego i-węzła to %lld\n" -#: .././repair/scan.c:633 .././db/check.c:4392 +#: .././db/inode.c:654 #, c-format -msgid "out-of-order cnt btree record %d (%u %u) block %u/%u\n" -msgstr "rekord b-drzewa cnt poza kolejnością: %d (%u %u), blok %u/%u\n" +msgid "bad inode number %lld\n" +msgstr "błędny numer i-węzła %lld\n" -#: .././repair/scan.c:658 -#, c-format -msgid "block (%d,%d-%d) multiply claimed by %s space tree, state - %d\n" -msgstr "blok (%d,%d-%d) wielokrotnie przypisany do drzewa miejsca %s, stan - %d\n" +#: .././db/input.c:43 +msgid "source-file" +msgstr "plik-źródłowy" -#: .././repair/scan.c:755 -#, c-format -msgid "badly aligned inode rec (starting inode = %)\n" -msgstr "błędnie wyrównany rekord i-węzła (początkowy i-węzeł = %)\n" +#: .././db/input.c:44 +msgid "get commands from source-file" +msgstr "odczyt poleceń z pliku-źródłowego" -#: .././repair/scan.c:771 +#: .././db/input.c:320 #, c-format -msgid "bad starting inode # (% (0x%x 0x%x)) in ino rec, skipping rec\n" -msgstr "błędny numer początkowego i-węzła (% (0x%x 0x%x)) w rekordzie i-węzła, pominięto rekord\n" +msgid "can't open %s\n" +msgstr "nie można otworzyć %s\n" -#: .././repair/scan.c:779 -#, c-format -msgid "bad ending inode # (% (0x%x 0x%zx)) in ino rec, skipping rec\n" -msgstr "błędny numer końcowego i-węzła (% (0x%x 0x%zx)) w rekordzie i-węzła, pominięto rekord\n" +#: .././db/io.c:46 +msgid "pop location from the stack" +msgstr "odtworzenie pozycji ze stosu" -#: .././repair/scan.c:804 -#, c-format -msgid "inode chunk claims used block, inobt block - agno %d, bno %d, inopb %d\n" -msgstr "część i-węzła odwołuje się do używanego bloku, blok inobt - agno %d, bno %d, inopb %d\n" +#: .././db/io.c:49 +msgid "push location to the stack" +msgstr "zapisanie pozycji na stos" -#: .././repair/scan.c:826 -#, c-format -msgid "inode rec for ino % (%d/%d) overlaps existing rec (start %d/%d)\n" -msgstr "rekord i-węzła dla i-węzła % (%d/%d) nachodzi na istniejący rekord (początek %d/%d)\n" +#: .././db/io.c:52 +msgid "view the location stack" +msgstr "podejrzenie stosu pozycji" -#: .././repair/scan.c:873 -#, c-format -msgid "ir_freecount/free mismatch, inode chunk %d/%u, freecount %d nfree %d\n" -msgstr "niezgodność ir_freecount/free, porcja i-węzłów %d/%u, freecount %d nfree %d\n" +#: .././db/io.c:55 +msgid "move forward to next entry in the position ring" +msgstr "przejście na następną pozycję w kręgu" -#: .././repair/scan.c:919 -#, c-format -msgid "bad magic # %#x in inobt block %d/%d\n" -msgstr "błędna liczba magiczna %#x w bloku inobt %d/%d\n" +#: .././db/io.c:58 +msgid "move to the previous location in the position ring" +msgstr "przejście na poprzednią pozycję w kręgu" -#: .././repair/scan.c:927 -#, c-format -msgid "expected level %d got %d in inobt block %d/%d\n" -msgstr "oczekiwano poziomu %d, a uzyskano %d w bloku inobt %d/%d\n" +#: .././db/io.c:61 +msgid "show position ring or move to a specific entry" +msgstr "pokazanie kręgu pozycji lub przejście do określonego wpisu" -#: .././repair/scan.c:949 +#: .././db/io.c:91 #, c-format -msgid "inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n" -msgstr "blok b-drzewa i-węzłów przypisany (stan %d), agno %d, bno %d, podejrzany %d\n" +msgid "can't set block offset to %d\n" +msgstr "nie można ustawić offsetu bloku na %d\n" -#: .././repair/scan.c:972 -#, c-format -msgid "dubious inode btree block header %d/%d\n" -msgstr "wątpliwy nagłówek bloku b-drzewa i-węzłów %d/%d\n" +#: .././db/io.c:104 +msgid "can't pop anything from I/O stack\n" +msgstr "nie można pobrać nic ze stosu we/wy\n" -#: .././repair/scan.c:1065 -#, c-format -msgid "can't read agfl block for ag %d\n" -msgstr "nie można odczytać bloku agfl dla ag %d\n" +#: .././db/io.c:138 +msgid "" +"\n" +" Changes the address and data type to the first entry on the stack.\n" +"\n" +msgstr "" +"\n" +" Zmiana adresu i typu danych na pierwszy wpis ze stosu.\n" +"\n" -#: .././repair/scan.c:1076 +#: .././db/io.c:152 #, c-format -msgid "bad agbno %u in agfl, agno %d\n" -msgstr "błędne agbno %u w agfl, agno %d\n" +msgid "\tbyte offset %lld, length %d\n" +msgstr "\toffset w bajtach %lld, długość %d\n" -#: .././repair/scan.c:1085 +#: .././db/io.c:153 #, c-format -msgid "freeblk count %d != flcount %d in ag %d\n" -msgstr "liczba freeblk %d != flcount %d w ag %d\n" +msgid "\tbuffer block %lld (fsbno %lld), %d bb%s\n" +msgstr "\tblok bufora %lld (fsbno %lld), %d bb%s\n" -#: .././repair/scan.c:1107 +#: .././db/io.c:157 .././db/io.c:508 #, c-format -msgid "bad agbno %u for btbno root, agno %d\n" -msgstr "błędne agbno %u dla głównego btbno, agno %d\n" +msgid "\tblock map" +msgstr "\tmapa bloków" -#: .././repair/scan.c:1116 +#: .././db/io.c:163 #, c-format -msgid "bad agbno %u for btbcnt root, agno %d\n" -msgstr "błędne agbno %u dla głównego btbcnt, agno %d\n" +msgid "\tinode %lld, dir inode %lld, type %s\n" +msgstr "\ti-węzeł %lld, i-węzeł katalogu %lld, typ %s\n" -#: .././repair/scan.c:1121 .././db/check.c:4033 +#: .././db/io.c:164 .././growfs/xfs_growfs.c:83 .././logprint/log_misc.c:151 +#: .././mkfs/xfs_mkfs.c:2126 #, c-format -msgid "agf_freeblks %u, counted %u in ag %u\n" -msgstr "agf_freeblks %u, naliczono %u w ag %u\n" +msgid "none" +msgstr "brak" -#: .././repair/scan.c:1126 .././db/check.c:4040 -#, c-format -msgid "agf_longest %u, counted %u in ag %u\n" -msgstr "agf_longest %u, naliczono %u w ag %u\n" +#: .././db/io.c:174 +msgid "no entries in location ring.\n" +msgstr "brak wpisów w kręgu pozycji.\n" -#: .././repair/scan.c:1132 -#, c-format -msgid "agf_btreeblks %u, counted % in ag %u\n" -msgstr "agf_btreeblks %u, naliczono % w ag %u\n" +#: .././db/io.c:178 +msgid " type bblock bblen fsbno inode\n" +msgstr " typ bblok bblen fsbno i-węzeł\n" -#: .././repair/scan.c:1151 +#: .././db/io.c:232 #, c-format -msgid "bad agbno %u for inobt root, agno %d\n" -msgstr "błędne agbno %u dla głównego inobt, agno %d\n" +msgid "no such command %s\n" +msgstr "nieznane polecenie %s\n" -#: .././repair/scan.c:1156 .././db/check.c:4056 +#: .././db/io.c:236 #, c-format -msgid "agi_count %u, counted %u in ag %u\n" -msgstr "agi_count %u, naliczono %u w ag %u\n" +msgid "no push form allowed for %s\n" +msgstr "forma push niedozwolona dla %s\n" -#: .././repair/scan.c:1161 .././db/check.c:4063 -#, c-format -msgid "agi_freecount %u, counted %u in ag %u\n" -msgstr "agi_freecount %u, naliczono %u w ag %u\n" +#: .././db/io.c:260 +msgid "" +"\n" +" Allows you to push the current address and data type on the stack for\n" +" later return. 'push' also accepts an additional command to execute after\n" +" storing the current address (ex: 'push a rootino' from the superblock).\n" +"\n" +msgstr "" +"\n" +" Pozwala zapisać bieżący adres i typ danych na stos w celu późniejszego\n" +" powrotu. 'push' akceptuje także dodatkowe polecenie do wykonania po zapisaniu\n" +" bieżącego adresu (np. 'push a rootino' z superbloku).\n" +"\n" -#: .././repair/scan.c:1170 -#, c-format -msgid "agi unlinked bucket %d is %u in ag %u (inode=%)\n" -msgstr "niedowiązany kubełek agi %d to %u w ag %u (i-węzeł=%)\n" +#: .././db/io.c:276 .././db/io.c:316 +msgid "ring is empty\n" +msgstr "krąg jest pusty\n" -#: .././repair/scan.c:1201 -#, c-format -msgid "can't get root superblock for ag %d\n" -msgstr "nie można uzyskać głównego superbloku dla ag %d\n" +#: .././db/io.c:280 +msgid "no further entries\n" +msgstr "brak dalszych wpisów\n" -#: .././repair/scan.c:1207 -msgid "can't allocate memory for superblock\n" -msgstr "nie można przydzielić pamięci dla superbloku\n" +#: .././db/io.c:299 +msgid "" +"\n" +" The 'forward' ('f') command moves to the next location in the position\n" +" ring, updating the current position and data type. If the current location\n" +" is the top entry in the ring, then the 'forward' command will have\n" +" no effect.\n" +"\n" +msgstr "" +"\n" +" Polecenie 'forward' ('f') przechodzi do następnej pozycji w kręgu,\n" +" uaktualniając bieżącą pozycję i typ danych. Jeśli bieżąca pozycja\n" +" jest szczytowym wpisem w kręgu, polecenie nie przyniesie efektu.\n" +"\n" -#: .././repair/scan.c:1217 -#, c-format -msgid "can't read agf block for ag %d\n" -msgstr "nie można odczytać bloku agf dla ag %d\n" +#: .././db/io.c:320 +msgid "no previous entries\n" +msgstr "brak poprzednich wpisów\n" -#: .././repair/scan.c:1228 -#, c-format -msgid "can't read agi block for ag %d\n" -msgstr "nie można odczytać bloku agi dla ag %d\n" +#: .././db/io.c:339 +msgid "" +"\n" +" The 'back' ('b') command moves to the previous location in the position\n" +" ring, updating the current position and data type. If the current location\n" +" is the last entry in the ring, then the 'back' command will have no effect.\n" +"\n" +msgstr "" +"\n" +" Polecenie 'back' ('b') przechodzi do poprzedniej pozycji w kręgu,\n" +" uaktualniając bieżącą pozycję i typ danych. Jeśli bieżąca pozycja\n" +" jest ostatnim wpisem w kręgu, polecenie nie przyniesie efektu.\n" +"\n" -#: .././repair/scan.c:1252 +#: .././db/io.c:362 #, c-format -msgid "reset bad sb for ag %d\n" -msgstr "przestawiono błędny superbloku dla ag %d\n" +msgid "invalid entry: %d\n" +msgstr "błędny wpis: %d\n" -#: .././repair/scan.c:1255 +#: .././db/io.c:381 #, c-format -msgid "would reset bad sb for ag %d\n" -msgstr "błędny superblok dla ag %d zostałby przestawiony\n" +msgid "" +"\n" +" The position ring automatically keeps track of each disk location and\n" +" structure type for each change of position you make during your xfs_db\n" +" session. The last %d most recent entries are kept in the ring.\n" +"\n" +" To display the current list of ring entries type 'ring' by itself on\n" +" the command line. The entry highlighted by an asterisk ('*') is the\n" +" current entry.\n" +"\n" +" To move to another entry in the ring type 'ring ' where is\n" +" your desired entry from the ring position list.\n" +"\n" +" You may also use the 'forward' ('f') or 'back' ('b') commands to move\n" +" to the previous or next entry in the ring, respectively.\n" +"\n" +" Note: Unlike the 'stack', 'push' and 'pop' commands, the ring tracks your\n" +" location implicitly. Use the 'push' and 'pop' commands if you wish to\n" +" store a specific location explicitly for later return.\n" +"\n" +msgstr "" +"\n" +" Krąg pozycji automatycznie śledzi każde położenie na dysku i typ struktury\n" +" dla każdej zmiany pozycji wykonywanej podczas sesji xfs_db. Ostatenie %d\n" +" pozycji jest trzymane w kręgu.\n" +"\n" +" Aby wyświetlić bieżącą listę wpisów w kręgu należy napisać w linii poleceń\n" +" po prostu 'ring'. Wpis oznaczony gwiazdką ('*') jest wpisem bieżącym.\n" +"\n" +" Aby przejść do innego wpisu w kręgu, należy wpisać 'ring ', gdzie\n" +" jest numerem pożądanego wpisu na liście pozycji.\n" +"\n" +" Można także używać poleceń 'forward' ('f') i 'back' ('b'), aby przenieść\n" +" się odpowiednio na poprzedni lub następny wpis w kręgu.\n" +"\n" +" Uwaga: w przeciwieństwie do poleceń 'stack', 'push' i 'pop', krąg śledzi\n" +" pozycje niejawnie. Aby zapisać jawnie dane położenie w celu późniejszego\n" +" powrotu, należy użyć poleceń 'push' i 'pop'.\n" +"\n" -#: .././repair/scan.c:1260 +#: .././db/io.c:434 .././db/io.c:450 #, c-format -msgid "reset bad agf for ag %d\n" -msgstr "przestawiono błędne agf dla ag %d\n" +msgid "write error: %s\n" +msgstr "błąd zapisu: %s\n" -#: .././repair/scan.c:1263 +#: .././db/io.c:440 .././db/io.c:456 #, c-format -msgid "would reset bad agf for ag %d\n" -msgstr "błędne agf dla ag %d zostałoby przestawione\n" +msgid "read error: %s\n" +msgstr "błąd odczytu: %s\n" -#: .././repair/scan.c:1268 -#, c-format -msgid "reset bad agi for ag %d\n" -msgstr "przestawiono błędne agi dla ag %d\n" +#: .././db/io.c:463 +msgid "nothing to write\n" +msgstr "nie ma nic do zapisania\n" -#: .././repair/scan.c:1271 -#, c-format -msgid "would reset bad agi for ag %d\n" -msgstr "błędna agi dla ag %d zostałoby przestawione\n" +#: .././db/io.c:493 +msgid "set_cur no stack element to set\n" +msgstr "set_cur: brak elementu stosu do ustawienia\n" -#: .././repair/scan.c:1281 +#: .././db/io.c:507 #, c-format -msgid "bad uncorrected agheader %d, skipping ag...\n" -msgstr "błędny nie poprawiony agheader %d, pominięto ag...\n" +msgid "xfs_db got a bbmap for %lld\n" +msgstr "xfs_db ma bbmap dla %lld\n" -#: .././repair/scan.c:1340 -msgid "no memory for ag header counts\n" -msgstr "brak pamięci na liczniki nagłówków ag\n" +#: .././db/io.c:583 +msgid "" +"\n" +" The stack is used to explicitly store your location and data type\n" +" for later return. The 'push' operation stores the current address\n" +" and type on the stack, the 'pop' operation returns you to the\n" +" position and datatype of the top entry on the stack.\n" +"\n" +" The 'stack' allows explicit location saves, see 'ring' for implicit\n" +" position tracking.\n" +"\n" +msgstr "" +"\n" +" Stos służy do jawnego zapisania pozycji i typu danych w celu późniejszego\n" +" powrotu. Operacja 'push' zapisuje bieżący adres i typ na stosie, a operacja\n" +" 'pop' odtwarza bieżący adres i typ danych z wierzchu stosu.\n" +"\n" +" Stos ('stack') pozwala na jawne zapisywanie pozycji; domyślnie pozycje są\n" +" śledzone poprzez krąg (p. 'ring').\n" +"\n" -#: .././repair/scan.c:1363 +#: .././db/malloc.c:27 #, c-format -msgid "sb_icount %, counted %\n" -msgstr "sb_icount %, naliczono %\n" +msgid "%s: out of memory\n" +msgstr "%s: brak pamięci\n" -#: .././repair/scan.c:1368 -#, c-format -msgid "sb_ifree %, counted %\n" -msgstr "sb_ifree %, naliczono %\n" +#: .././db/metadump.c:59 +msgid "[-e] [-g] [-m max_extent] [-w] [-o] filename" +msgstr "[-e] [-g] [-m max_extent] [-w] [-o] nazwa-pliku" -#: .././repair/scan.c:1373 -#, c-format -msgid "sb_fdblocks %, counted %\n" -msgstr "sb_fdblocks %, naliczono %\n" - -#: .././repair/incore_ext.c:135 .././repair/incore_ext.c:562 -msgid "couldn't allocate new extent descriptor.\n" -msgstr "nie udało się przydzielić nowego deskryptora ekstentu.\n" - -#: .././repair/incore_ext.c:232 -msgid "duplicate bno extent range\n" -msgstr "powtórzony przedział ekstentów bno\n" - -#: .././repair/incore_ext.c:369 -msgid ": duplicate bno extent range\n" -msgstr ": powtórzony przedział ekstentów bno\n" - -#: .././repair/incore_ext.c:644 .././repair/incore_ext.c:699 -msgid "duplicate extent range\n" -msgstr "powtórzony przedział ekstentów\n" - -#: .././repair/incore_ext.c:752 .././repair/incore_ext.c:756 -msgid "couldn't malloc dup extent tree descriptor table\n" -msgstr "nie udało się przydzielić tablicy deskryptorów drzewa powtórzonych ekstentów\n" - -#: .././repair/incore_ext.c:761 -msgid "couldn't malloc free by-bno extent tree descriptor table\n" -msgstr "nie udało się przydzielić tablicy deskryptorów drzewa wolnych ekstentów wg bno\n" - -#: .././repair/incore_ext.c:766 -msgid "couldn't malloc free by-bcnt extent tree descriptor table\n" -msgstr "nie udało się przydzielić tablicy deskryptorów drzewa wolnych ekstentów wg bcnt\n" - -#: .././repair/incore_ext.c:772 -msgid "couldn't malloc bno extent tree descriptor\n" -msgstr "nie udało się przydzielić deskryptora drzewa ekstentów wg bno\n" - -#: .././repair/incore_ext.c:776 -msgid "couldn't malloc bcnt extent tree descriptor\n" -msgstr "nie udało się przydzielić deskryptora drzewa ekstentów wg bcnt\n" - -#: .././repair/incore_ext.c:787 -msgid "couldn't malloc dup rt extent tree descriptor\n" -msgstr "nie udało się przydzielić deskryptora drzewa powtórzonych ekstentów rt\n" - -#: .././repair/bmap.c:53 +#: .././db/metadump.c:60 +msgid "dump metadata to a file" +msgstr "zrzut metadanych do pliku" + +#: .././db/metadump.c:90 #, c-format msgid "" -"Number of extents requested in blkmap_alloc (%d) overflows 32 bits.\n" -"If this is not a corruption, then you will need a 64 bit system\n" -"to repair this filesystem.\n" +"\n" +" The 'metadump' command dumps the known metadata to a compact file suitable\n" +" for compressing and sending to an XFS maintainer for corruption analysis \n" +" or xfs_repair failures.\n" +"\n" +" Options:\n" +" -e -- Ignore read errors and keep going\n" +" -g -- Display dump progress\n" +" -m -- Specify max extent size in blocks to copy (default = %d blocks)\n" +" -o -- Don't obfuscate names and extended attributes\n" +" -w -- Show warnings of bad metadata information\n" +"\n" msgstr "" -"Liczba ekstentów żądanych w blkmap_alloc (%d) przepełnia 32 bity.\n" -"Jeśli nie jest to efekt uszkodzenia, do naprawy tego systemu plików\n" -"niezbędny jest system 64-bitowy.\n" +"\n" +" Polecenie 'metadump' zrzuca znane metadane do zwięzłego pliku nadającego się\n" +" do skompresowania i wysłania prowadzącym projekt XFS w celu analizy uszkodzeń\n" +" lub błędów xfs_repair.\n" +"\n" +" Opcje:\n" +" -e - ignorowanie błędów odczytu i kontynuowanie\n" +" -g - wyświetlanie postępu\n" +" -m - określenie maksymalnego rozmiaru ekstentu (w blokach) do skopiowania\n" +" (domyślnie %d bloków)\n" +" -o - bez zaciemniania nazw i rozszerzonych atrybutów\n" +" -w - wyświetlanie ostrzeżeń o błędnych metadanych\n" +"\n" -#: .././repair/bmap.c:66 -#, c-format -msgid "malloc failed in blkmap_alloc (%zu bytes)\n" -msgstr "malloc nie powiodło się w blkmap_alloc (%zu bajtów)\n" +#: .././db/output.c:30 +msgid "[stop|start ]" +msgstr "[stop|start ]" -#: .././repair/bmap.c:173 -#, c-format -msgid "blkmap_getn malloc failed (% bytes)\n" -msgstr "malloc w blkmap_getn nie powiodło się (% bajtów)\n" +#: .././db/output.c:31 +msgid "start or stop logging to a file" +msgstr "rozpoczęcie lub zakończenie logowania do pliku" -#: .././repair/bmap.c:253 +#: .././db/output.c:68 #, c-format -msgid "" -"Number of extents requested in blkmap_grow (%d) overflows 32 bits.\n" -"You need a 64 bit system to repair this filesystem.\n" -msgstr "" -"Liczba ekstentów żądanych w blkmap_grow (%d) przepełnia 32 bity.\n" -"Do naprawy tego systemu plików niezbędny jest system 64-bitowy.\n" +msgid "logging to %s\n" +msgstr "logowanie do %s\n" + +#: .././db/output.c:70 .././db/output.c:77 +msgid "no log file\n" +msgstr "brak pliku logu\n" -#: .././repair/bmap.c:261 +#: .././db/output.c:80 #, c-format -msgid "" -"Number of extents requested in blkmap_grow (%d) overflowed the\n" -"maximum number of supported extents (%d).\n" -msgstr "" -"Liczba ekstentów żądanych w blkmap_grow (%d) przepełniła maksymalną\n" -"liczbę obsługiwanych ekstentów (%d).\n" +msgid "already logging to %s\n" +msgstr "już ustawiono logowanie do %s\n" -#: .././repair/bmap.c:269 -msgid "realloc failed in blkmap_grow\n" -msgstr "realloc nie powiodło się w blkmap_grow\n" +#: .././db/output.c:84 +#, c-format +msgid "can't open %s for writing\n" +msgstr "nie można otworzyć %s do zapisu\n" -#: .././repair/attr_repair.c:105 -msgid "entry contains illegal value in attribute named SGI_ACL_FILE or SGI_ACL_DEFAULT\n" -msgstr "wpis zawiera niedozwoloną wartość w atrybucie SGI_ACL_FILE lub SGI_ACL_DEFAULT\n" +#: .././db/output.c:90 +msgid "bad log command, ignored\n" +msgstr "błędne polecenie logowania, zignorowano\n" -#: .././repair/attr_repair.c:127 -msgid "entry contains illegal value in attribute named SGI_MAC_LABEL\n" -msgstr "wpis zawiera niedozwoloną wartość w atrybucie SGI_MAC_LABEL\n" +#: .././db/print.c:41 +msgid "[value]..." +msgstr "[wartość]..." -#: .././repair/attr_repair.c:133 -msgid "entry contains illegal value in attribute named SGI_CAP_FILE\n" -msgstr "wpis zawiera niedozwoloną wartość w atrybucie SGI_CAP_FILE\n" +#: .././db/print.c:42 +msgid "print field values" +msgstr "wypisanie wartości pól" -#: .././repair/attr_repair.c:172 +#: .././db/print.c:79 #, c-format -msgid "there are no attributes in the fork for inode %\n" -msgstr "nie ma atrybutów w gałęzi dla i-węzła %\n" +msgid "no print function for type %s\n" +msgstr "brak funkcji wypisującej dla typu %s\n" -#: .././repair/attr_repair.c:180 -#, c-format -msgid "would junk the attribute fork since count is 0 for inode %\n" -msgstr "gałąź atrybutów zostałaby usunięta ponieważ licznik wynosi 0 dla i-węzła %\n" +#: .././db/print.c:153 +msgid "(empty)\n" +msgstr "(puste)\n" -#: .././repair/attr_repair.c:200 -msgid "zero length name entry in attribute fork," -msgstr "wpis nazwy zerowej długości w gałęzi atrybutów," +#: .././db/print.c:215 +msgid "(empty)" +msgstr "(puste)" -#: .././repair/attr_repair.c:203 .././repair/attr_repair.c:223 -#, c-format -msgid " truncating attributes for inode % to %d\n" -msgstr " ucięto atrybuty dla i-węzła % do %d\n" +#: .././db/print.c:275 +msgid "no arguments allowed\n" +msgstr "argumenty nie są dozwolone\n" -#: .././repair/attr_repair.c:208 .././repair/attr_repair.c:229 -#, c-format -msgid " would truncate attributes for inode % to %d\n" -msgstr " atrybuty dla i-węzła % zostałyby ucięte do %d\n" +#: .././db/quit.c:27 +msgid "exit xfs_db" +msgstr "zakończenie xfs_db" -#: .././repair/attr_repair.c:220 -msgid "name or value attribute lengths are too large,\n" -msgstr "długości nazwy lub wartości atrybutów są zbyt duże,\n" +#: .././db/sb.c:43 +msgid "set current address to sb header" +msgstr "ustawienie bieżącego adresu na nagłówek sb" -#: .././repair/attr_repair.c:242 -msgid "entry contains illegal character in shortform attribute name\n" -msgstr "wpis zawiera niedozwolony znak w nazwie atrybutu krótkiego\n" +#: .././db/sb.c:45 +msgid "[uuid]" +msgstr "[uuid]" -#: .././repair/attr_repair.c:248 -msgid "entry has INCOMPLETE flag on in shortform attribute\n" -msgstr "wpis ma flagę NIEPEŁNY w atrybucie krótkim\n" +#: .././db/sb.c:46 +msgid "write/print FS uuid" +msgstr "zapisanie/wypisanie uuida FS" -#: .././repair/attr_repair.c:265 -#, c-format -msgid "removing attribute entry %d for inode %\n" -msgstr "usunięto wpis atrybutu %d dla i-węzła %\n" +#: .././db/sb.c:48 +msgid "[label]" +msgstr "[etykieta]" -#: .././repair/attr_repair.c:277 -#, c-format -msgid "would remove attribute entry %d for inode %\n" -msgstr "wpis atrybutu %d dla i-węzła % zostałby usunięty\n" +#: .././db/sb.c:49 +msgid "write/print FS label" +msgstr "zapisanie/wypisanie etykiety FS" -#: .././repair/attr_repair.c:292 -#, c-format -msgid "would have corrected attribute entry count in inode % from %d to %d\n" -msgstr "liczba wpisów atrybutów w i-węźle % zostałaby poprawiona z %d na %d\n" +#: .././db/sb.c:51 +msgid "[feature | [vnum fnum]]" +msgstr "[cecha | [vnum fnum]]" -#: .././repair/attr_repair.c:296 -#, c-format -msgid "corrected attribute entry count in inode %, was %d, now %d\n" -msgstr "poprawiono liczbę wpisów atrybutów w i-węźle % - było %d, jest %d\n" +#: .././db/sb.c:52 +msgid "set feature bit(s) in the sb version field" +msgstr "ustawienie bitów cech w polu wersji sb" -#: .././repair/attr_repair.c:307 -#, c-format -msgid "would have corrected attribute totsize in inode % from %d to %d\n" -msgstr "totsize atrybutów w i-węźle % zostałby poprawiony z %d na %d\n" +#: .././db/sb.c:136 +msgid "" +"\n" +" set allocation group superblock\n" +"\n" +" Example:\n" +"\n" +" 'sb 7' - set location to 7th allocation group superblock, set type to 'sb'\n" +"\n" +" Located in the first sector of each allocation group, the superblock\n" +" contains the base information for the filesystem.\n" +" The superblock in allocation group 0 is the primary. The copies in the\n" +" remaining allocation groups only serve as backup for filesystem recovery.\n" +" The icount/ifree/fdblocks/frextents are only updated in superblock 0.\n" +"\n" +msgstr "" +"\n" +" ustawienie superbloku grupy alokacji\n" +"\n" +" Przykład:\n" +"\n" +" 'sb 7' - ustawienie pozycji na superblok 7. grupy alokacji i typu na 'sb'\n" +"\n" +" Położony w 1. sektorze każdej grupy alokacji superblok zawiera podstawowe\n" +" informacje o systemie plików.\n" +" Superblok w grupie alokacji 0 jest główny. Kopie w pozostałych grupach\n" +" alokacji służą tylko jako kopie zapasowe do odtwarzania systemu plików.\n" +" Liczby icount/ifree/fdblocks/frextents są uaktualniane tylko w superbloku 0.\n" +"\n" -#: .././repair/attr_repair.c:312 +#: .././db/sb.c:195 #, c-format -msgid "corrected attribute entry totsize in inode %, was %d, now %d\n" -msgstr "poprawiono totsize wpisu atrybutów w i-węźle % - było %d, jest %d\n" +msgid "can't read superblock for AG %u\n" +msgstr "nie można odczytać superbloku dla AG %u\n" -#: .././repair/attr_repair.c:342 +#: .././db/sb.c:203 #, c-format -msgid "remote block for attributes of inode % is missing\n" -msgstr "brak odległego bloku dla atrybutów i-węzła %\n" +msgid "bad sb magic # %#x in AG %u\n" +msgstr "błędna liczba magiczna superbloku %#x w AG %u\n" -#: .././repair/attr_repair.c:350 +#: .././db/sb.c:208 #, c-format -msgid "can't read remote block for attributes of inode %\n" -msgstr "nie można odczytać odległego bloku dla atrybutów i-węzła %\n" +msgid "bad sb version # %#x in AG %u\n" +msgstr "błędny numer wersji superbloku %#x w AG %u\n" -#: .././repair/attr_repair.c:388 -#, c-format -msgid "attribute entry %d in attr block %u, inode % has bad name (namelen = %d)\n" -msgstr "wpis atrybutu %d w bloku atrybutów %u, i-węźle % ma błędną nazwę (namelen = %d)\n" +#: .././db/sb.c:233 +msgid "aborting - external log specified for FS with an internal log\n" +msgstr "przerwano - podano log zewnętrzny dla systemu plików z logiem wewnętrznym\n" -#: .././repair/attr_repair.c:405 -#, c-format -msgid "bad hashvalue for attribute entry %d in attr block %u, inode %\n" -msgstr "błędna wartość hasza dla wpisu atrybutu %d w bloku atrybutów %u, i-węźle %\n" +#: .././db/sb.c:239 +msgid "aborting - no external log specified for FS with an external log\n" +msgstr "przerwano - nie podano logu zewnętrznego dla systemu plików z logiem zewnętrznym\n" -#: .././repair/attr_repair.c:415 -#, c-format -msgid "bad security value for attribute entry %d in attr block %u, inode %\n" -msgstr "błędna wartość bezpieczeństwa dla wpisu atrybutu %d w bloku atrybutów %u, i-węźle %\n" +#: .././db/sb.c:261 +msgid "ERROR: cannot find log head/tail, run xfs_repair\n" +msgstr "BŁĄD: nie odnaleziono początku/końca logu, proszę uruchomić xfs_repair\n" -#: .././repair/attr_repair.c:448 +#: .././db/sb.c:266 #, c-format -msgid "inconsistent remote attribute entry %d in attr block %u, ino %\n" -msgstr "niespójny wpis odległego atrybutu %d w bloku atrybutów %u, i-węźle %\n" - -#: .././repair/attr_repair.c:458 -#, c-format -msgid "cannot malloc enough for remotevalue attribute for inode %\n" -msgstr "nie można przydzielić wystarczająco dużo dla atrybutu remotevalue dla i-węzła %\n" - -#: .././repair/attr_repair.c:460 -msgid "SKIPPING this remote attribute\n" -msgstr "POMINIĘTO ten atrybut odległy\n" +msgid "" +"ERROR: The filesystem has valuable metadata changes in a log which needs to\n" +"be replayed. Mount the filesystem to replay the log, and unmount it before\n" +"re-running %s. If you are unable to mount the filesystem, then use\n" +"the xfs_repair -L option to destroy the log and attempt a repair.\n" +"Note that destroying the log may cause corruption -- please attempt a mount\n" +"of the filesystem before doing this.\n" +msgstr "" +"BŁĄD: system plików zawiera wartościowe zmiany metadanych w logu, który\n" +"musi być odtworzony. Należy podmontować system plików, aby odtworzyć log,\n" +"a następnie odmontować go przed ponownym uruchomieniem %s. Jeśli\n" +"systemu plików nie da się podmontować, można użyć opcji -L, aby zniszczyć\n" +"log i spróbować naprawić system plików.\n" +"Należy zauważyć, że zniszczenie logu może spowodować uszkodzenia danych -\n" +"proszę najpierw spróbować podmontować system plików.\n" -#: .././repair/attr_repair.c:466 -#, c-format -msgid "remote attribute get failed for entry %d, inode %\n" -msgstr "pobranie odległego atrybutu nie powiodło się dla wpisu %d, i-węzła %\n" +#: .././db/sb.c:283 +msgid "Clearing log and setting UUID\n" +msgstr "Czyszczenei logu i ustawianie UUID-a\n" -#: .././repair/attr_repair.c:473 -#, c-format -msgid "remote attribute value check failed for entry %d, inode %\n" -msgstr "sprawdzenie wartości odległego atrybutu nie powiodło się dla wpisu %d, i-węzła %\n" +#: .././db/sb.c:291 +msgid "ERROR: cannot clear the log\n" +msgstr "BŁĄD: nie można wyczyścić logu\n" -#: .././repair/attr_repair.c:510 -#, c-format -msgid "bad attribute count %d in attr block %u, inode %\n" -msgstr "błędna liczba atrybutów %d w bloku atrybutów %u, i-węźle %\n" +#: .././db/sb.c:302 +msgid "" +"\n" +" write/print FS uuid\n" +"\n" +" Example:\n" +"\n" +" 'uuid' - print UUID\n" +" 'uuid 01234567-0123-0123-0123-0123456789ab' - write UUID\n" +" 'uuid generate' - generate and write\n" +" 'uuid rewrite' - copy UUID from SB 0\n" +"\n" +"The print function checks the UUID in each SB and will warn if the UUIDs\n" +"differ between AGs (the log is not checked). The write commands will\n" +"set the uuid in all AGs to either a specified value, a newly generated\n" +"value or the value found in the first superblock (SB 0) respectively.\n" +"As a side effect of writing the UUID, the log is cleared (which is fine\n" +"on a CLEANLY unmounted FS).\n" +"\n" +msgstr "" +"\n" +" zapisanie/wypisanie uuida systemu plików\n" +"\n" +"Przykład:\n" +"\n" +" 'uuid' - wypisanie UUID-a\n" +" 'uuid 01234567-0123-0123-0123-0123456789ab' - zapisanie UUID-a\n" +" 'uuid generate' - wygenerowanie i zapisanie\n" +" 'uuid rewrite' - skopiowanie UUID-a z sb 0\n" +"\n" +"Funkcja wypisująca sprawdza UUID w każdym superbloku i ostrzega, jeśli UUID-y\n" +"się różnią między AG (log nie jest sprawdzany). Polecenia zapisu ustawiają\n" +"UUID we wszystkich AG odpowiednio na określoną wartość, nowo wygenerowaną\n" +"wartość lub wartość znalezioną w pierwszym superbloku (SB 0).\n" +"Jako efekt uboczny zapisu UUID-a czyszczony jest log (co nie jest problemem\n" +"przy CZYSTO odmontowanym systemie plików).\n" +"\n" -#: .././repair/attr_repair.c:525 -#, c-format -msgid "bad attribute nameidx %d in attr block %u, inode %\n" -msgstr "błędny nameidx atrybutu %d w bloku atrybutów %u, i-węźle %\n" +#: .././db/sb.c:354 .././db/sb.c:506 +msgid "invalid parameters\n" +msgstr "błędne parametry\n" -#: .././repair/attr_repair.c:534 +#: .././db/sb.c:361 .././db/sb.c:513 .././db/sb.c:670 #, c-format -msgid "attribute entry #%d in attr block %u, inode % is INCOMPLETE\n" -msgstr "wpis atrybutu #%d w bloku atrybutów %u, i-węźle % jest NIEPEŁNY\n" +msgid "%s: not in expert mode, writing disabled\n" +msgstr "%s: nie w trybie expert, zapis wyłączony\n" -#: .././repair/attr_repair.c:545 -#, c-format -msgid "attribute entry %d in attr block %u, inode % claims already used space\n" -msgstr "wpis atrybutu %d w bloku atrybutów %u, i-węźle % odwołuje się do już użytego miejsca\n" +#: .././db/sb.c:373 +msgid "failed to read UUID from AG 0\n" +msgstr "nie udało się odczytać UUID-a z AG 0\n" -#: .././repair/attr_repair.c:568 +#: .././db/sb.c:378 #, c-format -msgid "attribute entry %d in attr block %u, inode % claims used space\n" -msgstr "wpis atrybutu %d w bloku atrybutów %u, i-węźle % odwołuje się do używanego miejsca\n" +msgid "old UUID = %s\n" +msgstr "stary UUID = %s\n" -#: .././repair/attr_repair.c:592 -#, c-format -msgid "- resetting first used heap value from %d to %d in block %u of attribute fork of inode %\n" -msgstr "- przestawiono pierwszą używaną wartość sterty z %d na %d w bloku %u gałęzi atrybutów i-węzła %\n" +#: .././db/sb.c:381 +msgid "invalid UUID\n" +msgstr "błędny UUID\n" -#: .././repair/attr_repair.c:600 -#, c-format -msgid "- would reset first used value from %d to %d in block %u of attribute fork of inode %\n" -msgstr "- pierwsza używana wartość zostałaby przestawiona z %d na %d w bloku %u gałęzi atrybutów i-węzła %\n" +#: .././db/sb.c:390 .././db/sb.c:518 .././db/sb.c:756 +msgid "writing all SBs\n" +msgstr "zapisywanie wszystkich superbloków\n" -#: .././repair/attr_repair.c:610 +#: .././db/sb.c:393 #, c-format -msgid "- resetting usedbytes cnt from %d to %d in block %u of attribute fork of inode %\n" -msgstr "- przestawiono liczbę użytych bajtów z %d na %d w bloku %u gałęzi atrybutów i-węzła %\n" +msgid "failed to set UUID in AG %d\n" +msgstr "nie udało się ustawić UUID-a w AG %d\n" -#: .././repair/attr_repair.c:618 +#: .././db/sb.c:398 #, c-format -msgid "- would reset usedbytes cnt from %d to %d in block %u of attribute fork of %\n" -msgstr "- liczba użytych bajtów zostałaby przestawiona z %d na %d w bloku %u gałęzi atrybutów i-węzła %\n" +msgid "new UUID = %s\n" +msgstr "nowy UUID = %s\n" -#: .././repair/attr_repair.c:670 +#: .././db/sb.c:406 #, c-format -msgid "can't map block %u for attribute fork for inode %\n" -msgstr "nie można odwzorować bloku %u dla gałęzi atrybutów dla i-węzła %\n" +msgid "failed to read UUID from AG %d\n" +msgstr "nie udało się odczytać UUID-a z AG %d\n" -#: .././repair/attr_repair.c:679 +#: .././db/sb.c:412 #, c-format -msgid "can't read file block %u (fsbno %) for attribute fork of inode %\n" -msgstr "nie można odczytać bloku pliku %u (fsbno %) dla gałęzi atrybutów i-węzła %\n" +msgid "warning: UUID in AG %d differs to the primary SB\n" +msgstr "uwaga: UUID w AG %d różni się od głównego SB\n" -#: .././repair/attr_repair.c:689 -#, c-format -msgid "bad attribute leaf magic %#x for inode %\n" -msgstr "błędna liczba magiczna liścia atrybutu %#x dla i-węzła %\n" +#: .././db/sb.c:423 +msgid "warning - external log specified for FS with an internal log\n" +msgstr "uwaga: podano log zewnętrzny dla systemu plików z logiem wewnętrznym\n" -#: .././repair/attr_repair.c:720 -#, c-format -msgid "bad sibling back pointer for block %u in attribute fork for inode %\n" -msgstr "błędny wskaźnik wsteczny dla bloku %u w gałęzi atrybutów dla i-węzła %\n" +#: .././db/sb.c:426 +msgid "warning - no external log specified for FS with an external log\n" +msgstr "uwaga: nie podano logu zewnętrznego dla systemu plików z logiem zewnętrznym\n" -#: .././repair/attr_repair.c:747 +#: .././db/sb.c:431 #, c-format -msgid "bad hash path in attribute fork for inode %\n" -msgstr "błędna ścieżka hasza w gałęzi atrybutów dla i-węzła %\n" +msgid "UUID = %s\n" +msgstr "UUID = %s\n" -#: .././repair/attr_repair.c:846 -#, c-format -msgid "block 0 of inode % attribute fork is missing\n" -msgstr "brak bloku 0 i-węzła % gałęzi atrybutów\n" +#: .././db/sb.c:442 +msgid "" +"\n" +" write/print FS label\n" +"\n" +" Example:\n" +"\n" +" 'label' - print label\n" +" 'label 123456789012' - write label\n" +" 'label --' - write an empty label\n" +"\n" +"The print function checks the label in each SB and will warn if the labels\n" +"differ between AGs. The write commands will set the label in all AGs to the\n" +"specified value. The maximum length of a label is 12 characters - use of a\n" +"longer label will result in truncation and a warning will be issued.\n" +"\n" +msgstr "" +"\n" +" zapisanie/wypisanie etykiety systemu plików\n" +"\n" +" Przykład:\n" +"\n" +" 'label' - wypisanie etykiety\n" +" 'label 123456789012' - zapisanie etykiety\n" +" 'label --' - zapisanie etykiety pustej\n" +"\n" +"Funkcja wypisująca sprawdza etykietę w każdym superbloku i ostrzega, jeśli\n" +"etykiety różnią się między AG. Polecenia zapisu ustawiają etykietw we\n" +"wszystkich AG na określoną wartość. Maksymalna długość etykiety to 12 znaków;\n" +"użycie etykiety dłuższej zaskutkuje ucięciem jej i wypisaniem ostrzeżenia.\n" +"\n" -#: .././repair/attr_repair.c:853 +#: .././db/sb.c:479 #, c-format -msgid "agno of attribute fork of inode % out of regular partition\n" -msgstr "agno gałęzi atrybutów i-węzła % spoza zwykłej partycji\n" +msgid "%s: truncating label length from %d to %d\n" +msgstr "%s: skrócono długość etykiety z %d do %d\n" -#: .././repair/attr_repair.c:861 +#: .././db/sb.c:521 #, c-format -msgid "can't read block 0 of inode % attribute fork\n" -msgstr "nie można odczytać bloku 0 i-węzła % gałęzi atrybutów\n" +msgid "failed to set label in AG %d\n" +msgstr "nie udało się ustawić etykiety w AG %d\n" -#: .././repair/attr_repair.c:876 +#: .././db/sb.c:524 #, c-format -msgid "clearing forw/back pointers in block 0 for attributes in inode %\n" -msgstr "wyczyszczono wskaźniki forw/back w bloku 0 dla atrybutów w i-węźle %\n" +msgid "new label = \"%s\"\n" +msgstr "nowa etykieta = \"%s\"\n" -#: .././repair/attr_repair.c:883 +#: .././db/sb.c:531 #, c-format -msgid "would clear forw/back pointers in block 0 for attributes in inode %\n" -msgstr "wskaźniki forw/back w bloku 0 dla atrybutów w i-węźle % zostałyby wyczyszczone\n" +msgid "failed to read label in AG %d\n" +msgstr "nie udało się odczytać etykiety w AG %d\n" -#: .././repair/attr_repair.c:913 +#: .././db/sb.c:537 #, c-format -msgid "bad attribute leaf magic # %#x for dir ino %\n" -msgstr "błędna liczba magiczna liścia atrybutu %#x dla i-węzła katalogu %\n" +msgid "warning: AG %d label differs\n" +msgstr "uwaga: etykieta w AG %d różni się\n" -#: .././repair/attr_repair.c:938 +#: .././db/sb.c:539 #, c-format -msgid "Too many ACL entries, count %d\n" -msgstr "Za dużo wpisów ACL, liczba %d\n" +msgid "label = \"%s\"\n" +msgstr "etykieta = \"%s\"\n" -#: .././repair/attr_repair.c:947 -msgid "cannot malloc enough for ACL attribute\n" -msgstr "nie można wykonać wystarczającego malloc dla atrybutu ACL\n" +#: .././db/sb.c:549 +msgid "" +"\n" +" set/print feature bits in sb version\n" +"\n" +" Example:\n" +"\n" +" 'version' - print current feature bits\n" +" 'version extflg' - enable unwritten extents\n" +" 'version attr1' - enable v1 inline extended attributes\n" +" 'version attr2' - enable v2 inline extended attributes\n" +" 'version log2' - enable v2 log format\n" +"\n" +"The version function prints currently enabled features for a filesystem\n" +"according to the version field of its primary superblock.\n" +"It can also be used to enable selected features, such as support for\n" +"unwritten extents. The updated version is written into all AGs.\n" +"\n" +msgstr "" +"\n" +" ustawienie/wypisanie bitów cech w wersji superbloku\n" +"\n" +" Przykład:\n" +"\n" +" 'version' - wypisanie bieżących bitów cech\n" +" 'version extflg' - włączenie nie zapisanych ekstentów\n" +" 'version attr1' - włączenie rozszerzonych atrybutów inline v1\n" +" 'version attr2' - włączenie rozszerzonych atrybutów inline v2\n" +" 'version log2' - włączenie formatu logu v2\n" +"\n" +"Funkcja 'version' wypisuje aktualnie włączone cechy dla systemu plików\n" +"zgodnie z polem wersji w głównym superbloku.\n" +"Może być używana także do włączania wybranych cech, takich jak obsługa\n" +"nie zapisanych ekstentów. Uaktualniona wersja jest zapisywana we wszystkich\n" +"AG.\n" +"\n" -#: .././repair/attr_repair.c:948 -msgid "SKIPPING this ACL\n" -msgstr "POMINIĘTO ten ACL\n" +#: .././db/sb.c:578 +msgid "Superblock has mismatched features2 fields, skipping modification\n" +msgstr "Superblok ma niepasujące pola features2, pominięto modyfikację\n" -#: .././repair/incore_ino.c:47 -msgid "could not allocate nlink array\n" -msgstr "Nie udało się przydzielić tablicy nlink\n" +#: .././db/sb.c:690 +msgid "unwritten extents flag is already enabled\n" +msgstr "flaga nie zapisanych ekstentów jest już włączona\n" -#: .././repair/incore_ino.c:233 -msgid "inode map malloc failed\n" -msgstr "przydzielenie mapy i-węzłów nie powiodło się\n" +#: .././db/sb.c:697 +msgid "unwritten extents always enabled for v5 superblocks.\n" +msgstr "nie zapisane ekstenty są zawsze włączone dla superbloków v5.\n" -#: .././repair/incore_ino.c:340 -msgid "add_aginode_uncertain - duplicate inode range\n" -msgstr "add_aginode_uncertain - powtórzony przedział i-węzłów\n" +#: .././db/sb.c:714 +msgid "version 2 log format is already in use\n" +msgstr "format logu w wersji 2 jest już w użyciu\n" -#: .././repair/incore_ino.c:435 -msgid "add_inode - duplicate inode range\n" -msgstr "add_inode - powtórzony przedział i-węzłów\n" +#: .././db/sb.c:721 +msgid "Version 2 logs always enabled for v5 superblocks.\n" +msgstr "Logi w wersji 2 są zawsze włączone dla superbloków v5.\n" -#: .././repair/incore_ino.c:529 +#: .././db/sb.c:726 #, c-format -msgid "good inode list is --\n" -msgstr "lista dobrych i-węzłów to:\n" +msgid "%s: Cannot change %s on v5 superblocks.\n" +msgstr "%s: Nie można zmienić %s przy superblokach v5.\n" -#: .././repair/incore_ino.c:532 +#: .././db/sb.c:750 #, c-format -msgid "uncertain inode list is --\n" -msgstr "lista niepewnych i-węzłów to:\n" +msgid "%s: invalid version change command \"%s\"\n" +msgstr "%s: błędne polecenie zmiany wersji \"%s\"\n" -#: .././repair/incore_ino.c:537 +#: .././db/sb.c:759 #, c-format -msgid "agno %d -- no inodes\n" -msgstr "agno %d - brak i-węzłów\n" +msgid "failed to set versionnum in AG %d\n" +msgstr "nie udało się ustawić versionnum w AG %d\n" -#: .././repair/incore_ino.c:541 +#: .././db/sb.c:777 #, c-format -msgid "agno %d\n" -msgstr "agno %d\n" - -#: .././repair/incore_ino.c:545 -#, c-format -msgid "\tptr = %lx, start = 0x%x, free = 0x%llx, confirmed = 0x%llx\n" -msgstr "\tptr = %lx, start = 0x%x, wolne = 0x%llx, potwierdzone = 0x%llx\n" +msgid "versionnum [0x%x+0x%x] = %s\n" +msgstr "versionnum [0x%x+0x%x] = %s\n" -#: .././repair/incore_ino.c:596 -msgid "couldn't malloc parent list table\n" -msgstr "nie udało się przydzielić tablicy listy rodziców\n" +#: .././db/type.c:49 +msgid "[newtype]" +msgstr "[nowy-typ]" -#: .././repair/incore_ino.c:607 .././repair/incore_ino.c:653 -msgid "couldn't memalign pentries table\n" -msgstr "nie udało się memalign na tablicy pentries\n" +#: .././db/type.c:50 +msgid "set/show current data type" +msgstr "ustawienie/wyświetlenie bieżącego typu danych" -#: .././repair/incore_ino.c:711 -msgid "could not malloc inode extra data\n" -msgstr "nie udało się przydzielić dodatkowych danych i-węzła\n" +#: .././db/type.c:144 +#, c-format +msgid "current type is \"%s\"\n" +msgstr "bieżący typ to \"%s\"\n" -#: .././repair/incore_ino.c:777 -msgid "couldn't malloc inode tree descriptor table\n" -msgstr "nie udało się przydzielić tablicy deskryptorów drzewa i-węzłów\n" +#: .././db/type.c:146 +msgid "" +"\n" +" supported types are:\n" +" " +msgstr "" +"\n" +" obsługiwane typy to:\n" +" " -#: .././repair/incore_ino.c:781 -msgid "couldn't malloc uncertain ino tree descriptor table\n" -msgstr "nie udało się przydzielić tablicy deskryptorów drzewa i-węzłów niepewnych\n" +#: .././db/type.c:163 +#, c-format +msgid "no such type %s\n" +msgstr "nie ma typu %s\n" -#: .././repair/incore_ino.c:786 -msgid "couldn't malloc inode tree descriptor\n" -msgstr "nie udało się przydzielić deskryptora drzewa i-węzłów\n" +#: .././db/type.c:166 +msgid "no current object\n" +msgstr "brak bieżącego obiektu\n" -#: .././repair/incore_ino.c:790 -msgid "couldn't malloc uncertain ino tree descriptor\n" -msgstr "nie udało się przydzielić deskryptora drzewa i-węzłów niepewnych\n" +#: .././db/write.c:41 +msgid "[field or value]..." +msgstr "[pole lub wartość]..." -#: .././repair/incore_ino.c:798 -msgid "couldn't malloc uncertain inode cache area\n" -msgstr "nie udało się przydzielić obszaru pamięci podręcznej i-węzłów niepewnych\n" +#: .././db/write.c:42 +msgid "write value to disk" +msgstr "zapis wartości na dysk" -#: .././repair/dir.c:152 -#, c-format -msgid "invalid inode number % in directory %\n" -msgstr "błędny numer i-węzła % w katalogu %\n" +#: .././db/write.c:58 +msgid "" +"\n" +" The 'write' command takes on different personalities depending on the\n" +" type of object being worked with.\n" +"\n" +" Write has 3 modes:\n" +" 'struct mode' - is active anytime you're looking at a filesystem object\n" +" which contains individual fields (ex: an inode).\n" +" 'data mode' - is active anytime you set a disk address directly or set\n" +" the type to 'data'.\n" +" 'string mode' - only used for writing symlink blocks.\n" +"\n" +" Examples:\n" +" Struct mode: 'write core.uid 23' - set an inode uid field to 23.\n" +" 'write fname \"hello\\000\"' - write superblock fname.\n" +" (note: in struct mode strings are not null terminated)\n" +" 'write fname #6669736800' - write superblock fname with hex.\n" +" 'write uuid 00112233-4455-6677-8899-aabbccddeeff'\n" +" - write superblock uuid.\n" +" Data mode: 'write fill 0xff' - fill the entire block with 0xff's\n" +" 'write lshift 3' - shift the block 3 bytes to the left\n" +" 'write sequence 1 5' - write a cycle of number [1-5] through\n" +" the entire block.\n" +" String mode: 'write \"This_is_a_filename\" - write null terminated string.\n" +"\n" +" In data mode type 'write' by itself for a list of specific commands.\n" +"\n" +msgstr "" +"\n" +" Polecenie 'write' ma różne osobowości w zależności od rodzaju obiektu,\n" +" na jakim pracuje.\n" +"\n" +" Zapis ma trzy tryby:\n" +" 'struct' (strukturalny) - aktywny w przypadku oglądania obiektu systemu\n" +" plików zawierającego poszczególne pola (np. i-węzeł).\n" +" 'data' (danych) - aktywny w przypadku bezpośredniego ustawienia adresu\n" +" na dysku lub ustawienia typu na 'data'.\n" +" 'string' (znakowy) - używany tylko przy zapisie bloków dowiązań\n" +" symbolicznych.\n" +"\n" +" Przykłady:\n" +" Tryb strukturalny: 'write core.uid 23' - ustawienie pola uid i-węzła na 23\n" +" 'write fname \"hello\\000\"' - zapis nazwy pliku sb\n" +" (uwaga: w trybie strukturalnym łańcuchy nie są zakańczane)\n" +" 'write fname #6669736800' - zapis nazwy pliku sb w hex.\n" +" 'write uuid 00112233-4455-6677-8899-aabbccddeeff'\n" +" - zapis UUID-a superbloku.\n" +" Tryb danych: 'write fill 0xff' - wypełnienie bloku bajtam 0xff\n" +" 'write lshift 3' - przesunięcie bloku o 3 bajty w lewo\n" +" 'write sequence 1 5' zapis cyklicznie liczb [1-5] przez\n" +" cały blok.\n" +" Tryb znakowy: 'write \"To_jest_nazwa_pliku\" - zapis łańcucha\n" +" zakończonego znakiem NUL.\n" +"\n" +" W trybie danych samo 'write' wypisze listę bardziej specyficznych poleceń.\n" +"\n" -#: .././repair/dir.c:157 +#: .././db/write.c:95 #, c-format -msgid "entry in shortform dir % references rt bitmap inode %\n" -msgstr "wpis w krótkim katalogu % odwołuje się do i-węzła bitmapy rt %\n" +msgid "%s started in read only mode, writing disabled\n" +msgstr "%s uruchomiono w trybie tylko do odczytu, zapis wyłączony\n" -#: .././repair/dir.c:162 +#: .././db/write.c:107 #, c-format -msgid "entry in shortform dir % references rt summary inode %\n" -msgstr "wpis w krótkim katalogu % odwołuje się do i-węzła opisu rt %\n" +msgid "no handler function for type %s, write unsupported.\n" +msgstr "brak funkcji obsługującej dla typu %s, zapis nie obsługiwany.\n" -#: .././repair/dir.c:167 +#: .././db/write.c:167 .././db/write.c:196 .././db/write.c:226 +#: .././db/write.c:259 .././db/write.c:295 .././db/write.c:344 +#: .././db/write.c:373 #, c-format -msgid "entry in shortform dir % references user quota inode %\n" -msgstr "wpis w krótkim katalogu % odwołuje się do i-węzła limitu użytkownika %\n" +msgid "length (%d) too large for data block size (%d)" +msgstr "długość (%d) zbyt duża dla rozmiaru bloku danych (%d)" -#: .././repair/dir.c:172 -#, c-format -msgid "entry in shortform dir % references group quota inode %\n" -msgstr "wpis w krótkim katalogu % odwołuje się do i-węzła limitu grupy %\n" +#: .././db/write.c:615 +msgid "usage: write fieldname value\n" +msgstr "składnia: write nazwa-pola wartość\n" -#: .././repair/dir.c:193 +#: .././db/write.c:621 #, c-format -msgid "entry references free inode % in shortform directory %\n" -msgstr "wpis odwołuje się do wolnego i-węzła % w krótkim katalogu %\n" +msgid "unable to parse '%s'.\n" +msgstr "nie można przeanalizować '%s'.\n" -#: .././repair/dir.c:212 -#, c-format -msgid "entry references non-existent inode % in shortform dir %\n" -msgstr "wpis odwołuje się do nie istniejącego i-węzła % w krótkim katalogu %\n" +#: .././db/write.c:635 +msgid "parsing error\n" +msgstr "błąd składni\n" -#: .././repair/dir.c:236 .././repair/dir2.c:995 +#: .././db/write.c:654 #, c-format -msgid "zero length entry in shortform dir %, resetting to %d\n" -msgstr "wpis zerowej długości w krótkim katalogu %, przestawiono na %d\n" +msgid "unable to convert value '%s'.\n" +msgstr "nie można przekonwertować wartości '%s'.\n" -#: .././repair/dir.c:241 .././repair/dir2.c:1000 -#, c-format -msgid "zero length entry in shortform dir %, would set to %d\n" -msgstr "wpis zerowej długości w krótkim katalogu %, zostałby przestawiony na %d\n" +#: .././db/write.c:677 +msgid "usage (in string mode): write \"string...\"\n" +msgstr "składnia (w trybie znakowym): write \"łańcuch...\"\n" -#: .././repair/dir.c:246 -#, c-format -msgid "zero length entry in shortform dir %, " -msgstr "wpis zerowej długości w krótkim katalogu %, " +#: .././db/write.c:719 +msgid "write: invalid subcommand\n" +msgstr "write: błędne podpolecenie\n" -#: .././repair/dir.c:249 .././repair/dir.c:292 .././repair/dir2.c:1051 +#: .././db/write.c:724 #, c-format -msgid "junking %d entries\n" -msgstr "wyrzucono %d wpisów\n" +msgid "write %s: invalid number of arguments\n" +msgstr "write %s: błędna liczba argumentów\n" -#: .././repair/dir.c:252 .././repair/dir.c:301 .././repair/dir2.c:1060 -#, c-format -msgid "would junk %d entries\n" -msgstr "%d wpisów zostałoby wyrzuconych\n" +#: .././db/write.c:748 +msgid "usage: write (in data mode)\n" +msgstr "składnia: write (w trybie danych)\n" -#: .././repair/dir.c:270 .././repair/dir2.c:1029 +#: .././estimate/xfs_estimate.c:78 #, c-format -msgid "size of last entry overflows space left in in shortform dir %, " -msgstr "rozmiar ostatniego wpisu przekracza miejsce pozostałe w krótkim katalogu %, " +msgid "" +"Usage: %s [opts] directory [directory ...]\n" +"\t-b blocksize (fundamental filesystem blocksize)\n" +"\t-i logsize (internal log size)\n" +"\t-e logsize (external log size)\n" +"\t-v prints more verbose messages\n" +"\t-V prints version and exits\n" +"\t-h prints this usage message\n" +"\n" +"Note:\tblocksize may have 'k' appended to indicate x1024\n" +"\tlogsize may also have 'm' appended to indicate (1024 x 1024)\n" +msgstr "" +"Składnia: %s [opcje] katalog [katalog ...]\n" +"\t-b rozmiar_bloku (rozmiar bloku zasadniczego systemu plików)\n" +"\t-i rozmiar_logu (rozmiar logu wewnętrznego)\n" +"\t-e rozmiar_logu (rozmiar logu zewnętrznego)\n" +"\t-v wypisywanie bardziej szczegółowych komunikatów\n" +"\t-V wypisanie informacji o wersji i zakończenie\n" +"\t-h wypisanie tej informacji o sposobie użycia\n" +"\n" -#: .././repair/dir.c:273 .././repair/dir2.c:1032 +#: .././estimate/xfs_estimate.c:109 #, c-format -msgid "resetting to %d\n" -msgstr "przestawiono na %d\n" +msgid "blocksize %llu too small\n" +msgstr "rozmiar bloku %llu jest zbyt mały\n" -#: .././repair/dir.c:278 .././repair/dir2.c:1037 +#: .././estimate/xfs_estimate.c:114 #, c-format -msgid "would reset to %d\n" -msgstr "zostałby przestawiony na %d\n" +msgid "blocksize %llu too large\n" +msgstr "rozmiar bloku %llu jest zbyt duży\n" -#: .././repair/dir.c:283 .././repair/dir2.c:1042 +#: .././estimate/xfs_estimate.c:121 #, c-format -msgid "size of entry #%d overflows space left in in shortform dir %\n" -msgstr "rozmiar wpisu #%d przekracza miejsce pozostałe w krótkim katalogu %\n" +msgid "already have external log noted, can't have both\n" +msgstr "już jest przypisany zewnętrzny log, nie mogą istnieć oba\n" -#: .././repair/dir.c:288 .././repair/dir2.c:1047 +#: .././estimate/xfs_estimate.c:130 #, c-format -msgid "junking entry #%d\n" -msgstr "wyrzucono wpis #%d\n" +msgid "already have internal log noted, can't have both\n" +msgstr "już jest przypisany wewnętrzny log, nie mogą istnieć oba\n" -#: .././repair/dir.c:297 .././repair/dir2.c:1056 +#: .././estimate/xfs_estimate.c:160 #, c-format -msgid "would junk entry #%d\n" -msgstr "wpis #%d zostałby wyrzucony\n" +msgid "directory bsize blocks megabytes logsize\n" +msgstr "katalog rozmb bloków megabajtów rozm.logu\n" -#: .././repair/dir.c:320 .././repair/dir2.c:1079 +#: .././estimate/xfs_estimate.c:174 #, c-format -msgid "entry contains illegal character in shortform dir %\n" -msgstr "wpis zawiera niedozwolony znak w krótkim katalogu %\n" +msgid "dirsize=%llu\n" +msgstr "dirsize=%llu\n" -#: .././repair/dir.c:374 .././repair/dir2.c:1143 +#: .././estimate/xfs_estimate.c:175 #, c-format -msgid "junking entry \"%s\" in directory inode %\n" -msgstr "wyrzucono wpis \"%s\" w i-węźle katalogu %\n" +msgid "fullblocks=%llu\n" +msgstr "fullblocks=%llu\n" -#: .././repair/dir.c:378 .././repair/dir2.c:1147 +#: .././estimate/xfs_estimate.c:176 #, c-format -msgid "would have junked entry \"%s\" in directory inode %\n" -msgstr "wpis \"%s\" w i-węźle katalogu % zostałby wyrzucony\n" +msgid "isize=%llu\n" +msgstr "isize=%llu\n" -#: .././repair/dir.c:404 .././repair/dir2.c:1174 +#: .././estimate/xfs_estimate.c:178 #, c-format -msgid "would have corrected entry count in directory % from %d to %d\n" -msgstr "liczba wpisów w katalogu % zostałaby poprawiona z %d na %d\n" +msgid "%llu regular files\n" +msgstr "%llu plików zwykłych\n" -#: .././repair/dir.c:408 .././repair/dir2.c:1178 +#: .././estimate/xfs_estimate.c:179 #, c-format -msgid "corrected entry count in directory %, was %d, now %d\n" -msgstr "poprawiono liczbę wpisów w katalogu % - było %d, jest %d\n" +msgid "%llu symbolic links\n" +msgstr "%llu dowiązań symbolicznych\n" -#: .././repair/dir.c:419 +#: .././estimate/xfs_estimate.c:180 #, c-format -msgid "would have corrected directory % size from %to %\n" -msgstr "rozmiar katalogu % zostałby poprawiony z % na %\n" +msgid "%llu directories\n" +msgstr "%llu katalogów\n" -#: .././repair/dir.c:424 .././repair/dir2.c:1212 +#: .././estimate/xfs_estimate.c:181 #, c-format -msgid "corrected directory % size, was %, now %\n" -msgstr "poprawiono rozmiar katalogu % - było %, jest %\n" +msgid "%llu special files\n" +msgstr "%llu plików specjalnych\n" -#: .././repair/dir.c:446 .././repair/dir2.c:1253 +#: .././estimate/xfs_estimate.c:194 #, c-format -msgid "bogus .. inode number (%) in directory inode %, " -msgstr "błędny numer i-węzła .. (%) w i-węźle katalogu %, " - -#: .././repair/dir.c:449 .././repair/dir.c:483 .././repair/dir2.c:1257 -#: .././repair/dir2.c:1292 -msgid "clearing inode number\n" -msgstr "wyczyszczono numer i-węzła\n" - -#: .././repair/dir.c:455 .././repair/dir.c:489 .././repair/dir2.c:1263 -#: .././repair/dir2.c:1298 -msgid "would clear inode number\n" -msgstr "numer i-węzła zostałby wyczyszczony\n" +msgid "%s will take about %.1f megabytes\n" +msgstr "%s zajmie około %.1f megabajtów\n" -#: .././repair/dir.c:463 .././repair/dir2.c:1271 +#: .././estimate/xfs_estimate.c:201 #, c-format -msgid "corrected root directory % .. entry, was %, now %\n" -msgstr "poprawiono wpis .. głównego katalogu % - było %, jest %\n" +msgid "%-39s %5llu %8llu %10.1fMB %10llu\n" +msgstr "%-39s %5llu %8llu %10.1fMB %10llu\n" -#: .././repair/dir.c:471 .././repair/dir2.c:1279 +#: .././estimate/xfs_estimate.c:207 #, c-format -msgid "would have corrected root directory % .. entry from % to %\n" -msgstr "wpis .. głównego katalogu % zostałby poprawiony z % na %\n" +msgid "\twith the external log using %llu blocks " +msgstr "\tz zewnętrznym logiem zajmującym %llu bloków " -#: .././repair/dir.c:480 +#: .././estimate/xfs_estimate.c:209 #, c-format -msgid "bad .. entry in dir ino %, points to self, " -msgstr "błędny wpis .. w i-węźle katalogu %, wskazuje na siebie, " +msgid "or about %.1f megabytes\n" +msgstr "lub około %.1f megabajtów\n" -#: .././repair/dir.c:524 +#: .././fsr/xfs_fsr.c:194 #, c-format -msgid "bad range claimed [%d, %d) in da block\n" -msgstr "błędny przedział [%d, %d) przypisany w bloku da\n" +msgid "%s: cannot read %s\n" +msgstr "%s: nie można odczytać %s\n" -#: .././repair/dir.c:531 +#: .././fsr/xfs_fsr.c:273 #, c-format -msgid "byte range end [%d %d) in da block larger than blocksize %d\n" -msgstr "koniec przedziału bajtów [%d %d) w bloku da większy niż rozmiar bloku %d\n" +msgid "%s: Stats not yet supported for XFS\n" +msgstr "%s: statystyki nie są jeszcze obsługiwane dla XFS-a\n" -#: .././repair/dir.c:538 +#: .././fsr/xfs_fsr.c:337 #, c-format -msgid "multiply claimed byte %d in da block\n" -msgstr "wielokrotnie użyty bajt %d w bloku da\n" +msgid "%s: could not stat: %s: %s\n" +msgstr "%s: nie można wykonać stat: %s: %s\n" -#: .././repair/dir.c:568 +#: .././fsr/xfs_fsr.c:356 #, c-format -msgid "hole (start %d, len %d) out of range, block %d, dir ino %\n" -msgstr "dziura (początek %d, długość %d) poza zakresem, blok %d, i-węzeł katalogu %\n" +msgid "%s: char special not supported: %s\n" +msgstr "%s: urządzenia znakowe nie są obsługiwane: %s\n" -#: .././repair/dir.c:579 +#: .././fsr/xfs_fsr.c:362 #, c-format -msgid "hole claims used byte %d, block %d, dir ino %\n" -msgstr "dziura odwołuje się do używanego bajtu %d, blok %d, i-węzeł katalogu %\n" +msgid "%s: cannot defragment: %s: Not XFS\n" +msgstr "%s: nie można zdefragmentować: %s: to nie jest XFS\n" -#: .././repair/dir.c:693 +#: .././fsr/xfs_fsr.c:372 #, c-format -msgid "- derived hole value %d, saw %d, block %d, dir ino %\n" -msgstr "- wyprowadzona wartość dziury %d, widziano %d, blok %d, i-węzeł katalogu %\n" +msgid "%s: not fsys dev, dir, or reg file, ignoring\n" +msgstr "%s: nie jest urządzeniem z systemem plików, katalogiem ani zwykłym plikiem, zignorowano\n" -#: .././repair/dir.c:712 +#: .././fsr/xfs_fsr.c:387 #, c-format -msgid "- derived hole (base %d, size %d) in block %d, dir inode % not found\n" -msgstr "- wyprowadzona dziura (podstawa %d, rozmiar %d) w bloku %d, i-węzeł katalogu % nie znaleziona\n" +msgid "" +"Usage: %s [-d] [-v] [-g] [-t time] [-p passes] [-f leftf] [-m mtab]\n" +" %s [-d] [-v] [-g] xfsdev | dir | file ...\n" +" %s -V\n" +"\n" +"Options:\n" +" -g Print to syslog (default if stdout not a tty).\n" +" -t time How long to run in seconds.\n" +" -p passes Number of passes before terminating global re-org.\n" +" -f leftoff Use this instead of %s.\n" +" -m mtab Use something other than /etc/mtab.\n" +" -d Debug, print even more.\n" +" -v Verbose, more -v's more verbose.\n" +" -V Print version number and exit.\n" +msgstr "" +"Składnia: %s [-d] [-v] [-g] [-t czas] [-p przebiegi] [-f leftf] [-m mtab]\n" +" %s [-d] [-v] [-g] xfsdev | katalog | plik ...\n" +" %s -V\n" +"\n" +"Opcje:\n" +" -g Pisanie do sysloga (domyślne jeśli stdout to nie tty).\n" +" -t czas Czas działania w sekundach.\n" +" -p przebiegi Liczba przebiegów przed zakończeniem reorganizacji.\n" +" -f leftoff Użycie tego pliku zamiast %s.\n" +" -m mtab Użycie pliku innego niż /etc/mtab.\n" +" -d Diagnostyka, dużo więcej informacji.\n" +" -v Tym więcej szczegółów, im więcej opcji -v.\n" +" -V Wypisanie informacji o wersji i zakończenie.\n" -#: .././repair/dir.c:767 .././repair/phase6.c:1214 .././repair/phase6.c:1583 +#: .././fsr/xfs_fsr.c:417 #, c-format -msgid "can't read block %u (fsbno %) for directory inode %\n" -msgstr "nie można odczytać bloku %u (fsbno %) dla i-węzła katalogu %\n" +msgid "could not open mtab file: %s\n" +msgstr "nie udało się otworzyć pliku mtab: %s\n" -#: .././repair/dir.c:771 +#: .././fsr/xfs_fsr.c:423 .././fsr/xfs_fsr.c:455 #, c-format -msgid "can't read block %u (fsbno %) for attrbute fork of inode %\n" -msgstr "nie można odczytać bloku %u (fsbno %) dla gałęzi atrybutów i-węzła %\n" +msgid "out of memory: %s\n" +msgstr "brak pamięci: %s\n" -#: .././repair/dir.c:779 .././repair/phase6.c:1224 +#: .././fsr/xfs_fsr.c:446 #, c-format -msgid "bad dir/attr magic number in inode %, file bno = %u, fsbno = %\n" -msgstr "błędna liczba magiczna katalogu/atrybutu w i-węźle %, bno pliku = %u, fsbno = %\n" +msgid "Skipping %s: not mounted rw\n" +msgstr "Pominięto %s: nie zamontowany rw\n" -#: .././repair/dir.c:787 .././repair/dir2.c:333 +#: .././fsr/xfs_fsr.c:460 #, c-format -msgid "bad record count in inode %, count = %d, max = %d\n" -msgstr "błędna liczba rekordów w i-węźle %, liczba = %d, maksimum = %d\n" +msgid "out of memory on realloc: %s\n" +msgstr "brak pamięci przy realloc: %s\n" -#: .././repair/dir.c:806 .././repair/dir2.c:356 +#: .././fsr/xfs_fsr.c:471 .././fsr/xfs_fsr.c:475 #, c-format -msgid "bad directory btree for directory inode %\n" -msgstr "błędne b-drzewo katalogu dla i-węzła katalogu %\n" +msgid "strdup(%s) failed\n" +msgstr "strdup(%s) nie powiodło się\n" -#: .././repair/dir.c:810 +#: .././fsr/xfs_fsr.c:485 #, c-format -msgid "bad attribute fork btree for inode %\n" -msgstr "błędne b-drzewo gałęzi atrybutów dla i-węzła %\n" +msgid "no rw xfs file systems in mtab: %s\n" +msgstr "brak w pliku mtab systemów plików xfs w trybie rw: %s\n" -#: .././repair/dir.c:864 +#: .././fsr/xfs_fsr.c:489 #, c-format -msgid "release_da_cursor_int got unexpected non-null bp, dabno = %u\n" -msgstr "release_da_cursor_int otrzymało nieoczekiwany niepusty bp, dabno = %u\n" +msgid "Found %d mounted, writable, XFS filesystems\n" +msgstr "Liczba znalezionych zamontowanych, zapisywalnych systemów plików XFS: %d\n" -#: .././repair/dir.c:931 +#: .././fsr/xfs_fsr.c:519 #, c-format -msgid "directory/attribute block used/count inconsistency - %d/%hu\n" -msgstr "niespójność wartości used/count bloku katalogu/atrybutu - %d/%hu\n" +msgid "%s: open failed\n" +msgstr "%s: open nie powiodło się\n" -#: .././repair/dir.c:941 .././repair/dir2.c:478 +#: .././fsr/xfs_fsr.c:534 #, c-format -msgid "directory/attribute block hashvalue inconsistency, expected > %u / saw %u\n" -msgstr "niespójność wartości hasza bloku katalogu/atrybutu - oczekiwano > %u, widziano %u\n" +msgid "Can't use %s: mode=0%o own=%d nlink=%d\n" +msgstr "Nie można użyć %s: mode=0%o own=%d nlink=%d\n" -#: .././repair/dir.c:948 .././repair/dir2.c:485 +#: .././fsr/xfs_fsr.c:554 #, c-format -msgid "bad directory/attribute forward block pointer, expected 0, saw %u\n" -msgstr "błędny wskaźnik bloku w przód katalogu/atrybutu - oczekiwano 0, widziano %u\n" +msgid "could not read %s, starting with %s\n" +msgstr "nie można odczytać %s, rozpoczęcie z %s\n" -#: .././repair/dir.c:954 +#: .././fsr/xfs_fsr.c:593 #, c-format -msgid "bad directory block in dir ino %\n" -msgstr "błędny blok katalogu w i-węźle katalogu %\n" +msgid "START: pass=%d ino=%llu %s %s\n" +msgstr "START: przebieg=%d i-węzeł=%llu %s %s\n" -#: .././repair/dir.c:984 +#: .././fsr/xfs_fsr.c:610 #, c-format -msgid "" -"correcting bad hashval in non-leaf dir/attr block\n" -"\tin (level %d) in inode %.\n" -msgstr "" -"poprawiono błędne hashval w bloku katalogu/atrybutu nie będącego liściem\n" -"\tw i-węźle (poziomu %d) %.\n" +msgid "Completed all %d passes\n" +msgstr "Zakończono wszystkie przebiegi w liczbie %d\n" -#: .././repair/dir.c:992 -#, c-format -msgid "" -"would correct bad hashval in non-leaf dir/attr block\n" -"\tin (level %d) in inode %.\n" -msgstr "" -"błędne hashval zostałoby poprawione w bloku katalogu/atrybutu nie będącego liściem\n" -"\tw i-węźle (poziomu %d) %.\n" +#: .././fsr/xfs_fsr.c:620 +msgid "couldn't fork sub process:" +msgstr "nie udało się uruchomić podprocesu:" -#: .././repair/dir.c:1130 .././repair/dir2.c:652 +#: .././fsr/xfs_fsr.c:655 #, c-format -msgid "can't get map info for block %u of directory inode %\n" -msgstr "nie można uzyskać informacji o mapie dla bloku %u i-węzła katalogu %\n" +msgid "%s startpass %d, endpass %d, time %d seconds\n" +msgstr "%s pocz. przebieg %d, końc. przebieg %d, czas %d sekund\n" -#: .././repair/dir.c:1140 +#: .././fsr/xfs_fsr.c:662 #, c-format -msgid "can't read block %u (%) for directory inode %\n" -msgstr "nie można odczytać bloku %u (%) dla i-węzła katalogu %\n" +msgid "open(%s) failed: %s\n" +msgstr "open(%s) nie powiodło się: %s\n" -#: .././repair/dir.c:1153 +#: .././fsr/xfs_fsr.c:668 #, c-format -msgid "bad magic number %x in block %u (%) for directory inode %\n" -msgstr "błędna liczba magiczna %x w bloku %u (%) dla i-węzła katalogu %\n" +msgid "write(%s) failed: %s\n" +msgstr "write(%s) nie powiodło się: %s\n" -#: .././repair/dir.c:1161 +#: .././fsr/xfs_fsr.c:692 #, c-format -msgid "bad back pointer in block %u (%) for directory inode %\n" -msgstr "błędny wskaźnik wstecz w bloku %u (%) dla i-węzła katalogu %\n" +msgid "%s start inode=%llu\n" +msgstr "%s pocz. i-węzeł=%llu\n" -#: .././repair/dir.c:1167 +#: .././fsr/xfs_fsr.c:697 #, c-format -msgid "entry count %d too large in block %u (%) for directory inode %\n" -msgstr "liczba wpisów %d zbyt duża w bloku %u (%) dla i-węzła katalogu %\n" +msgid "unable to get handle: %s: %s\n" +msgstr "nie udało się uzyskać uchwytu: %s: %s\n" -#: .././repair/dir.c:1174 +#: .././fsr/xfs_fsr.c:703 #, c-format -msgid "bad level %d in block %u (%) for directory inode %\n" -msgstr "błędny poziom %d w bloku %u (%) dla i-węzła katalogu %\n" +msgid "unable to open: %s: %s\n" +msgstr "nie udało się otworzyć: %s: %s\n" -#: .././repair/dir.c:1231 +#: .././fsr/xfs_fsr.c:709 #, c-format -msgid "" -"correcting bad hashval in interior dir/attr block\n" -"\tin (level %d) in inode %.\n" -msgstr "" -"poprawiono błędne hashval w wewnętrznym bloku katalogu/atrybutu\n" -"\tw i-węźle (poziomu %d) %.\n" +msgid "Skipping %s: could not get XFS geometry\n" +msgstr "Pominięto %s: nie można odczytać geometrii XFS\n" -#: .././repair/dir.c:1239 +#: .././fsr/xfs_fsr.c:743 #, c-format -msgid "" -"would correct bad hashval in interior dir/attr block\n" -"\tin (level %d) in inode %.\n" -msgstr "" -"błędne hashval zostałoby poprawione w wewnętrznym bloku katalogu/atrybutu\n" -"\tw i-węźle (poziomu %d) %.\n" +msgid "could not open: inode %llu\n" +msgstr "nie udało się otworzyć: i-węzeł %llu\n" -#: .././repair/dir.c:1347 +#: .././fsr/xfs_fsr.c:773 #, c-format -msgid "directory block header conflicts with used space in directory inode %\n" -msgstr "nagłówek bloku katalogu jest w konflikcie z użytym miejscem w i-węźle katalogu %\n" +msgid "%s: xfs_bulkstat: %s\n" +msgstr "%s: xfs_bulkstat: %s\n" -#: .././repair/dir.c:1377 +#: .././fsr/xfs_fsr.c:799 #, c-format -msgid "nameidx %d for entry #%d, bno %d, ino % > fs blocksize, deleting entry\n" -msgstr "nameidx %d dla wpisu #%d, bno %d, i-węzeł % > rozmiaru bloku fs, usunięto wpis\n" +msgid "%s: Directory defragmentation not supported\n" +msgstr "%s: Defragmentacja katalogów nie jest obsługiwana\n" -#: .././repair/dir.c:1414 +#: .././fsr/xfs_fsr.c:818 #, c-format -msgid "nameidx %d, entry #%d, bno %d, ino % > fs blocksize, marking entry bad\n" -msgstr "nameidx %d, wpis #%d, bno %d, i-węzeł % > rozmiaru bloku fs, zaznaczono wpis jako błędny\n" +msgid "unable to construct sys handle for %s: %s\n" +msgstr "nie udało się utworzyć uchwytu systemowego dla %s: %s\n" -#: .././repair/dir.c:1429 +#: .././fsr/xfs_fsr.c:829 #, c-format -msgid "nameidx %d, entry #%d, bno %d, ino % > fs blocksize, would delete entry\n" -msgstr "nameidx %d, wpis #%d, bno %d, i-węzeł % > rozmiaru bloku fs, wpis zostałby usunięty\n" +msgid "unable to open sys handle for %s: %s\n" +msgstr "nie udało się otworzyć uchwytu systemowego dla %s: %s\n" -#: .././repair/dir.c:1466 +#: .././fsr/xfs_fsr.c:835 #, c-format -msgid "invalid ino number % in dir ino %, entry #%d, bno %d\n" -msgstr "nieprawidłowy numer i-węzła % w i-węźle katalogu %, wpis #%d, bno %d\n" +msgid "unable to get bstat on %s: %s\n" +msgstr "nie udało się uzyskać bstat na %s: %s\n" -#: .././repair/dir.c:1470 .././repair/dir.c:1486 .././repair/dir.c:1503 -#: .././repair/dir.c:1519 .././repair/dir.c:1536 +#: .././fsr/xfs_fsr.c:843 #, c-format -msgid "\tclearing ino number in entry %d...\n" -msgstr "\twyczyszczono numer i-węzła we wpisie %d...\n" +msgid "unable to open handle %s: %s\n" +msgstr "nie udało się otworzyć uchwytu %s: %s\n" -#: .././repair/dir.c:1477 .././repair/dir.c:1494 .././repair/dir.c:1510 -#: .././repair/dir.c:1527 .././repair/dir.c:1544 +#: .././fsr/xfs_fsr.c:851 #, c-format -msgid "\twould clear ino number in entry %d...\n" -msgstr "\tnumer i-węzła we wpisie %d zostałby wyczyszczony...\n" +msgid "Unable to get geom on fs for: %s\n" +msgstr "Nie udało się odczytać geometrii systemu plików dla: %s\n" -#: .././repair/dir.c:1482 +#: .././fsr/xfs_fsr.c:900 #, c-format -msgid "entry #%d, bno %d in directory % references realtime bitmap inode %\n" -msgstr "wpis #%d, bno %d w katalogu % odwołuje się do i-węzła bitmapy realtime %\n" +msgid "sync failed: %s: %s\n" +msgstr "sync nie powiodło się: %s: %s\n" -#: .././repair/dir.c:1499 +#: .././fsr/xfs_fsr.c:906 #, c-format -msgid "entry #%d, bno %d in directory % references realtime summary inode %\n" -msgstr "wpis #%d, bno %d w katalogu % odwołuje się do i-węzła opisu realtime %\n" +msgid "%s: zero size, ignoring\n" +msgstr "%s: zerowy rozmiar, zignorowano\n" -#: .././repair/dir.c:1515 +#: .././fsr/xfs_fsr.c:925 #, c-format -msgid "entry #%d, bno %d in directory % references user quota inode %\n" -msgstr "wpis #%d, bno %d w katalogu % odwołuje się do i-węzła limitu użytkownika %\n" +msgid "locking check failed: %s\n" +msgstr "sprawdzenie blokowania nie powiodło się: %s\n" -#: .././repair/dir.c:1532 +#: .././fsr/xfs_fsr.c:932 #, c-format -msgid "entry #%d, bno %d in directory % references group quota inode %\n" -msgstr "wpis #%d, bno %d w katalogu % odwołuje się do i-węzła limitu grupy %\n" +msgid "mandatory lock: %s: ignoring\n" +msgstr "obowiązkowa blokada: %s: zignorowano\n" -#: .././repair/dir.c:1569 +#: .././fsr/xfs_fsr.c:945 #, c-format -msgid "entry references free inode % in directory %, will clear entry\n" -msgstr "wpis odwołuje się do wolnego i-węzła % w katalogu %, zostanie wyczyszczony\n" +msgid "unable to get fs stat on %s: %s\n" +msgstr "nie udało się uzyskać stat fs na %s: %s\n" -#: .././repair/dir.c:1577 +#: .././fsr/xfs_fsr.c:952 #, c-format -msgid "entry references free inode % in directory %, would clear entry\n" -msgstr "wpis odwołuje się do wolnego i-węzła % w katalogu %, zostałby wyczyszczony\n" +msgid "insufficient freespace for: %s: size=%lld: ignoring\n" +msgstr "niewystarczająca ilość miejsca dla: %s: rozmiar=%lld: zignorowano\n" -#: .././repair/dir.c:1585 +#: .././fsr/xfs_fsr.c:959 #, c-format -msgid "bad ino number % in dir ino %, entry #%d, bno %d\n" -msgstr "błędny numer i-węzła % w i-węźle katalogu %, wpis #%d, bno %d\n" - -#: .././repair/dir.c:1588 -msgid "clearing inode number...\n" -msgstr "wyczyszczono numer i-węzła...\n" - -#: .././repair/dir.c:1593 -msgid "would clear inode number...\n" -msgstr "numer i-węzła zostałby wyczyszczony\n" +msgid "failed to get inode attrs: %s\n" +msgstr "nie udało się uzyskać atrybutów i-węzła: %s\n" -#: .././repair/dir.c:1613 +#: .././fsr/xfs_fsr.c:964 #, c-format -msgid "entry #%d, dir inode %, has zero-len name, deleting entry\n" -msgstr "wpis #%d, i-węzeł katalogu % ma nazwę zerowej długości, usunięto\n" +msgid "%s: immutable/append, ignoring\n" +msgstr "%s: niezmienny/tylko do dołączania, zignorowano\n" -#: .././repair/dir.c:1651 +#: .././fsr/xfs_fsr.c:969 #, c-format -msgid "entry #%d, dir inode %, has zero-len name, marking entry bad\n" -msgstr "wpis #%d, i-węzeł katalogu % ma nazwę zerowej długości, zaznaczono jako błędny\n" +msgid "%s: marked as don't defrag, ignoring\n" +msgstr "%s: oznaczony jako nie do defragmentacji, zignorowano\n" -#: .././repair/dir.c:1664 +#: .././fsr/xfs_fsr.c:975 #, c-format -msgid "bad size, entry #%d in dir inode %, block %u -- entry overflows block\n" -msgstr "błędny rozmiar, wpis #%d w i-węźle katalogu %, blok %u - wpis wykracza poza blok\n" +msgid "cannot get realtime geometry for: %s\n" +msgstr "nie można uzyskać geometrii realtime dla: %s\n" -#: .././repair/dir.c:1675 +#: .././fsr/xfs_fsr.c:980 #, c-format -msgid "dir entry slot %d in block %u conflicts with used space in dir inode %\n" -msgstr "slot wpisu katalogu %d w bloku %u jest w konflikcie z użytym miejscem w i-węźle katalogu %\n" +msgid "low on realtime free space: %s: ignoring file\n" +msgstr "mało wolnego miejsca realtime: %s: plik zignorowany\n" -#: .././repair/dir.c:1715 +#: .././fsr/xfs_fsr.c:987 #, c-format -msgid "illegal name \"%s\" in directory inode %, entry will be cleared\n" -msgstr "niedozwolona nazwa \"%s\" w i-węźle katalogu %, wpis zostanie wyczyszczony\n" +msgid "cannot open: %s: Permission denied\n" +msgstr "nie można otworzyć: %s: brak uprawnień\n" -#: .././repair/dir.c:1721 -#, c-format -msgid "illegal name \"%s\" in directory inode %, entry would be cleared\n" -msgstr "niedozwolona nazwa \"%s\" w i-węźle katalogu %, wpis zostałby wyczyszczony\n" +#: .././fsr/xfs_fsr.c:1045 .././fsr/xfs_fsr.c:1095 .././fsr/xfs_fsr.c:1187 +msgid "could not set ATTR\n" +msgstr "nie udało się ustawić ATTR\n" -#: .././repair/dir.c:1731 +#: .././fsr/xfs_fsr.c:1054 #, c-format -msgid "\tmismatched hash value for entry \"%s\"\n" -msgstr "\tniedopasowana wartość hasza dla wpisu \"%s\"\n" +msgid "unable to stat temp file: %s\n" +msgstr "nie udało się wykonać stat na pliku tymczasowym: %s\n" -#: .././repair/dir.c:1735 +#: .././fsr/xfs_fsr.c:1072 #, c-format -msgid "\t\tin directory inode %. resetting hash value.\n" -msgstr "\t\tw i-węźle katalogu %. Przestawiono wartość hasza.\n" +msgid "unable to get bstat on temp file: %s\n" +msgstr "nie udało się uzyskać bstat pliku tymczasowego: %s\n" -#: .././repair/dir.c:1741 +#: .././fsr/xfs_fsr.c:1077 #, c-format -msgid "\t\tin directory inode %. would reset hash value.\n" -msgstr "\t\tw i-węźle katalogu %. Wartość hasza zostałaby przestawiona.\n" +msgid "orig forkoff %d, temp forkoff %d\n" +msgstr "orig forkoff %d, temp forkoff %d\n" -#: .././repair/dir.c:1771 -#, c-format -msgid "\tbad hash ordering for entry \"%s\"\n" -msgstr "\tbłędny porządek hasza dla wpisu \"%s\"\n" +#: .././fsr/xfs_fsr.c:1126 +msgid "FSGETXATTRA failed on target\n" +msgstr "FSGETXATTRA nie powiodło się na docelowym urządzeniu\n" + +#: .././fsr/xfs_fsr.c:1142 +msgid "big ATTR set failed\n" +msgstr "duży zbiór ATTR nie powiódł się\n" -#: .././repair/dir.c:1775 +#: .././fsr/xfs_fsr.c:1163 #, c-format -msgid "\t\tin directory inode %. will clear entry\n" -msgstr "\t\tw i-węźle katalogu %. Wpis zostanie wyczyszczony.\n" +msgid "forkoff diff %d too large!\n" +msgstr "różnica forkoff %d zbyt duża!\n" -#: .././repair/dir.c:1782 +#: .././fsr/xfs_fsr.c:1180 #, c-format -msgid "\t\tin directory inode %. would clear entry\n" -msgstr "\t\tw i-węźle katalogu %. Wpis zostałby wyczyszczony.\n" +msgid "data fork growth unimplemented\n" +msgstr "powiększanie odgałęzienia danych nie jest zaimplementowane\n" -#: .././repair/dir.c:1798 -#, c-format -msgid "name \"%s\" (block %u, slot %d) conflicts with used space in dir inode %\n" -msgstr "nazwa \"%s\" (blok %u, slot %d) jest w konflikcie z użytym miejscem w i-węźle katalogu %\n" +#: .././fsr/xfs_fsr.c:1195 +msgid "set temp attr\n" +msgstr "ustawianie atrybutów pliku tymczasowego\n" -#: .././repair/dir.c:1805 -#, c-format -msgid "will clear entry \"%s\" (#%d) in directory inode %\n" -msgstr "wpis \"%s\" (#%d) zostanie wyczyszczony w i-węźle katalogu %\n" +#: .././fsr/xfs_fsr.c:1198 +msgid "failed to match fork offset\n" +msgstr "nie udało się dopasować offsetu odgałęzienia\n" -#: .././repair/dir.c:1809 +#: .././fsr/xfs_fsr.c:1244 #, c-format -msgid "would clear entry \"%s\" (#%d)in directory inode %\n" -msgstr "wpis \"%s\" (#%d) zostałby wyczyszczony w i-węźle katalogu %\n" +msgid "%s already fully defragmented.\n" +msgstr "%s jest już całkowicie zdefragmentowany.\n" -#: .././repair/dir.c:1845 +#: .././fsr/xfs_fsr.c:1250 #, c-format -msgid "bad .. entry in dir ino %, points to self" -msgstr "błędny wpis .. w i-węźle katalogu %, wskazuje na siebie" - -#: .././repair/dir.c:1849 .././repair/dir.c:1946 -msgid "will clear entry\n" -msgstr "wpis zostanie wyczyszczony\n" - -#: .././repair/dir.c:1854 .././repair/dir.c:1950 .././repair/dir2.c:1642 -msgid "would clear entry\n" -msgstr "wpis zostałby wyczyszczony\n" +msgid "%s extents=%d can_save=%d tmp=%s\n" +msgstr "%s extents=%d can_save=%d tmp=%s\n" -#: .././repair/dir.c:1864 +#: .././fsr/xfs_fsr.c:1256 #, c-format -msgid "correcting .. entry in root inode %, was %\n" -msgstr "poprawiono wpis .. w głównym i-węźle %, było %\n" +msgid "could not open tmp file: %s: %s\n" +msgstr "nie udało się otworzyć pliku tymczasowego: %s: %s\n" -#: .././repair/dir.c:1871 +#: .././fsr/xfs_fsr.c:1264 #, c-format -msgid "bad .. entry (%) in root inode % should be %\n" -msgstr "błędny wpis .. (%) w głównym i-węźle %, powinno być %\n" +msgid "failed to set ATTR fork on tmp: %s:\n" +msgstr "nie udało się ustawić odgałęzienia ATTR na tmp: %s\n" -#: .././repair/dir.c:1888 +#: .././fsr/xfs_fsr.c:1271 #, c-format -msgid "multiple .. entries in directory inode %, will clear second entry\n" -msgstr "wiele wpisów .. w i-węźle katalogu %, drugi wpis zostanie wyczyszczony\n" +msgid "could not set inode attrs on tmp: %s\n" +msgstr "nie udało się ustawić atrybutów i-węzła na tmp: %s\n" -#: .././repair/dir.c:1894 +#: .././fsr/xfs_fsr.c:1278 #, c-format -msgid "multiple .. entries in directory inode %, would clear second entry\n" -msgstr "wiele wpisów .. w i-węźle katalogu %, drugi wpis zostałby wyczyszczony\n" +msgid "could not get DirectIO info on tmp: %s\n" +msgstr "nie udało się uzyskać informacji o bezpośrednim we/wy na tmp: %s\n" -#: .././repair/dir.c:1907 +#: .././fsr/xfs_fsr.c:1293 #, c-format -msgid ". in directory inode % has wrong value (%), fixing entry...\n" -msgstr ". w i-węźle katalogu % ma niepoprawną wartość (%), poprawiono wpis...\n" +msgid "DEBUG: fsize=%lld blsz_dio=%d d_min=%d d_max=%d pgsz=%d\n" +msgstr "DEBUG: fsize=%lld blsz_dio=%d d_min=%d d_max=%d pgsz=%d\n" -#: .././repair/dir.c:1914 +#: .././fsr/xfs_fsr.c:1300 #, c-format -msgid ". in directory inode % has wrong value (%)\n" -msgstr ". w i-węźle katalogu % ma niepoprawną wartość (%)\n" +msgid "could not allocate buf: %s\n" +msgstr "nie udało się przydzielić bufora: %s\n" -#: .././repair/dir.c:1920 +#: .././fsr/xfs_fsr.c:1310 #, c-format -msgid "multiple . entries in directory inode %\n" -msgstr "wiele wpisów . w i-węźle katalogu %\n" +msgid "could not open fragfile: %s : %s\n" +msgstr "nie udało się otworzyć pliku frag: %s: %s\n" -#: .././repair/dir.c:1927 +#: .././fsr/xfs_fsr.c:1325 #, c-format -msgid "will clear one . entry in directory inode %\n" -msgstr "jeden wpis . w i-węźle katalogu % zostanie wyczyszczony\n" +msgid "could not trunc tmp %s\n" +msgstr "nie udało się uciąć tmp %s\n" -#: .././repair/dir.c:1933 +#: .././fsr/xfs_fsr.c:1329 .././fsr/xfs_fsr.c:1349 .././fsr/xfs_fsr.c:1377 #, c-format -msgid "would clear one . entry in directory inode %\n" -msgstr "jeden wpis . w i-węźle katalogu % zostałby wyczyszczony\n" +msgid "could not lseek in tmpfile: %s : %s\n" +msgstr "nie udało się przemieścić (lseek) w pliku tymczasowym: %s: %s\n" -#: .././repair/dir.c:1943 +#: .././fsr/xfs_fsr.c:1344 #, c-format -msgid "entry \"%s\" in directory inode % points to self, " -msgstr "wpis \"%s\" w i-węźle katalogu % wskazuje na siebie, " +msgid "could not pre-allocate tmp space: %s\n" +msgstr "nie udało się wstępnie przydzielić miejsca tmp: %s\n" -#: .././repair/dir.c:1968 -#, c-format -msgid "- resetting first used heap value from %d to %d in block %u of dir ino %\n" -msgstr "- przestawiono pierwszą używaną wartość sterty z %d na %d w bloku %u i-węzła katalogu %\n" +#: .././fsr/xfs_fsr.c:1357 +msgid "Couldn't rewind on temporary file\n" +msgstr "Nie udało się przewinąć pliku tymczasowego\n" -#: .././repair/dir.c:1976 +#: .././fsr/xfs_fsr.c:1364 #, c-format -msgid "- would reset first used value from %d to %d in block %u of dir ino %\n" -msgstr "- pierwsza używana wartość zostałaby przestawiona z %d na %d w bloku %u i-węzła katalogu %\n" +msgid "Temporary file has %d extents (%d in original)\n" +msgstr "Plik tymczasowy ma ekstentów: %d (%d w oryginale)\n" -#: .././repair/dir.c:1986 +#: .././fsr/xfs_fsr.c:1367 #, c-format -msgid "- resetting namebytes cnt from %d to %d in block %u of dir inode %\n" -msgstr "- przestawiono liczbę bajtów nazwy z %d na %d w bloku %u i-węzła katalogu %\n" +msgid "No improvement will be made (skipping): %s\n" +msgstr "Nie nastąpi poprawa (pominięto): %s\n" -#: .././repair/dir.c:1994 +#: .././fsr/xfs_fsr.c:1382 #, c-format -msgid "- would reset namebytes cnt from %d to %d in block %u of dir inode %\n" -msgstr "- liczba bajtów nazwy zostałaby przestawiona z %d na %d w bloku %u i-węzła katalogu %\n" +msgid "could not lseek in file: %s : %s\n" +msgstr "nie udało się przemieścić (lseek) w pliku: %s: %s\n" -#: .././repair/dir.c:2029 +#: .././fsr/xfs_fsr.c:1418 #, c-format -msgid "- found unexpected lost holes in block %u, dir inode %\n" -msgstr "- znaleziono nieoczekiwane utracone dziury w bloku %u, i-węźle katalogu %\n" +msgid "bad read of %d bytes from %s: %s\n" +msgstr "błędny odczyt %d bajtów z %s: %s\n" -#: .././repair/dir.c:2037 +#: .././fsr/xfs_fsr.c:1422 .././fsr/xfs_fsr.c:1454 #, c-format -msgid "- hole info non-optimal in block %u, dir inode %\n" -msgstr "- nieoptymalna informacja o dziurze w bloku %u, i-węźle katalogu %\n" +msgid "bad write of %d bytes to %s: %s\n" +msgstr "błędny zapis %d bajtów do %s: %s\n" -#: .././repair/dir.c:2044 +#: .././fsr/xfs_fsr.c:1439 #, c-format -msgid "- hole info incorrect in block %u, dir inode %\n" -msgstr "- niepoprawna informacja o dziurze w bloku %u, i-węźle katalogu %\n" +msgid "bad write2 of %d bytes to %s: %s\n" +msgstr "błędny zapis 2 %d bajtów do %s: %s\n" -#: .././repair/dir.c:2055 +#: .././fsr/xfs_fsr.c:1444 #, c-format -msgid "- existing hole info for block %d, dir inode % (base, size) - \n" -msgstr "- istniejąca informacja o dziurze dla bloku %d, i-węzła katalogu % (podstawa, rozmiar) - \n" +msgid "bad copy to %s\n" +msgstr "błędna kopia do %s\n" -#: .././repair/dir.c:2063 +#: .././fsr/xfs_fsr.c:1462 #, c-format -msgid "- holes flag = %d\n" -msgstr "- flaga dziur = %d\n" +msgid "could not truncate tmpfile: %s : %s\n" +msgstr "nie udało się obciąć pliku tymczasowego: %s: %s\n" -#: .././repair/dir.c:2069 +#: .././fsr/xfs_fsr.c:1467 #, c-format -msgid "- compacting block %u in dir inode %\n" -msgstr "- zagęszczono blok %u w i-węźle katalogu %\n" +msgid "could not fsync tmpfile: %s : %s\n" +msgstr "nie udało się wykonać fsync pliku tymczasowego: %s: %s\n" -#: .././repair/dir.c:2110 +#: .././fsr/xfs_fsr.c:1482 #, c-format -msgid "not enough space in block %u of dir inode % for all entries\n" -msgstr "zbyt mało miejsca dla wszystkich wpisów w bloku %u i-węzła katalogu %\n" +msgid "failed to fchown tmpfile %s: %s\n" +msgstr "nie udało się wykonać fchown na pliku tymczasowym %s: %s\n" -#: .././repair/dir.c:2180 +#: .././fsr/xfs_fsr.c:1492 #, c-format -msgid "- would compact block %u in dir inode %\n" -msgstr "- bloku %u w i-węźle katalogu % zostałby zagęszczony\n" +msgid "%s: file type not supported\n" +msgstr "%s: tym pliku nie obsługiwany\n" -#: .././repair/dir.c:2245 .././repair/dir2.c:1828 +#: .././fsr/xfs_fsr.c:1496 #, c-format -msgid "can't map block %u for directory inode %\n" -msgstr "nie można odwzorować bloku %u dla i-węzła katalogu %\n" +msgid "%s: file modified defrag aborted\n" +msgstr "%s: plik zmodyfikowany, defragmentacja przerwana\n" -#: .././repair/dir.c:2256 +#: .././fsr/xfs_fsr.c:1501 #, c-format -msgid "can't read file block %u (fsbno %, daddr %) for directory inode %\n" -msgstr "nie można odczytać bloku pliku %u (fsbno %, daddr %) dla i-węzła katalogu %\n" +msgid "%s: file busy\n" +msgstr "%s: plik zajęty\n" -#: .././repair/dir.c:2270 .././repair/dir.c:2529 +#: .././fsr/xfs_fsr.c:1503 #, c-format -msgid "bad directory leaf magic # %#x for dir ino %\n" -msgstr "błędna liczba magiczna liścia katalogu %#x dla i-węzła katalogu %\n" +msgid "XFS_IOC_SWAPEXT failed: %s: %s\n" +msgstr "XFS_IOC_SWAPEXT nie powiodło się: %s: %s\n" -#: .././repair/dir.c:2310 +#: .././fsr/xfs_fsr.c:1511 #, c-format -msgid "bad sibling back pointer for directory block %u in directory inode %\n" -msgstr "błędny wskaźnik wstecz dla bloku katalogu %u w i-węźle katalogu %\n" +msgid "extents before:%d after:%d %s %s\n" +msgstr "ekstentów przed: %d po: %d %s %s\n" -#: .././repair/dir.c:2341 .././repair/dir2.c:1904 +#: .././fsr/xfs_fsr.c:1545 #, c-format -msgid "bad hash path in directory %\n" -msgstr "błędna ścieżka hasza w katalogu %\n" +msgid "tmp file name too long: %s\n" +msgstr "nazwa pliku tymczasowego zbyt długa: %s\n" -#: .././repair/dir.c:2450 +#: .././fsr/xfs_fsr.c:1595 #, c-format -msgid "out of range internal directory block numbers (inode %)\n" -msgstr "numery bloków wewnętrznego katalogu spoza zakresu (i-węzeł %)\n" +msgid "realloc failed: %s\n" +msgstr "realloc nie powiodło się: %s\n" -#: .././repair/dir.c:2456 +#: .././fsr/xfs_fsr.c:1608 #, c-format -msgid "setting directory inode (%) size to % bytes, was % bytes\n" -msgstr "ustawiono rozmiar i-węzła katalogu (%) na % bajtów, było % bajtów\n" +msgid "malloc failed: %s\n" +msgstr "malloc nie powiodło się: %s\n" -#: .././repair/dir.c:2509 +#: .././fsr/xfs_fsr.c:1638 #, c-format -msgid "block 0 for directory inode % is missing\n" -msgstr "brak bloku 0 dla i-węzła katalogu %\n" +msgid "failed reading extents: inode %llu" +msgstr "nie udało się odczytać ekstentów: i-węzeł %llu" -#: .././repair/dir.c:2516 -#, c-format -msgid "can't read block 0 for directory inode %\n" -msgstr "nie można odczytać bloku 0 dla i-węzła katalogu %\n" +#: .././fsr/xfs_fsr.c:1688 +msgid "failed reading extents" +msgstr "nie udało się odczytać ekstentów" -#: .././repair/dir.c:2552 +#: .././fsr/xfs_fsr.c:1776 .././fsr/xfs_fsr.c:1790 #, c-format -msgid "clearing forw/back pointers for directory inode %\n" -msgstr "wyczyszczono wskaźniki w przód/wstecz dla i-węzła katalogu %\n" +msgid "tmpdir already exists: %s\n" +msgstr "katalog tymczasowy już istnieje: %s\n" -#: .././repair/dir.c:2558 +#: .././fsr/xfs_fsr.c:1779 #, c-format -msgid "would clear forw/back pointers for directory inode %\n" -msgstr "wskaźniki w przód/wstecz dla i-węzła katalogu % zostałyby wyczyszczone\n" +msgid "could not create tmpdir: %s: %s\n" +msgstr "nie udało się utworzyć katalogu tymczasowego: %s: %s\n" -#: .././repair/dir.c:2623 .././repair/dir2.c:2109 +#: .././fsr/xfs_fsr.c:1792 #, c-format -msgid "no . entry for directory %\n" -msgstr "brak wpisu . dla katalogu %\n" +msgid "cannot create tmpdir: %s: %s\n" +msgstr "nie można utworzyć katalogu tymczasowego: %s: %s\n" -#: .././repair/dir.c:2632 .././repair/dir2.c:2119 +#: .././fsr/xfs_fsr.c:1830 .././fsr/xfs_fsr.c:1838 #, c-format -msgid "no .. entry for directory %\n" -msgstr "brak wpisu .. dla katalogu %\n" - -#: .././repair/dir.c:2634 .././repair/dir2.c:2121 -#, c-format -msgid "no .. entry for root directory %\n" -msgstr "brak wpisu .. dla katalogu głównego %\n" - -#: .././repair/dir2.c:57 -#, c-format -msgid "malloc failed (%zu bytes) dir2_add_badlist:ino %\n" -msgstr "malloc nie powiodło się (%zu bajtów) w dir2_add_badlist:ino %\n" - -#: .././repair/dir2.c:98 .././repair/dir2.c:209 .././repair/dir2.c:245 -msgid "couldn't malloc dir2 buffer list\n" -msgstr "nie można przydzielić listy bufora dir2\n" - -#: .././repair/dir2.c:125 -msgid "couldn't malloc dir2 buffer header\n" -msgstr "nie można przydzielić nagłówka bufora dir2\n" - -#: .././repair/dir2.c:142 -msgid "couldn't malloc dir2 buffer data\n" -msgstr "nie można przydzielić danych bufora dir2\n" - -#: .././repair/dir2.c:305 .././repair/dir2.c:663 .././repair/dir2.c:1709 -#: .././repair/phase6.c:2290 -#, c-format -msgid "can't read block %u for directory inode %\n" -msgstr "nie można odczytać bloku %u dla i-węzła katalogu %\n" - -#: .././repair/dir2.c:315 -#, c-format -msgid "found non-root LEAFN node in inode % bno = %u\n" -msgstr "znaleziono niegłówny węzeł LEAFN w i-węźle % bno = %u\n" +msgid "could not remove tmpdir: %s: %s\n" +msgstr "nie udało się usunąć katalogu tymczasowego: %s: %s\n" -#: .././repair/dir2.c:324 +#: .././growfs/xfs_growfs.c:26 #, c-format -msgid "bad dir magic number 0x%x in inode % bno = %u\n" -msgstr "błędna liczba magiczna katalogu 0x%x w i-węźle % bno = %u\n" +msgid "" +"Usage: %s [options] mountpoint\n" +"\n" +"Options:\n" +"\t-d grow data/metadata section\n" +"\t-l grow log section\n" +"\t-r grow realtime section\n" +"\t-n don't change anything, just show geometry\n" +"\t-i convert log from external to internal format\n" +"\t-t alternate location for mount table (/etc/mtab)\n" +"\t-x convert log from internal to external format\n" +"\t-D size grow data/metadata section to size blks\n" +"\t-L size grow/shrink log section to size blks\n" +"\t-R size grow realtime section to size blks\n" +"\t-e size set realtime extent size to size blks\n" +"\t-m imaxpct set inode max percent to imaxpct\n" +"\t-V print version information\n" +msgstr "" +"Składnia: %s [opcje] punkt_montowania\n" +"\n" +"Opcje:\n" +"\t-d powiększenie sekcji danych/metadanych\n" +"\t-l powiększenie sekcji logu\n" +"\t-r powiększenie sekcji realtime\n" +"\t-n bez zmian, tylko pokazanie geometrii\n" +"\t-i przekształcenie logu z formatu zewnętrznego na wewnętrzny\n" +"\t-t inne położenie tabeli montowań (/etc/mtab)\n" +"\t-x przekształcenie logu z formatu wewnętrznego na zewnętrzny\n" +"\t-D rozmiar powiększenie sekcji danych/metadanych do rozmiaru w blokach\n" +"\t-L rozmiar powiększenie/zmniejszenie sekcji logu do rozmiaru w blokach\n" +"\t-R rozmiar powiększenie sekcji realtime do rozmiaru w blokach\n" +"\t-e rozmiar stawienie rozmiaru ekstentu realtime na rozmiar w blokach\n" +"\t-m imaxpct ustawienie maksymalnego procentu i-węzłów na imaxpct\n" +"\t-V wypisanie informacji o wersji\n" -#: .././repair/dir2.c:345 +#: .././growfs/xfs_growfs.c:63 #, c-format -msgid "bad header depth for directory inode %\n" -msgstr "błędna głębokość nagłówka dla i-węzła katalogu %\n" +msgid "" +"meta-data=%-22s isize=%-6u agcount=%u, agsize=%u blks\n" +" =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" +" =%-22s crc=%-8u finobt=%u\n" +"data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" +" =%-22s sunit=%-6u swidth=%u blks\n" +"naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n" +"log =%-22s bsize=%-6u blocks=%u, version=%u\n" +" =%-22s sectsz=%-5u sunit=%u blks, lazy-count=%u\n" +"realtime =%-22s extsz=%-6u blocks=%llu, rtextents=%llu\n" +msgstr "" +"metadane=%-22s isize=%-6u agcount=%u, agsize=%u bloków\n" +" =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" +" =%-22s crc=%-8u finobt=%u\n" +"dane =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" +" =%-22s sunit=%-6u swidth=%u bloków\n" +"nazwy =wersja %-14u bsize=%-6u ascii-ci=%d ftype=%d\n" +"log =%-22s bsize=%-6u blocks=%u, wersja=%u\n" +" =%-22s sectsz=%-5u sunit=%u bloków, lazy-count=%u\n" +"realtime=%-22s extsz=%-6u blocks=%llu, rtextents=%llu\n" -#: .././repair/dir2.c:406 -#, c-format -msgid "release_dir2_cursor_int got unexpected non-null bp, dabno = %u\n" -msgstr "release_dir2_cursor_int otrzymał nieoczekiwany niezerowy bp, dabno = %u\n" +#: .././growfs/xfs_growfs.c:80 .././growfs/xfs_growfs.c:453 +#: .././growfs/xfs_growfs.c:454 +msgid "internal" +msgstr "wewnętrzny" -#: .././repair/dir2.c:469 -#, c-format -msgid "directory block used/count inconsistency - %d / %hu\n" -msgstr "niespójność wartości used/count bloku katalogu - %d / %hu\n" +#: .././growfs/xfs_growfs.c:80 .././growfs/xfs_growfs.c:83 +#: .././growfs/xfs_growfs.c:453 .././growfs/xfs_growfs.c:454 +msgid "external" +msgstr "zewnętrzny" -#: .././repair/dir2.c:491 +#: .././growfs/xfs_growfs.c:199 #, c-format -msgid "bad directory block in inode %\n" -msgstr "błędny blok katalogu w i-węźle %\n" +msgid "%s: %s is not a mounted XFS filesystem\n" +msgstr "%s: %s nie jest podmontowanym systemem plików XFS\n" -#: .././repair/dir2.c:512 +#: .././growfs/xfs_growfs.c:216 #, c-format -msgid "" -"correcting bad hashval in non-leaf dir block\n" -"\tin (level %d) in inode %.\n" -msgstr "" -"poprawiono błędne hashval w bloku katalogu nie będącego liściem\n" -"\tw i-węźle (poziomu %d) %.\n" +msgid "%s: specified file [\"%s\"] is not on an XFS filesystem\n" +msgstr "%s: podany plik [\"%s\"] nie jest na systemie plików XFS\n" -#: .././repair/dir2.c:520 +#: .././growfs/xfs_growfs.c:233 #, c-format -msgid "" -"would correct bad hashval in non-leaf dir block\n" -"\tin (level %d) in inode %.\n" -msgstr "" -"błędne hashval w bloku katalogu nie będącego liściem zostałoby poprawione\n" -"\tw i-węźle (poziomu %d) %.\n" +msgid "%s: cannot determine geometry of filesystem mounted at %s: %s\n" +msgstr "%s: nie można określić geometrii systemu plików podmontowanego pod %s: %s\n" -#: .././repair/dir2.c:676 +#: .././growfs/xfs_growfs.c:273 #, c-format -msgid "bad magic number %x in block %u for directory inode %\n" -msgstr "błędna liczba magiczna %x w bloku %u dla i-węzła katalogu %\n" +msgid "%s: failed to access data device for %s\n" +msgstr "%s: nie udało się uzyskać dostępu do urządzenia z danymi dla %s\n" -#: .././repair/dir2.c:684 +#: .././growfs/xfs_growfs.c:278 #, c-format -msgid "bad back pointer in block %u for directory inode %\n" -msgstr "błędny wskaźnik wstecz w bloku %u dla i-węzła katalogu %\n" +msgid "%s: failed to access external log for %s\n" +msgstr "%s: nie udało się uzyskać dostępu do zewnętrznego logu dla %s\n" -#: .././repair/dir2.c:690 +#: .././growfs/xfs_growfs.c:284 #, c-format -msgid "entry count %d too large in block %u for directory inode %\n" -msgstr "liczba wpisów %d zbyt duża w bloku %u dla i-węzła katalogu %\n" +msgid "%s: failed to access realtime device for %s\n" +msgstr "%s: nie udało się uzyskać dostępu do urządzenia realtime dla %s\n" -#: .././repair/dir2.c:697 +#: .././growfs/xfs_growfs.c:323 #, c-format -msgid "bad level %d in block %u for directory inode %\n" -msgstr "błędny poziom %d w bloku %u dla i-węzła katalogu %\n" +msgid "data size %lld too large, maximum is %lld\n" +msgstr "rozmiar danych %lld zbyt duży, maksymalny to %lld\n" -#: .././repair/dir2.c:740 +#: .././growfs/xfs_growfs.c:330 #, c-format -msgid "" -"correcting bad hashval in interior dir block\n" -"\tin (level %d) in inode %.\n" -msgstr "" -"poprawiono błędne hashval w wewnętrznym bloku katalogu\n" -"\tw i-węźle (poziomu %d) %.\n" +msgid "data size %lld too small, old size is %lld\n" +msgstr "rozmiar danych %lld zbyt mały, stary rozmiar to %lld\n" -#: .././repair/dir2.c:748 +#: .././growfs/xfs_growfs.c:338 #, c-format -msgid "" -"would correct bad hashval in interior dir block\n" -"\tin (level %d) in inode %.\n" -msgstr "" -"błędne hashval w wewnętrznym bloku katalogu zostałoby poprawione\n" -"\tw i-węźle (poziomu %d) %.\n" - -#: .././repair/dir2.c:782 -msgid "couldn't malloc dir2 shortform copy\n" -msgstr "nie udało się przydzielić krótkiej kopii dir2\n" - -#: .././repair/dir2.c:920 -msgid "current" -msgstr "bieżącego i-węzła" - -#: .././repair/dir2.c:923 .././repair/dir2.c:1443 -msgid "invalid" -msgstr "nieprawidłowego i-węzła" - -#: .././repair/dir2.c:926 .././repair/dir2.c:1445 -msgid "realtime bitmap" -msgstr "i-węzła bitmapy realtime" - -#: .././repair/dir2.c:929 .././repair/dir2.c:1447 -msgid "realtime summary" -msgstr "i-węzła opisu realtime" - -#: .././repair/dir2.c:932 .././repair/dir2.c:1449 -msgid "user quota" -msgstr "i-węzła limitów użytkownika" - -#: .././repair/dir2.c:935 .././repair/dir2.c:1451 -msgid "group quota" -msgstr "i-węzła limitów grupy" - -#: .././repair/dir2.c:953 .././repair/dir2.c:1481 -msgid "free" -msgstr "free" - -#: .././repair/dir2.c:970 .././repair/dir2.c:1461 -msgid "non-existent" -msgstr "nie istniejącego i-węzła" +msgid "data size unchanged, skipping\n" +msgstr "rozmiar danych nie zmieniony, pominięto\n" -#: .././repair/dir2.c:975 +#: .././growfs/xfs_growfs.c:341 #, c-format -msgid "entry \"%*.*s\" in shortform directory % references %s inode %\n" -msgstr "wpis \"%*.*s\" w krótkim katalogu % odwołuje się do %s %\n" +msgid "inode max pct unchanged, skipping\n" +msgstr "maksymalny procent i-węzłów nie zmieniony, pominięto\n" -#: .././repair/dir2.c:1005 +#: .././growfs/xfs_growfs.c:348 .././growfs/xfs_growfs.c:387 +#: .././growfs/xfs_growfs.c:422 #, c-format -msgid "zero length entry in shortform dir %" -msgstr "wpis zerowej długości w krótkim katalogu %" +msgid "%s: growfs operation in progress already\n" +msgstr "%s: operacja growfs już trwa\n" -#: .././repair/dir2.c:1008 +#: .././growfs/xfs_growfs.c:352 #, c-format -msgid ", junking %d entries\n" -msgstr ", wyrzucono %d wpisów\n" +msgid "%s: XFS_IOC_FSGROWFSDATA xfsctl failed: %s\n" +msgstr "%s: xfsctl XFS_IOC_FSGROWFSDATA nie powiodło się: %s\n" -#: .././repair/dir2.c:1011 +#: .././growfs/xfs_growfs.c:368 #, c-format -msgid ", would junk %d entries\n" -msgstr ", %d wpisów zostałoby wyrzucone\n" +msgid "realtime size %lld too large, maximum is %lld\n" +msgstr "rozmiar realtime %lld zbyt duży, maksymalny to %lld\n" -#: .././repair/dir2.c:1086 +#: .././growfs/xfs_growfs.c:374 #, c-format -msgid "entry contains offset out of order in shortform dir %\n" -msgstr "wpis zawiera uszkodzony offset w krótkim katalogu %\n" +msgid "realtime size %lld too small, old size is %lld\n" +msgstr "rozmiar realtime %lld zbyt mały, stary rozmiar to %lld\n" -#: .././repair/dir2.c:1189 +#: .././growfs/xfs_growfs.c:380 #, c-format -msgid "would have corrected i8 count in directory % from %d to %d\n" -msgstr "liczba i8 zostałaby poprawiona w katalogu % z %d na %d\n" +msgid "realtime size unchanged, skipping\n" +msgstr "rozmiar realtime nie zmieniony, pominięto\n" -#: .././repair/dir2.c:1193 +#: .././growfs/xfs_growfs.c:391 #, c-format -msgid "corrected i8 count in directory %, was %d, now %d\n" -msgstr "poprawiono liczbę i8 w katalogu % - było %d, jest %d\n" +msgid "%s: realtime growth not implemented\n" +msgstr "%s: powiększanie realtime nie jest zaimplementowane\n" -#: .././repair/dir2.c:1207 +#: .././growfs/xfs_growfs.c:395 #, c-format -msgid "would have corrected directory % size from % to %\n" -msgstr "rozmiar katalogu % zostałby poprawiony z % na %\n" +msgid "%s: XFS_IOC_FSGROWFSRT xfsctl failed: %s\n" +msgstr "%s: xfsctl XFS_IOC_FSGROWFSRT nie powiodło się: %s\n" -#: .././repair/dir2.c:1224 +#: .././growfs/xfs_growfs.c:416 #, c-format -msgid "directory % offsets too high\n" -msgstr "offsety zbyt duże w katalogu %\n" +msgid "log size unchanged, skipping\n" +msgstr "rozmiar logu nie zmieniony, pominięto\n" -#: .././repair/dir2.c:1230 +#: .././growfs/xfs_growfs.c:426 #, c-format -msgid "would have corrected entry offsets in directory %\n" -msgstr "offsety wpisów w katalogu % zostałyby poprawione\n" +msgid "%s: log growth not supported yet\n" +msgstr "%s: powiększanie logu nie jest jeszcze obsługiwane\n" -#: .././repair/dir2.c:1234 +#: .././growfs/xfs_growfs.c:430 #, c-format -msgid "corrected entry offsets in directory %\n" -msgstr "poprawiono offsety wpisów w katalogu %\n" +msgid "%s: XFS_IOC_FSGROWFSLOG xfsctl failed: %s\n" +msgstr "%s: xfsctl XFS_IOC_FSGROWFSLOG nie powiodło się: %s\n" -#: .././repair/dir2.c:1289 +#: .././growfs/xfs_growfs.c:438 #, c-format -msgid "bad .. entry in directory inode %, points to self, " -msgstr "błędny wpis .. w i-węźle katalogu %, wskazuje na siebie, " +msgid "%s: XFS_IOC_FSGEOMETRY xfsctl failed: %s\n" +msgstr "%s: xfsctl XFS_IOC_FSGEOMETRY nie powiodło się: %s\n" -#: .././repair/dir2.c:1401 +#: .././growfs/xfs_growfs.c:443 #, c-format -msgid "corrupt block %u in directory inode %\n" -msgstr "uszkodzony blok %u w i-węźle katalogu %\n" - -#: .././repair/dir2.c:1404 -msgid "\twill junk block\n" -msgstr "\tblok zostanie wyrzucony\n" - -#: .././repair/dir2.c:1406 -msgid "\twould junk block\n" -msgstr "\tblok zostałby wyrzucony\n" +msgid "data blocks changed from %lld to %lld\n" +msgstr "bloki danych zmienione z %lld na %lld\n" -#: .././repair/dir2.c:1490 +#: .././growfs/xfs_growfs.c:446 #, c-format -msgid "entry \"%*.*s\" at block %d offset % in directory inode % references %s inode %\n" -msgstr "wpis \"%*.*s\" w bloku %d offsecie % w i-węźle katalogu % odwołuje się do %s %\n" +msgid "inode max percent changed from %d to %d\n" +msgstr "maksymalny procent i-węzłów zmieniony z %d na %d\n" -#: .././repair/dir2.c:1501 +#: .././growfs/xfs_growfs.c:449 #, c-format -msgid "entry at block %u offset % in directory inode %has 0 namelength\n" -msgstr "wpis w bloku %u offsecie % w i-węźle katalogu % ma zerową długość nazwy\n" +msgid "log blocks changed from %d to %d\n" +msgstr "bloki logu zmienione z %d na %d\n" -#: .././repair/dir2.c:1514 +#: .././growfs/xfs_growfs.c:452 #, c-format -msgid "\tclearing inode number in entry at offset %...\n" -msgstr "\twyczyszczono numer i-węzła we wpisie o offsecie %...\n" +msgid "log changed from %s to %s\n" +msgstr "log zmieniony - był %s, jest %s\n" -#: .././repair/dir2.c:1521 +#: .././growfs/xfs_growfs.c:456 #, c-format -msgid "\twould clear inode number in entry at offset %...\n" -msgstr "\tnumer i-węzła we wpisie o offsecie % zostałby wyczyszczony...\n" +msgid "realtime blocks changed from %lld to %lld\n" +msgstr "bloki realtime zmienione z %lld na %lld\n" -#: .././repair/dir2.c:1534 +#: .././growfs/xfs_growfs.c:459 #, c-format -msgid "entry at block %u offset % in directory inode % has illegal name \"%*.*s\": " -msgstr "wpis w bloku %u offsecie % w i-węźle katalogu % ma niedozwoloną nazwę \"%*.*s\": " +msgid "realtime extent size changed from %d to %d\n" +msgstr "rozmiar ekstentu realtime zmieniony z %d na %d\n" -#: .././repair/dir2.c:1564 +#: .././io/attr.c:59 #, c-format -msgid "bad .. entry in directory inode %, points to self: " -msgstr "błędny wpis .. w i-węźle katalogu %, wskazuje na siebie: " +msgid "" +"\n" +" displays the set of extended inode flags associated with the current file\n" +"\n" +" Each individual flag is displayed as a single character, in this order:\n" +" r -- file data is stored in the realtime section\n" +" p -- file has preallocated extents (cannot be changed using chattr)\n" +" i -- immutable, file cannot be modified\n" +" a -- append-only, file can only be appended to\n" +" s -- all updates are synchronous\n" +" A -- the access time is not updated for this inode\n" +" d -- do not include this file in a dump of the filesystem\n" +" t -- child created in this directory has realtime bit set by default\n" +" P -- child created in this directory has parents project ID by default\n" +" n -- symbolic links cannot be created in this directory\n" +" e -- for non-realtime files, observe the inode extent size value\n" +" E -- children created in this directory inherit the extent size value\n" +" f -- do not include this file when defragmenting the filesystem\n" +" S -- enable filestreams allocator for this directory\n" +"\n" +" Options:\n" +" -R -- recursively descend (useful when current file is a directory)\n" +" -D -- recursively descend, but only list attributes on directories\n" +" -a -- show all flags which can be set alongside those which are set\n" +" -v -- verbose mode; show long names of flags, not single characters\n" +"\n" +msgstr "" +"\n" +" wyświetlanie zbioru rozszerzonych flag i-węzłów związanych z bieżącym plikiem\n" +"\n" +" Każda flaga jest wyświetlana jako pojedynczy znak, w tej kolejności:\n" +" r - dane pliku są zapisane w sekcji realtime\n" +" p - plik ma już przydzielone ekstenty (nie do zmiany przez chattr)\n" +" i - niezmienny, pliku nie można modyfikować\n" +" a - tylko do dopisywania, do pliku można tylko dopisywać\n" +" s - wszystkie uaktualnienia są synchroniczne\n" +" A - czas dostępu nie jest uaktualniany dla tego i-węzła\n" +" d - nie dołączanie pliku do zrzutu systemu plików\n" +" t - wpisy tworzone w tym katalogu mają domyślnie ustawiony bit realtime\n" +" P - wpisy tworzone w tym katalogu mają domyślnie ID projektu rodzica\n" +" n - w tym katalogu nie można tworzyć dowiązań symbolicznych\n" +" e - dla plików nie-realtime - przestrzeganie wartości rozmiaru ekstentu i-węzła\n" +" E - wpisy tworzone w tym katalogu dziedziczą wartość rozmiaru ekstentu\n" +" f - nie uwzględnianie tego pliku przy defragmentacji systemu plików\n" +" S - włączenie przydzielania strumieni plikowych dla tego katalogu\n" +"\n" +" Opcje:\n" +" -R - rekurencyjne zagłębianie się (przydatne kiedy bieżący plik jest katalogiem)\n" +" -D - rekurencyjne zagłębianie się, ale wypisywanie atrybutów tylko katalogów\n" +" -a - pokazywanie wszystkich flag, które można ustawić, obok ustawionych\n" +" -v - tryb szczegółowy; pokazywanie długich nazw flag zamiast pojedynczych znaków\n" +"\n" -#: .././repair/dir2.c:1575 +#: .././io/attr.c:90 #, c-format -msgid "bad .. entry in root directory inode %, was %: " -msgstr "błędny wpis w i-węźle głównego katalogu %, było %: " - -#: .././repair/dir2.c:1578 .././repair/dir2.c:1610 .././repair/phase2.c:180 -#: .././repair/phase2.c:189 .././repair/phase2.c:198 -msgid "correcting\n" -msgstr "poprawiono\n" - -#: .././repair/dir2.c:1582 .././repair/dir2.c:1614 .././repair/phase2.c:182 -#: .././repair/phase2.c:191 .././repair/phase2.c:200 -msgid "would correct\n" -msgstr "zostałby poprawiony\n" +msgid "" +"\n" +" modifies the set of extended inode flags associated with the current file\n" +"\n" +" Examples:\n" +" 'chattr +a' - sets the append-only flag\n" +" 'chattr -a' - clears the append-only flag\n" +"\n" +" -R -- recursively descend (useful when current file is a directory)\n" +" -D -- recursively descend, only modifying attributes on directories\n" +" +/-r -- set/clear the realtime flag\n" +" +/-i -- set/clear the immutable flag\n" +" +/-a -- set/clear the append-only flag\n" +" +/-s -- set/clear the sync flag\n" +" +/-A -- set/clear the no-atime flag\n" +" +/-d -- set/clear the no-dump flag\n" +" +/-t -- set/clear the realtime inheritance flag\n" +" +/-P -- set/clear the project ID inheritance flag\n" +" +/-n -- set/clear the no-symbolic-links flag\n" +" +/-e -- set/clear the extent-size flag\n" +" +/-E -- set/clear the extent-size inheritance flag\n" +" +/-f -- set/clear the no-defrag flag\n" +" +/-S -- set/clear the filestreams allocator flag\n" +" Note1: user must have certain capabilities to modify immutable/append-only.\n" +" Note2: immutable/append-only files cannot be deleted; removing these files\n" +" requires the immutable/append-only flag to be cleared first.\n" +" Note3: the realtime flag can only be set if the filesystem has a realtime\n" +" section, and the (regular) file must be empty when the flag is set.\n" +"\n" +msgstr "" +"\n" +" zmiana zbioru rozszerzonych flag i-węzłów związanych z bieżącym plikiem\n" +"\n" +" Przykłady:\n" +" 'chattr +a' - ustawia flagę tylko do dopisywania\n" +" 'chattr -a' - zdejmuje flagę tylko do dopisywania\n" +"\n" +" -R - rekurencyjne zagłębianie się (przydatne kiedy bieżący plik jest katalogiem)\n" +" -D - rekurencyjne zagłębianie się, ale zmiana atrybutów tylko katalogów\n" +" +/-r - ustawienie/zdjęcie flagi realtime\n" +" +/-i - ustawienie/zdjęcie flagi immutable (niezmienności)\n" +" +/-a - ustawienie/zdjęcie flagi append-only (tylko do dopisywania)\n" +" +/-s - ustawienie/zdjęcie flagi sync (synchronicznego zapisu)\n" +" +/-A - ustawienie/zdjęcie flagi no-atime\n" +" +/-d - ustawienie/zdjęcie flagi no-dump\n" +" +/-t - ustawienie/zdjęcie flagi dziedziczenia realtime\n" +" +/-P - ustawienie/zdjęcie flagi dziedziczenia ID projektu\n" +" +/-n - ustawienie/zdjęcie flagi braku dowiązań symbolicznych\n" +" +/-e - ustawienie/zdjęcie flagi rozmiaru ekstentu\n" +" +/-E - ustawienie/zdjęcie flagi dziedziczenia rozmiaru ekstentu\n" +" +/-f - ustawienie/zdjęcie flagi no-defrag\n" +" +/-S - ustawienie/zdjęcie flagi przydzielania strumieni plikowych\n" +" Uwaga1: użytkownik musi mieć pewne uprawnienia do zmiany flag\n" +" immutable/append-only\n" +" Uwaga2: plików immutable/append-only nie można usuwać; usuwanie tych plików\n" +" wymaga zdjęcia flag immutable/append-only przed usunięciem.\n" +" Uwaga3: flagę realtime można ustawić tylko jeśli system plików ma sekcję\n" +" realtime i (zwykły) plik musi być pusty przy ustawianiu flagi.\n" +"\n" -#: .././repair/dir2.c:1594 +#: .././io/attr.c:171 .././io/attr.c:247 .././io/open.c:424 .././io/open.c:496 +#: .././io/open.c:620 .././io/open.c:642 .././libxfs/init.c:109 +#: .././mkfs/proto.c:293 .././quota/project.c:118 .././quota/project.c:163 +#: .././quota/project.c:210 #, c-format -msgid "multiple .. entries in directory inode %: " -msgstr "wiele wpisów .. w i-węźle katalogu %: " +msgid "%s: cannot open %s: %s\n" +msgstr "%s: nie można otworzyć %s: %s\n" -#: .././repair/dir2.c:1607 +#: .././io/attr.c:174 .././io/attr.c:221 .././io/attr.c:250 .././io/attr.c:321 +#: .././quota/project.c:122 .././quota/project.c:168 .././quota/project.c:215 #, c-format -msgid "bad . entry in directory inode %, was %: " -msgstr "błędny wpis . w i-węźle katalogu %, było %: " +msgid "%s: cannot get flags on %s: %s\n" +msgstr "%s: nie można pobrać flag %s: %s\n" -#: .././repair/dir2.c:1619 +#: .././io/attr.c:256 .././io/attr.c:327 #, c-format -msgid "multiple . entries in directory inode %: " -msgstr "wiele wpisów . w i-węźle katalogu %: " +msgid "%s: cannot set flags on %s: %s\n" +msgstr "%s: nie można ustawić flag %s: %s\n" -#: .././repair/dir2.c:1629 +#: .././io/attr.c:291 .././io/attr.c:305 #, c-format -msgid "entry \"%*.*s\" in directory inode % points to self: " -msgstr "wpis \"%*.*s\" w i-węźle katalogu % wskazuje na siebie: " - -#: .././repair/dir2.c:1640 -msgid "clearing entry\n" -msgstr "wyczyszczono wpis\n" +msgid "%s: unknown flag\n" +msgstr "%s: nieznana flaga\n" -#: .././repair/dir2.c:1655 +#: .././io/attr.c:311 #, c-format -msgid "bad bestfree table in block %u in directory inode %: " -msgstr "błędna tablica bestfree w bloku %u w i-węźle katalogu %: " +msgid "%s: bad chattr command, not +/-X\n" +msgstr "%s: złe polecenie chattr - nie +/-X\n" -#: .././repair/dir2.c:1658 -msgid "repairing table\n" -msgstr "naprawiono tablicę\n" +#: .././io/attr.c:338 +msgid "[-R|-D] [+/-" +msgstr "[-R|-D] [+/-" -#: .././repair/dir2.c:1662 -msgid "would repair table\n" -msgstr "tablica zostałaby naprawiona\n" +#: .././io/attr.c:343 +msgid "change extended inode flags on the currently open file" +msgstr "zmiana rozszerzonych flag i-węzłów aktualnie otwartego pliku" -#: .././repair/dir2.c:1700 -#, c-format -msgid "block %u for directory inode % is missing\n" -msgstr "brak bloku %u dla i-węzła katalogu %\n" +#: .././io/attr.c:348 +msgid "[-R|-D|-a|-v]" +msgstr "[-R|-D|-a|-v]" -#: .././repair/dir2.c:1719 -#, c-format -msgid "bad directory block magic # %#x in block %u for directory inode %\n" -msgstr "błędna liczba magiczna bloku katalogu %#x w bloku %u dla i-węzła katalogu %\n" +#: .././io/attr.c:353 +msgid "list extended inode flags set on the currently open file" +msgstr "wypisanie rozszerzonych flag i-węzłów aktualnie otwartego pliku" -#: .././repair/dir2.c:1763 +#: .././io/bmap.c:30 #, c-format -msgid "bad entry count in block %u of directory inode %\n" -msgstr "błędna liczba wpisów w bloku %u i-węzła katalogu %\n" +msgid "" +"\n" +" prints the block mapping for an XFS file's data or attribute forks\n" +" Example:\n" +" 'bmap -vp' - tabular format verbose map, including unwritten extents\n" +"\n" +" bmap prints the map of disk blocks used by the current file.\n" +" The map lists each extent used by the file, as well as regions in the\n" +" file that do not have any corresponding blocks (holes).\n" +" By default, each line of the listing takes the following form:\n" +" extent: [startoffset..endoffset]: startblock..endblock\n" +" Holes are marked by replacing the startblock..endblock with 'hole'.\n" +" All the file offsets and disk blocks are in units of 512-byte blocks.\n" +" -a -- prints the attribute fork map instead of the data fork.\n" +" -d -- suppresses a DMAPI read event, offline portions shown as holes.\n" +" -l -- also displays the length of each extent in 512-byte blocks.\n" +" -n -- query n extents.\n" +" -p -- obtain all unwritten extents as well (w/ -v show which are unwritten.)\n" +" -v -- Verbose information, specify ag info. Show flags legend on 2nd -v\n" +" Note: the bmap for non-regular files can be obtained provided the file\n" +" was opened appropriately (in particular, must be opened read-only).\n" +"\n" +msgstr "" +"\n" +" wypisanie mapowania bloków dla danych lub atrybutów pliku na XFS-ie\n" +" Przykład:\n" +" 'bmap -vp' - szczegółowa mapa w formacie tabeli wraz z nie zapisanymi\n" +" ekstentami\n" +"\n" +" bmap wypisuje mapę bloków dysku używanych przez bieżący plik.\n" +" Mapa opisuje każdy ekstent użyty przez plik, a także regiony w pliku\n" +" nie mające przypisanych bloków (dziury).\n" +" Domyślnie każda linia listingu przyjmuje następującą postać:\n" +" ekstent: [offsetpocz..offsetkońc]: blokpocz..blokkońc\n" +" Dziury są oznaczane przez zastąpienie blokpocz..blokkońc przez 'dziura'.\n" +" Wszystkie offsety w plikach i bloki dysku są w jednostkach 512-bajtowych.\n" +" -a - wypisanie mapy gałęzi atrybutów zamiast gałęzi danych.\n" +" -d - pominięcie zdarzenia odczytu DMAPI, pokazanie części offline jako dziur.\n" +" -l - wyświetlenie także długości każdego fragmentu w 512-bajtowych blokach.\n" +" -n - odpytanie n ekstentów.\n" +" -p - wypisanie także nie zapisanych ekstentów (z -v pokazuje, które są nie\n" +" zapisane).\n" +" -v - szczegółowe informacje z podaniem informacji ag; legenda drugim -v\n" +" Uwaga: bmap dla plików nie będących plikami zwykłymi można uzyskać pod\n" +" warunkiem, że plik został otwarty odpowiednio (w szczególności musi być\n" +" otwarty tylko do odczytu).\n" +"\n" -#: .././repair/dir2.c:1771 +#: .././io/bmap.c:123 #, c-format -msgid "bad hash ordering in block %u of directory inode %\n" -msgstr "błędna kolejność hasza w bloku %u i-węzła katalogu %\n" +msgid "%s: can't get geometry [\"%s\"]: %s\n" +msgstr "%s: nie można uzyskać geometrii [\"%s\"]: %s\n" -#: .././repair/dir2.c:1780 +#: .././io/bmap.c:131 #, c-format -msgid "bad stale count in block %u of directory inode %\n" -msgstr "błędna liczba stale %u i-węzła katalogu %\n" +msgid "%s: cannot read attrs on \"%s\": %s\n" +msgstr "%s: nie można odczytać atrybutów \"%s\": %s\n" -#: .././repair/dir2.c:1838 +#: .././io/bmap.c:149 .././io/fiemap.c:259 #, c-format -msgid "can't read file block %u for directory inode %\n" -msgstr "nie można odczytać bloku pliku %u dla i-węzła katalogu %\n" +msgid "%s: malloc of %d bytes failed.\n" +msgstr "%s: przydzielenie %d bajtów nie powiodło się.\n" -#: .././repair/dir2.c:1849 +#: .././io/bmap.c:197 #, c-format -msgid "bad directory leaf magic # %#x for directory inode % block %u\n" -msgstr "błędna liczba magiczna liścia katalogu %#x dla i-węzła katalogu % bloku %u\n" +msgid "%s: xfsctl(XFS_IOC_GETBMAPX) iflags=0x%x [\"%s\"]: %s\n" +msgstr "%s: xfsctl(XFS_IOC_GETBMAPX) iflags=0x%x [\"%s\"]: %s\n" -#: .././repair/dir2.c:1879 +#: .././io/bmap.c:228 #, c-format -msgid "bad sibling back pointer for block %u in directory inode %\n" -msgstr "błędny wskaźnik wstecz dla bloku %u w i-węźle katalogu %\n" +msgid "%s: cannot realloc %d bytes\n" +msgstr "%s: nie można wykonać realloc na %d bajtów\n" -#: .././repair/dir2.c:2009 +#: .././io/bmap.c:237 #, c-format -msgid "block % for directory inode % is missing\n" -msgstr "brak bloku % dla i-węzła katalogu %\n" +msgid "%s: no extents\n" +msgstr "%s: brak ekstentów\n" -#: .././repair/dir2.c:2018 +#: .././io/bmap.c:251 .././io/bmap.c:379 .././io/fiemap.c:105 +#: .././io/fiemap.c:340 .././io/fiemap.c:344 #, c-format -msgid "can't read block % for directory inode %\n" -msgstr "nie można odczytać bloku % dla i-węzła katalogu %\n" +msgid "hole" +msgstr "dziura" -#: .././repair/dir2.c:2025 +#: .././io/bmap.c:260 #, c-format -msgid "bad directory block magic # %#x in block % for directory inode %\n" -msgstr "błędna liczba magiczna bloku katalogu %#x w bloku % dla i-węzła katalogu %\n" +msgid " %lld blocks\n" +msgstr " %lld bloków\n" -#: .././repair/dir2.c:2102 -#, c-format -msgid "bad size/format for directory %\n" -msgstr "błędny rozmiar/format dla katalogu %\n" +#: .././io/bmap.c:339 .././io/fiemap.c:94 +msgid "EXT" +msgstr "EXT" -#: .././repair/phase4.c:202 -msgid "Phase 4 - check for duplicate blocks...\n" -msgstr "Faza 4 - sprawdzanie powtórzonych bloków...\n" +#: .././io/bmap.c:340 .././io/fiemap.c:95 +msgid "FILE-OFFSET" +msgstr "OFFSET-W-PLIKU" -#: .././repair/phase4.c:203 -msgid " - setting up duplicate extent list...\n" -msgstr " - tworzenie listy powtórzonych ekstentów...\n" +#: .././io/bmap.c:341 +msgid "RT-BLOCK-RANGE" +msgstr "ZAKRES-BLOKÓW-RT" -#: .././repair/phase4.c:217 -msgid "root inode would be lost\n" -msgstr "główny i-węzeł zostałby utracony\n" +#: .././io/bmap.c:341 .././io/fiemap.c:96 +msgid "BLOCK-RANGE" +msgstr "ZAKRES-BLOKÓW" -#: .././repair/phase4.c:219 -msgid "root inode lost\n" -msgstr "główny i-węzeł utracony\n" +#: .././io/bmap.c:342 +msgid "AG" +msgstr "AG" -#: .././repair/phase4.c:236 -#, c-format -msgid "unknown block state, ag %d, block %d\n" -msgstr "nieznany stan bloku, ag %d, blok %d\n" +#: .././io/bmap.c:343 +msgid "AG-OFFSET" +msgstr "OFFSET-AG" -#: .././repair/phase4.c:269 -#, c-format -msgid "unknown rt extent state, extent %\n" -msgstr "nieznany stan ekstentu rt, ekstent %\n" +#: .././io/bmap.c:344 .././io/fiemap.c:97 +msgid "TOTAL" +msgstr "RAZEM" -#: .././repair/phase4.c:318 -msgid " - check for inodes claiming duplicate blocks...\n" -msgstr " - szukanie i-węzłów odwołujących się do powtórzonych bloków...\n" +#: .././io/bmap.c:345 +msgid " FLAGS" +msgstr " FLAGI" -#: .././repair/phase6.c:63 +#: .././io/bmap.c:413 #, c-format -msgid "malloc failed add_dotdot_update (%zu bytes)\n" -msgstr "malloc nie powiodło się w add_dotdot_update (%zu bajtów)\n" +msgid " FLAG Values:\n" +msgstr " Wartości FLAG:\n" -#: .././repair/phase6.c:174 +#: .././io/bmap.c:414 #, c-format -msgid "malloc failed in dir_hash_add (%zu bytes)\n" -msgstr "malloc nie powiodło się w dir_hash_add (%zu bajtów)\n" - -#: .././repair/phase6.c:228 -msgid "ok" -msgstr "ok" - -#: .././repair/phase6.c:229 -msgid "duplicate leaf" -msgstr "powtórzony liść" - -#: .././repair/phase6.c:230 -msgid "hash value mismatch" -msgstr "niezgodność wartości hasza" - -#: .././repair/phase6.c:231 -msgid "no data entry" -msgstr "brak wpisu danych" - -#: .././repair/phase6.c:232 -msgid "no leaf entry" -msgstr "brak wpisu liścia" - -#: .././repair/phase6.c:233 -msgid "bad stale count" -msgstr "błędna liczba stale" +msgid " %*.*o Unwritten preallocated extent\n" +msgstr " %*.*o Nie zapisany, już przydzielony ekstent\n" -#: .././repair/phase6.c:241 +#: .././io/bmap.c:416 #, c-format -msgid "bad hash table for directory inode % (%s): " -msgstr "błędna tablica haszująca dla i-węzła katalogu % (%s): " - -#: .././repair/phase6.c:244 -msgid "rebuilding\n" -msgstr "przebudowano\n" - -#: .././repair/phase6.c:246 -msgid "would rebuild\n" -msgstr "zostałaby przebudowana\n" - -#: .././repair/phase6.c:282 -msgid "calloc failed in dir_hash_init\n" -msgstr "calloc nie powiodło się w dir_hash_init\n" - -#: .././repair/phase6.c:412 -msgid "ran out of disk space!\n" -msgstr "brak miejsca na dysku!\n" +msgid " %*.*o Doesn't begin on stripe unit\n" +msgstr " %*.*o Nie zaczyna się od jednostki pasa\n" -#: .././repair/phase6.c:414 +#: .././io/bmap.c:418 #, c-format -msgid "xfs_trans_reserve returned %d\n" -msgstr "xfs_trans_reserve zwróciło %d\n" +msgid " %*.*o Doesn't end on stripe unit\n" +msgstr " %*.*o Nie kończy się na jednostce pasa\n" -#: .././repair/phase6.c:443 .././repair/phase6.c:536 +#: .././io/bmap.c:420 #, c-format -msgid "couldn't iget realtime bitmap inode -- error - %d\n" -msgstr "nie udało się wykonać iget dla i-węzła bitmapy realtime - błąd %d\n" +msgid " %*.*o Doesn't begin on stripe width\n" +msgstr " %*.*o Nie zaczyna się na szerokości pasa\n" -#: .././repair/phase6.c:493 +#: .././io/bmap.c:422 #, c-format -msgid "couldn't allocate realtime bitmap, error = %d\n" -msgstr "nie udało się przydzielić bitmapy realtime, błąd = %d\n" +msgid " %*.*o Doesn't end on stripe width\n" +msgstr " %*.*o Nie kończy się na szerokości pasa\n" -#: .././repair/phase6.c:506 -#, c-format -msgid "allocation of the realtime bitmap failed, error = %d\n" -msgstr "przydzielenie bitmapy realtime nie powiodło się, błąd = %d\n" +#: .././io/bmap.c:438 +msgid "[-adlpv] [-n nx]" +msgstr "[-adlpv] [-n nx]" -#: .././repair/phase6.c:549 -#, c-format -msgid "couldn't map realtime bitmap block %, error = %d\n" -msgstr "nie udało się odwzorować bloku bitmapy realtime %, błąd = %d\n" +#: .././io/bmap.c:439 +msgid "print block mapping for an XFS file" +msgstr "wypisanie mapowania bloków dla pliku na XFS-ie" -#: .././repair/phase6.c:562 +#: .././io/fadvise.c:31 #, c-format -msgid "can't access block % (fsbno %) of realtime bitmap inode %\n" -msgstr "brak dostępu do bloku % (fsbno %) i-węzła bitmapy realtime %\n" +msgid "" +"\n" +" advise the page cache about expected I/O patterns on the current file\n" +"\n" +" Modifies kernel page cache behaviour when operating on the current file.\n" +" The range arguments are required by some advise commands ([*] below).\n" +" With no arguments, the POSIX_FADV_NORMAL advice is implied.\n" +" -d -- don't need these pages (POSIX_FADV_DONTNEED) [*]\n" +" -n -- data will be accessed once (POSIX_FADV_NOREUSE) [*]\n" +" -r -- expect random page references (POSIX_FADV_RANDOM)\n" +" -s -- expect sequential page references (POSIX_FADV_SEQUENTIAL)\n" +" -w -- will need these pages (POSIX_FADV_WILLNEED) [*]\n" +" Notes: these interfaces are not supported in Linux kernels before 2.6.\n" +" NORMAL sets the default readahead setting on the file.\n" +" RANDOM sets the readahead setting on the file to zero.\n" +" SEQUENTIAL sets double the default readahead setting on the file.\n" +" WILLNEED and NOREUSE are equivalent, and force the maximum readahead.\n" +"\n" +msgstr "" +"\n" +" doradzenie buforowi stron w sprawie oczekiwanych schematów we/wy na bieżącym\n" +" pliku\n" +"\n" +" fadvise modyfikuje zachowanie bufora stron przy operacjach na bieżącym pliku.\n" +" Niektóre polecenia fadvise ([*] poniżej) wymagają podania zakresu.\n" +" Bez argumentów zakłada się doradzenie POSIX_FADV_NORMAL.\n" +" -d - podane strony nie są wymagane (POSIX_FADV_DONTNEED) [*]\n" +" -n - dostęp do danych będzie jednokrotny (POSIX_FADV_NOREUSE) [*]\n" +" -r - należy oczekiwać losowych odwołań do stron (POSIX_FADV_RANDOM)\n" +" -s - należy oczekiwać sekwencyjnych odwołań do stron (POSIX_FADV_SEQUENTIAL)\n" +" -w - podane strony będą potrzebne (POSIX_FADV_WILLNEED) [*]\n" +" Uwagi: te interfejsy nie były obsługiwane przez jądra Linuksa przed 2.6.\n" +" NORMAL ustawia domyślną wartość czytania z wyprzedzeniem dla pliku.\n" +" RANDOM ustawia czytanie z wyprzedzeniem dla pliku na zero.\n" +" SEQUENTIAL ustawia podwójną domyślną wartość czytania z wyprzedzeniem.\n" +" WILLNEED i NOREUSE są równoznaczne i wymuszają maksymalne czytanie\n" +" z wyprzedzeniem.\n" +"\n" -#: .././repair/phase6.c:605 .././repair/phase6.c:676 +#: .././io/fadvise.c:92 .././io/madvise.c:87 .././io/mincore.c:48 +#: .././io/mmap.c:206 .././io/mmap.c:301 .././io/mmap.c:387 .././io/mmap.c:546 +#: .././io/prealloc.c:65 .././io/pwrite.c:344 .././io/sendfile.c:126 +#: .././io/sync_file_range.c:75 #, c-format -msgid "couldn't iget realtime summary inode -- error - %d\n" -msgstr "nie udało się wykonać iget dla i-węzła opisu realtime - błąd %d\n" +msgid "non-numeric offset argument -- %s\n" +msgstr "nieliczbowy argument będący offsetem - %s\n" -#: .././repair/phase6.c:618 +#: .././io/fadvise.c:99 .././io/madvise.c:94 .././io/mincore.c:54 +#: .././io/mmap.c:212 .././io/mmap.c:308 .././io/mmap.c:394 .././io/mmap.c:553 +#: .././io/pread.c:452 .././io/pread.c:460 .././io/prealloc.c:70 +#: .././io/pwrite.c:350 .././io/sendfile.c:133 .././io/sync_file_range.c:82 #, c-format -msgid "couldn't map realtime summary inode block %, error = %d\n" -msgstr "nie udało się odwzorować bloku i-węzła opisu realtime %, błąd = %d\n" +msgid "non-numeric length argument -- %s\n" +msgstr "nieliczbowy argument będący długością - %s\n" -#: .././repair/phase6.c:631 -#, c-format -msgid "can't access block % (fsbno %) of realtime summary inode %\n" -msgstr "brak dostępu do bloku % (fsbno %) i-węzła opisu realtime %\n" +#: .././io/fadvise.c:122 +msgid "[-dnrsw] [off len]" +msgstr "[-dnrsw] [offset długość]" -#: .././repair/phase6.c:732 -#, c-format -msgid "couldn't allocate realtime summary inode, error = %d\n" -msgstr "nie udało się przydzielić i-węzła opisu realtime, błąd = %d\n" +#: .././io/fadvise.c:123 +msgid "advisory commands for sections of a file" +msgstr "polecenia doradcze dla sekcji pliku" -#: .././repair/phase6.c:745 +#: .././io/fiemap.c:32 #, c-format -msgid "allocation of the realtime summary ino failed, error = %d\n" -msgstr "przydzielenie i-węzła opisu realtime nie powiodło się, błąd = %d\n" +msgid "" +"\n" +" prints the block mapping for a file's data or attribute forks\n" +" Example:\n" +" 'fiemap -v' - tabular format verbose map\n" +"\n" +" fiemap prints the map of disk blocks used by the current file.\n" +" The map lists each extent used by the file, as well as regions in the\n" +" file that do not have any corresponding blocks (holes).\n" +" By default, each line of the listing takes the following form:\n" +" extent: [startoffset..endoffset]: startblock..endblock\n" +" Holes are marked by replacing the startblock..endblock with 'hole'.\n" +" All the file offsets and disk blocks are in units of 512-byte blocks.\n" +" -a -- prints the attribute fork map instead of the data fork.\n" +" -l -- also displays the length of each extent in 512-byte blocks.\n" +" -n -- query n extents.\n" +" -v -- Verbose information\n" +"\n" +msgstr "" +"\n" +" wypisanie mapowania bloków dla danych lub atrybutów pliku\n" +" Przykład:\n" +" 'fiemap -v' - szczegółowa mapa w formacie tabeli\n" +"\n" +" fiemap wypisuje mapę bloków dysku używanych przez bieżący plik.\n" +" Mapa opisuje każdy ekstent użyty przez plik, a także regiony w pliku\n" +" nie mające przypisanych bloków (dziury).\n" +" Domyślnie każda linia listingu przyjmuje następującą postać:\n" +" ekstent: [offsetpocz..offsetkońc]: blokpocz..blokkońc\n" +" Dziury są oznaczane przez zastąpienie blokpocz..blokkońc przez 'dziura'.\n" +" Wszystkie offsety w plikach i bloki dysku są w jednostkach 512-bajtowych.\n" +" -a - wypisanie mapy gałęzi atrybutów zamiast gałęzi danych.\n" +" -l - wyświetlenie także długości każdego fragmentu w 512-bajtowych blokach.\n" +" -n - odpytanie n ekstentów.\n" +" -v - szczegółowe informacje\n" +"\n" -#: .././repair/phase6.c:775 -#, c-format -msgid "could not iget root inode -- error - %d\n" -msgstr "nie udało się wykonać iget dla głównego i-węzła - błąd %d\n" +#: .././io/fiemap.c:98 +msgid "FLAGS" +msgstr "FLAGI" -#: .././repair/phase6.c:845 +#: .././io/fiemap.c:147 .././io/fiemap.c:161 .././io/fiemap.c:346 #, c-format -msgid "%d - couldn't iget root inode to obtain %s\n" -msgstr "%d - nie udało się wykonać iget dla głównego węzła, aby uzyskać %s\n" +msgid " %llu blocks\n" +msgstr " %llu bloków\n" -#: .././repair/phase6.c:876 -#, c-format -msgid "%s inode allocation failed %d\n" -msgstr "przydzielenie i-węzłą %s nie powiodło się - %d\n" +#: .././io/fiemap.c:366 +msgid "[-alv] [-n nx]" +msgstr "[-alv] [-n nx]" -#: .././repair/phase6.c:907 -#, c-format -msgid "can't make %s, createname error %d\n" -msgstr "nie można zrobić %s, błąd createname %d\n" +#: .././io/fiemap.c:367 +msgid "print block mapping for a file" +msgstr "wypisanie mapowania bloków dla pliku" -#: .././repair/phase6.c:927 +#: .././io/file.c:39 #, c-format -msgid "%s directory creation failed -- bmapf error %d\n" -msgstr "tworzenie katalogu %s nie powiodło się - błąd bmapf %d\n" +msgid "%c%03d%c %-14s (%s,%s,%s,%s%s%s%s%s)\n" +msgstr "%c%03d%c %-14s (%s,%s,%s,%s%s%s%s%s)\n" -#: .././repair/phase6.c:970 -#, c-format -msgid "%d - couldn't iget orphanage inode\n" -msgstr "%d - nie udało się wykonać iget dla i-węzła sierocińca\n" +#: .././io/file.c:41 +msgid "foreign" +msgstr "obcy" -#: .././repair/phase6.c:983 -#, c-format -msgid "%d - couldn't iget disconnected inode\n" -msgstr "%d - nie udało się wykonać iget dla odłączonego i-węzła\n" +#: .././io/file.c:41 +msgid "xfs" +msgstr "xfs" -#: .././repair/phase6.c:1003 .././repair/phase6.c:1047 -#: .././repair/phase6.c:1104 .././repair/phase6.c:1747 -#, c-format -msgid "space reservation failed (%d), filesystem may be out of space\n" -msgstr "nie udało się zarezerwować miejsca (%d), może brakować miejsca w systemie plików\n" +#: .././io/file.c:42 .././io/open.c:97 +msgid "sync" +msgstr "synchr" -#: .././repair/phase6.c:1014 .././repair/phase6.c:1059 -#: .././repair/phase6.c:1115 -#, c-format -msgid "name create failed in %s (%d), filesystem may be out of space\n" -msgstr "tworzenie nazwy nie powiodło się w %s (%d), może brakować miejsca w systemie plików\n" +#: .././io/file.c:42 .././io/open.c:97 +msgid "non-sync" +msgstr "niesynchr" -#: .././repair/phase6.c:1027 -#, c-format -msgid "creation of .. entry failed (%d), filesystem may be out of space\n" -msgstr "tworzenie wpisu .. nie powiodło się (%d), może brakować miejsca w systemie plików\n" +#: .././io/file.c:43 .././io/open.c:98 +msgid "direct" +msgstr "bezpośredni" -#: .././repair/phase6.c:1036 -#, c-format -msgid "bmap finish failed (err - %d), filesystem may be out of space\n" -msgstr "zakończenie bmap nie powiodło się (błąd %d), może brakować miejsca w systemie plików\n" +#: .././io/file.c:43 .././io/open.c:98 +msgid "non-direct" +msgstr "niebezpośredni" -#: .././repair/phase6.c:1078 -#, c-format -msgid "name replace op failed (%d), filesystem may be out of space\n" -msgstr "operacja zastąpienia nazwy nie powiodła się (%d), może brakować miejsca w systemie plików\n" +#: .././io/file.c:44 .././io/open.c:99 +msgid "read-only" +msgstr "tylko do odczytu" -#: .././repair/phase6.c:1085 .././repair/phase6.c:1125 -#: .././repair/phase6.c:1770 -#, c-format -msgid "bmap finish failed (%d), filesystem may be out of space\n" -msgstr "zakończenie bmap nie powiodło się (%d), może brakować miejsca w systemie plików\n" +#: .././io/file.c:44 .././io/open.c:99 +msgid "read-write" +msgstr "odczyt i zapis" -#: .././repair/phase6.c:1163 .././repair/phase6.c:1564 -msgid "dir" -msgstr "katalogu" +#: .././io/file.c:45 .././io/open.c:100 +msgid ",real-time" +msgstr ",real-time" -#: .././repair/phase6.c:1172 .././repair/phase6.c:1176 -#, c-format -msgid "can't map block %d in %s inode %, xfs_bmapi returns %d, nmap = %d\n" -msgstr "nie można odwzorować bloku %d w i-węźle %s %, xfs_bmapi zwraca %d, nmap = %d\n" +#: .././io/file.c:46 .././io/open.c:101 +msgid ",append-only" +msgstr ",tylko dopisywanie" -#: .././repair/phase6.c:1185 .././repair/phase6.c:1189 -#: .././repair/phase6.c:1643 .././repair/phase6.c:1647 -#, c-format -msgid "block %d in %s ino % doesn't exist\n" -msgstr "blok %d w i-węźle %s % nie istnieje\n" +#: .././io/file.c:47 .././io/open.c:102 +msgid ",non-block" +msgstr ",nieblokujący" -#: .././repair/phase6.c:1244 .././repair/phase6.c:1248 -#, c-format -msgid "can't map block %d in %s ino %, xfs_bmapi returns %d, nmap = %d\n" -msgstr "nie można odwzorować bloku %d w i-węźle %s %, xfs_bmapi zwraca %d, nmap = %d\n" +#: .././io/file.c:48 .././io/open.c:103 +msgid ",tmpfile" +msgstr ",tmpfile" -#: .././repair/phase6.c:1256 .././repair/phase6.c:1260 +#: .././io/file.c:82 .././io/sendfile.c:103 .././quota/path.c:112 #, c-format -msgid "block %d in %s inode % doesn't exist\n" -msgstr "blok %d w i-węźle %s % nie istnieje\n" +msgid "value %d is out of range (0-%d)\n" +msgstr "wartość %d jest spoza zakresu (0-%d)\n" -#: .././repair/phase6.c:1283 -msgid ", marking entry to be junked\n" -msgstr ", zaznaczono wpis do wyrzucenia\n" +#: .././io/file.c:95 .././quota/path.c:126 +msgid "[N]" +msgstr "[N]" -#: .././repair/phase6.c:1287 -msgid ", would junk entry\n" -msgstr ", wpis zostałby wyrzucony\n" +#: .././io/file.c:100 +msgid "set the current file" +msgstr "ustawienie bieżącego pliku" -#: .././repair/phase6.c:1404 -#, c-format -msgid "entry \"%s\" in dir inode % points to non-existent inode %" -msgstr "wpis \"%s\" w i-węźle katalogu % wskazuje na nie istniejący i-węzęł %" +#: .././io/file.c:109 +msgid "list current open files and memory mappings" +msgstr "wypisanie aktualnie otwartych plików i odwzorowań w pamięci" -#: .././repair/phase6.c:1422 +#: .././io/freeze.c:37 #, c-format -msgid "entry \"%s\" in dir inode % points to free inode %" -msgstr "wpis \"%s\" w i-węźle katalogu % wskazuje na wolny i-węzeł %" +msgid "%s: cannot freeze filesystem at %s: %s\n" +msgstr "%s: nie można zamrozić systemu plików na %s: %s\n" -#: .././repair/phase6.c:1438 .././repair/phase6.c:2105 -#: .././repair/phase6.c:2733 .././repair/phase6.c:3063 +#: .././io/freeze.c:54 #, c-format -msgid "%s (ino %) in root (%) is not a directory" -msgstr "%s (i-węzeł %) w katalogu głównym (%) nie jest katalogiem" +msgid "%s: cannot unfreeze filesystem mounted at %s: %s\n" +msgstr "%s: nie można odmrozić systemu plików podmontowanego pod %s: %s\n" -#: .././repair/phase6.c:1460 .././repair/phase6.c:2126 -#: .././repair/phase6.c:2751 .././repair/phase6.c:3081 -#, c-format -msgid "entry \"%s\" (ino %) in dir % is a duplicate name" -msgstr "wpis \"%s\" (i-węzeł %) w katalogu % jest powtórzoną nazwą" +#: .././io/freeze.c:70 +msgid "freeze filesystem of current file" +msgstr "zamrożenie systemu plików na bieżącym pliku" -#: .././repair/phase6.c:1491 -#, c-format -msgid "entry \"%s\" in dir ino % points to an already connected dir inode %,\n" -msgstr "wpis \"%s\" w katalogu % wskazuje na już podłączony i-węzeł katalogu %,\n" +#: .././io/freeze.c:77 +msgid "unfreeze filesystem of current file" +msgstr "odmrożenie systemu plików na bieżącym pliku" -#: .././repair/phase6.c:1500 .././repair/phase6.c:2226 -#: .././repair/phase6.c:2785 .././repair/phase6.c:3113 -#, c-format -msgid "entry \"%s\" in dir ino % doesn't have a .. entry, will set it in ino %.\n" -msgstr "wpis \"%s\" w i-węźle katalogu % nie ma wpisu .., zostanie ustawiony w i-węźle %.\n" +#: .././io/fsync.c:59 +msgid "calls fsync(2) to flush all in-core file state to disk" +msgstr "wywołanie fsync(2) aby zrzucić cały stan pliku z pamięci na dysk" -#: .././repair/phase6.c:1508 -#, c-format -msgid "entry \"%s\" in dir ino % not consistent with .. value (%) in ino %,\n" -msgstr "wpis \"%s\" w i-węźle katalogu % niespójny z wartością .. (%) w i-węźle %,\n" +#: .././io/fsync.c:66 +msgid "calls fdatasync(2) to flush the files in-core data to disk" +msgstr "wywołanie fdatasync(2) aby zrzucić dane pliku z pamięci na dysk" -#: .././repair/phase6.c:1522 .././repair/phase6.c:2249 -#, c-format -msgid "\twill clear entry \"%s\"\n" -msgstr "\twpis \"%s\" zostanie wyczyszczony\n" +#: .././io/getrusage.c:118 +msgid "report process resource usage" +msgstr "informacje o wykorzystaniu zasobów przez proces" -#: .././repair/phase6.c:1525 .././repair/phase6.c:2252 +#: .././io/imap.c:53 #, c-format -msgid "\twould clear entry \"%s\"\n" -msgstr "\twpis \"%s\" zostałby wyczyszczony\n" +msgid "ino %10llu count %2d mask %016llx\n" +msgstr "i-węzeł %10llu liczba %2d maska %016llx\n" -#: .././repair/phase6.c:1570 -#, c-format -msgid "cannot map block 0 of directory inode %\n" -msgstr "nie można odwzorować bloku 0 i-węzła katalogu %\n" +#: .././io/imap.c:71 +msgid "[nentries]" +msgstr "[liczba_wpisów]" -#: .././repair/phase6.c:1593 -#, c-format -msgid "bad magic # (0x%x) for dir ino % leaf block (bno %u fsbno %)\n" -msgstr "błędna liczba magiczna (0x%x) dla bloku liścia i-węzła katalogu % (bno %u fsbno %)\n" +#: .././io/imap.c:73 +msgid "inode map for filesystem of current file" +msgstr "map i-węzłów dla systemu plików bieżącego pliku" -#: .././repair/phase6.c:1630 .././repair/phase6.c:1634 +#: .././io/init.c:35 #, c-format -msgid "can't map leaf block %d in dir %, xfs_bmapi returns %d, nmap = %d\n" -msgstr "nie można odwzorować bloku liścia %d w katalogu %, xfs_bmapi zwraca %d, nmap = %d\n" +msgid "Usage: %s [-adfmnrRstVx] [-p prog] [-c cmd]... file\n" +msgstr "Składnia: %s [-adfmnrRstVx] [-p program] [-c polecenie]... plik\n" -#: .././repair/phase6.c:1686 +#: .././io/init.c:105 .././io/mmap.c:168 .././io/mmap.c:175 .././io/mmap.c:178 +#: .././io/open.c:292 #, c-format -msgid "rebuilding directory inode %\n" -msgstr "przebudowywanie i-węzła katalogu %\n" +msgid "no files are open, try 'help open'\n" +msgstr "nie ma otwartych plików, spróbuj 'help open'\n" -#: .././repair/phase6.c:1711 +#: .././io/init.c:109 .././io/mmap.c:167 .././io/mmap.c:174 #, c-format -msgid "xfs_bmap_last_offset failed -- error - %d\n" -msgstr "xfs_bmap_last_offset nie powiodło się - błąd %d\n" +msgid "no mapped regions, try 'help mmap'\n" +msgstr "nie ma podmapowanych regionów, spróbuj 'help mmap'\n" -#: .././repair/phase6.c:1718 +#: .././io/init.c:115 #, c-format -msgid "xfs_bunmapi failed -- error - %d\n" -msgstr "xfs_bunmapi nie powiodło się - błąd %d\n" +msgid "foreign file active, %s command is for XFS filesystems only\n" +msgstr "aktywny jest plik obcy, polecenie %s jest tylko dla systemów plików XFS\n" -#: .././repair/phase6.c:1760 +#: .././io/init.c:160 .././io/open.c:314 #, c-format -msgid "name create failed in ino % (%d), filesystem may be out of space\n" -msgstr "tworzenie nazwy nie powiodło się w i-węźle % (%d), może brakować miejsca w systemie plików\n" +msgid "non-numeric mode -- %s\n" +msgstr "tryb nieliczbowy - %s\n" -#: .././repair/phase6.c:1825 +#: .././io/inject.c:109 #, c-format -msgid "shrink_inode failed inode % block %u\n" -msgstr "shrink_inode nie powiodło się dla i-węzła % bloku %u\n" +msgid "" +"\n" +" inject errors into the filesystem of the currently open file\n" +"\n" +" Example:\n" +" 'inject readagf' - cause errors on allocation group freespace reads\n" +"\n" +" Causes the kernel to generate and react to errors within XFS, provided\n" +" the XFS kernel code has been built with debugging features enabled.\n" +" With no arguments, displays the list of error injection tags.\n" +"\n" +msgstr "" +"\n" +" wprowadzenie błędów do systemu plików aktualnie otwartego pliku\n" +"\n" +" Przykład:\n" +" 'inject readagf' - spowodowanie błędów przy odczytach wolnego miejsca grup\n" +" alokacji\n" +"\n" +" inject powoduje, że jądro generuje i reaguje na błędy wewnątrz XFS-a,\n" +" pod warunkiem, że kod XFS-a w jądrze został zbudowany z włączonymi opcjami\n" +" diagnostycznymi. Bez argumentów wyświetla listę znaczników wprowadzania\n" +" błędów.\n" +"\n" -#: .././repair/phase6.c:1906 +#: .././io/inject.c:135 #, c-format -msgid "realloc failed in longform_dir2_entry_check_data (%zu bytes)\n" -msgstr "realloc nie powiodło się w longform_dir2_entry_check_data (%zu bajtów)\n" +msgid "no such tag -- %s\n" +msgstr "nie ma takiego znacznika - %s\n" -#: .././repair/phase6.c:1963 -#, c-format -msgid "empty data block %u in directory inode %: " -msgstr "pusty blok danych %u w i-węźle katalogu %: " +#: .././io/inject.c:156 +msgid "[tag ...]" +msgstr "[znacznik ...]" + +#: .././io/inject.c:157 +msgid "inject errors into a filesystem" +msgstr "wprowadzanie błędów do systemu plików" -#: .././repair/phase6.c:1967 +#: .././io/link.c:35 #, c-format -msgid "corrupt block %u in directory inode %: " -msgstr "uszkodzony blok %u w i-węźle katalogu %: " +msgid "" +"\n" +"link the open file descriptor to the supplied filename\n" +"\n" +"\n" +msgstr "" +"\n" +"dowiązanie otwartego deskryptora pliku do podanej nazwy pliku\n" +"\n" +"\n" -#: .././repair/phase6.c:1971 -msgid "junking block\n" -msgstr "wyrzucono blok\n" +#: .././io/link.c:64 +msgid "filename" +msgstr "nazwa_pliku" -#: .././repair/phase6.c:1974 -msgid "would junk block\n" -msgstr "blok zostałby wyrzucony\n" +#: .././io/link.c:66 +msgid "link the open file descriptor to the supplied filename" +msgstr "dowiązanie otwartego deskryptora pliku do podanej nazwy pliku" -#: .././repair/phase6.c:1998 +#: .././io/madvise.c:32 #, c-format -msgid "bad directory block magic # %#x for directory inode % block %d: " -msgstr "błędna liczba magiczna bloku katalogu %#x dla i-węzła katalogu % bloku %d: " +msgid "" +"\n" +" advise the page cache about access patterns expected for a mapping\n" +"\n" +" Modifies page cache behavior when operating on the current mapping.\n" +" The range arguments are required by some advise commands ([*] below).\n" +" With no arguments, the POSIX_MADV_NORMAL advice is implied.\n" +" -d -- don't need these pages (POSIX_MADV_DONTNEED) [*]\n" +" -r -- expect random page references (POSIX_MADV_RANDOM)\n" +" -s -- expect sequential page references (POSIX_MADV_SEQUENTIAL)\n" +" -w -- will need these pages (POSIX_MADV_WILLNEED) [*]\n" +" Notes:\n" +" NORMAL sets the default readahead setting on the file.\n" +" RANDOM sets the readahead setting on the file to zero.\n" +" SEQUENTIAL sets double the default readahead setting on the file.\n" +" WILLNEED forces the maximum readahead.\n" +"\n" +msgstr "" +"\n" +" doradzenie buforowi stron w sprawie oczekiwanych schematów dostępu do odwzorowań\n" +"\n" +" madvise modyfikuje zachowanie bufora stron przy operacjach na bieżącym\n" +" odwzorowaniu. Niektóre polecenia madvise ([*] poniżej) wymagają podania zakresu.\n" +" Bez argumentów zakłada się doradzenie POSIX_MADV_NORMAL.\n" +" -d - podane strony nie są wymagane (POSIX_MADV_DONTNEED) [*]\n" +" -r - należy oczekiwać losowych odwołań do stron (POSIX_MADV_RANDOM)\n" +" -s - należy oczekiwać sekwencyjnych odwołań do stron (POSIX_MADV_SEQUENTIAL)\n" +" -w - podane strony będą potrzebne (POSIX_MADV_WILLNEED) [*]\n" +" Uwagi:\n" +" NORMAL ustawia domyślną wartość czytania z wyprzedzeniem dla pliku.\n" +" RANDOM ustawia czytanie z wyprzedzeniem dla pliku na zero.\n" +" SEQUENTIAL ustawia podwójną domyślną wartość czytania z wyprzedzeniem.\n" +" WILLNEED wymusza maksymalne czytanie z wyprzedzeniem.\n" +"\n" -#: .././repair/phase6.c:2001 +#: .././io/madvise.c:98 .././io/mincore.c:58 #, c-format -msgid "fixing magic # to %#x\n" -msgstr "poprawiono liczbę magiczną na %#x\n" +msgid "length argument too large -- %lld\n" +msgstr "zbyt duży argument będący długością - %lld\n" -#: .././repair/phase6.c:2005 -#, c-format -msgid "would fix magic # to %#x\n" -msgstr "liczba magiczna zostałaby poprawiona na %#x\n" +#: .././io/madvise.c:127 +msgid "[-drsw] [off len]" +msgstr "[-drsw] [offset długość]" + +#: .././io/madvise.c:128 +msgid "give advice about use of memory" +msgstr "doradzenie w sprawie użycia pamięci" -#: .././repair/phase6.c:2026 +#: .././io/mincore.c:92 .././io/mincore.c:102 #, c-format -msgid "directory inode % block %u has consecutive free entries: " -msgstr "i-węzeł katalogu % blok %u ma kolejne wolne wpisy: " +msgid "0x%lx %lu pages (%llu : %lu)\n" +msgstr "0x%lx %lu stron (%llu : %lu)\n" -#: .././repair/phase6.c:2029 -msgid "joining together\n" -msgstr "połączono\n" +#: .././io/mincore.c:122 +msgid "[off len]" +msgstr "[offset długość]" -#: .././repair/phase6.c:2038 -msgid "would join together\n" -msgstr "zostałyby połączone\n" +#: .././io/mincore.c:123 +msgid "find mapping pages that are memory resident" +msgstr "odnalezienie stron odwzorowań przechowywanych w pamięci" -#: .././repair/phase6.c:2070 +#: .././io/mmap.c:76 #, c-format -msgid "entry \"%s\" in directory inode % points to non-existent inode %" -msgstr "wpis \"%s\" w i-węźle katalogu % wskazuje na nie istniejący i-węzeł %" +msgid "offset (%lld) is before start of mapping (%lld)\n" +msgstr "offset (%lld) przed początkiem odwzorowania (%lld)\n" -#: .././repair/phase6.c:2087 +#: .././io/mmap.c:82 #, c-format -msgid "entry \"%s\" in directory inode % points to free inode %" -msgstr "wpis \"%s\" w i-węźle katalogu % wskazuje na wolny i-węzeł %" +msgid "offset (%lld) is beyond end of mapping (%lld)\n" +msgstr "offset (%lld) za końcem odwzorowania (%lld)\n" -#: .././repair/phase6.c:2157 +#: .././io/mmap.c:87 #, c-format -msgid "entry \"%s\" (ino %) in dir % is not in the the first block" -msgstr "wpis \"%s\" (i-węzeł %) w katalogu % nie jest w pierwszym bloku" +msgid "range (%lld:%lld) is beyond mapping (%lld:%ld)\n" +msgstr "przedział (%lld:%lld) poza odwzorowaniem (%lld:%ld)\n" -#: .././repair/phase6.c:2182 +#: .././io/mmap.c:93 #, c-format -msgid "entry \"%s\" in dir % is not the first entry" -msgstr "wpis \"%s\" w katalogu % nie jest pierwszym wpisem" +msgid "offset address (%p) is not page aligned\n" +msgstr "adres offsetu (%p) nie jest wyrównany do rozmiaru strony\n" -#: .././repair/phase6.c:2217 +#: .././io/mmap.c:133 #, c-format -msgid "entry \"%s\" in dir % points to an already connected directory inode %\n" -msgstr "wpis \"%s\" w katalogu % wskazuje na już podłączony i-węzeł katalogu %\n" +msgid "" +"\n" +" maps a range within the current file into memory\n" +"\n" +" Example:\n" +" 'mmap -rw 0 1m' - maps one megabyte from the start of the current file\n" +"\n" +" Memory maps a range of a file for subsequent use by other xfs_io commands.\n" +" With no arguments, mmap shows the current mappings. The current mapping\n" +" can be set by using the single argument form (mapping number or address).\n" +" If two arguments are specified (a range), a new mapping is created and the\n" +" following options are available:\n" +" -r -- map with PROT_READ protection\n" +" -w -- map with PROT_WRITE protection\n" +" -x -- map with PROT_EXEC protection\n" +" If no protection mode is specified, all are used by default.\n" +"\n" +msgstr "" +"\n" +" odwzorowanie przedziału z bieżącego pliku w pamięci\n" +"\n" +"Przykład:\n" +" 'mmap -rw 0 1m' - odwzorowuje 1MB od początku bieżącego pliku\n" +"\n" +" mmap odwzorowuje w pamięci przedział z pliku do dalszego wykorzystania przez\n" +" inne polecenia xfs_io.\n" +" Bez argumentów mmap pokazuje aktualne odwzorowania. Bieżące odwzorowanie\n" +" można ustawić przy użyciu formy jednoargumentowej (mmap numer lub adres).\n" +" Jeśli podano dwa argumenty (przedział), tworzone jest nowe odwzorowanie\n" +" i dostępne są następujące opcje:\n" +" -r - odwzorowanie z ochroną PROT_READ\n" +" -w - odwzorowanie z ochroną PROT_WRITE\n" +" -x - odwzorowanie z ochroną PROT_EXEC\n" +" Jeśli nie podano trybu ochrony, domyślnie używane są wszystkie.\n" +"\n" -#: .././repair/phase6.c:2236 +#: .././io/mmap.c:254 #, c-format -msgid "entry \"%s\" in dir inode % inconsistent with .. value (%) in ino %\n" -msgstr "wpis \"%s\" w i-węźle katalogu % niespójny z wartością .. (%) w i-węźle %\n" +msgid "" +"\n" +" flushes a range of bytes in the current memory mapping\n" +"\n" +" Writes all modified copies of pages over the specified range (or entire\n" +" mapping if no range specified) to their backing storage locations. Also,\n" +" optionally invalidates so that subsequent references to the pages will be\n" +" obtained from their backing storage locations (instead of cached copies).\n" +" -a -- perform asynchronous writes (MS_ASYNC)\n" +" -i -- invalidate mapped pages (MS_INVALIDATE)\n" +" -s -- perform synchronous writes (MS_SYNC)\n" +"\n" +msgstr "" +"\n" +" zrzucenie przedziału bajtów w bieżącym odwzorowaniu pamięci\n" +"\n" +" msync zapisuje wszystkie zmodyfikowane kopie stron z podanego przedziału\n" +" (lub całego odwzorowania, jeśli nie podano przedziału) do miejsca\n" +" przechowywania danych. Opcjonalnie unieważnia bufor, żeby dalsze odwołania\n" +" do tych stron odbywały się z miejsca przechowywania danych (zamiast kopii\n" +" w pamięci podręcznej).\n" +" -a - wykonanie zapisu asynchronicznego (MS_ASYNC)\n" +" -i - unieważnienie odwzorowanych stron (MS_INVALIDATE)\n" +" -s - wykonanie zapisu synchronicznego (MS_SYNC)\n" +"\n" -#: .././repair/phase6.c:2307 .././repair/phase6.c:2387 +#: .././io/mmap.c:330 #, c-format -msgid "leaf block %u for directory inode % bad header\n" -msgstr "błędny nagłówek bloku liścia %u dla i-węzła katalogu %\n" +msgid "" +"\n" +" reads a range of bytes in the current memory mapping\n" +"\n" +" Example:\n" +" 'mread -v 512 20' - dumps 20 bytes read from 512 bytes into the mapping\n" +"\n" +" Accesses a range of the current memory mapping, optionally dumping it to\n" +" the standard output stream (with -v option) for subsequent inspection.\n" +" -f -- verbose mode, dump bytes with offsets relative to start of file.\n" +" -r -- reverse order; start accessing from the end of range, moving backward\n" +" -v -- verbose mode, dump bytes with offsets relative to start of mapping.\n" +" The accesses are performed sequentially from the start offset by default.\n" +" Notes:\n" +" References to whole pages following the end of the backing file results\n" +" in delivery of the SIGBUS signal. SIGBUS signals may also be delivered\n" +" on various filesystem conditions, including quota exceeded errors, and\n" +" for physical device errors (such as unreadable disk blocks). No attempt\n" +" has been made to catch signals at this stage...\n" +"\n" +msgstr "" +"\n" +" odczytanie przedziału bajtów w bieżącym odwzorowaniu pamięci\n" +"\n" +" Przykład:\n" +" 'mread -v 512 20' - zrzucenie 20 bajtów odczytanych od 512 bajtu\n" +" w odwzorowaniu\n" +"\n" +" mread odwołuje się do przedziału bieżącego odwzorowania pamięci, opcjonalnie\n" +" zrzucając go na strumień standardowego wyjścia (z opcją -v) do dalszych badań.\n" +" -f - tryb szczegółowy, zrzucenie bajtów z offsetami względem początku pliku.\n" +" -r - odwrotna kolejność; dostęp począwszy od końca przedziału do początku.\n" +" -v - tryb szczegółowy, zrzucenie bajtów z offsetami względem początku\n" +" odwzorowania.\n" +" Dostępy są wykonywane sekwencyjnie, domyślnie od offsetu początkowego.\n" +" Uwagi:\n" +" Odwołania do całych stron za końcem pliku powodują w efekcie sygnał SIGBUS.\n" +" Sygnały SIGBUS mogą być wywołane także przy różnych zdarzeniach związanych\n" +" z systemem plików, włącznie z błędami przekroczenia limitów (quota) oraz\n" +" fizycznymi błędami urządzenia (takimi jak nieczytelne bloki dysku). Na tym\n" +" etapie nie ma prób wyłapania sygnałów...\n" +"\n" -#: .././repair/phase6.c:2326 +#: .././io/mmap.c:494 #, c-format -msgid "leaf block %u for directory inode % bad tail\n" -msgstr "błędna końcówka bloku liścia %u dla i-węzła katalogu %\n" +msgid "" +"\n" +" dirties a range of bytes in the current memory mapping\n" +"\n" +" Example:\n" +" 'mwrite 512 20 - writes 20 bytes at 512 bytes into the current mapping.\n" +"\n" +" Stores a byte into memory for a range within a mapping.\n" +" The default stored value is 'X', repeated to fill the range specified.\n" +" -S -- use an alternate seed character\n" +" -r -- reverse order; start storing from the end of range, moving backward\n" +" The stores are performed sequentially from the start offset by default.\n" +"\n" +msgstr "" +"\n" +" zmiana przedziału bajtów w bieżącym odwzorowaniu pamięci\n" +"\n" +" Przykład:\n" +" 'mwrite 512 20' - zapisuje 20 bajtów od 512 bajtu w bieżącym odwzorowaniu.\n" +"\n" +" mwrite zapisuje bajt do przedziału pamięci w ramach odwzorowania.\n" +" Domyślnie zapisywaną wartością jest 'X', powtarzane do wypełnienia przedziału.\n" +" -S - użycie alternatywnego znaku\n" +" -r - odwrotna kolejność; rozpoczęcie zapisywania od końca przedziału do\n" +" początku\n" +" Zapisy są wykonywane kolejno, domyślnie od offsetu początkowego.\n" +"\n" -#: .././repair/phase6.c:2365 +#: .././io/mmap.c:530 .././io/pread.c:437 .././io/pwrite.c:303 +#: .././io/pwrite.c:330 #, c-format -msgid "can't read leaf block %u for directory inode %\n" -msgstr "nie można odczytać bloku liścia %u dla i-węzła katalogu %\n" +msgid "non-numeric seed -- %s\n" +msgstr "nieliczbowy zarodek - %s\n" -#: .././repair/phase6.c:2377 -#, c-format -msgid "unknown magic number %#x for block %u in directory inode %\n" -msgstr "nieznana liczba magiczna %#x dla bloku %u w i-węźle katalogu %\n" +#: .././io/mmap.c:586 +msgid "[N] | [-rwx] [off len]" +msgstr "[N] | [-rwx] [offset długość]" -#: .././repair/phase6.c:2411 -#, c-format -msgid "can't read freespace block %u for directory inode %\n" -msgstr "nie można odczytać bloku wolnego miejsca %u dla i-węzła katalogu %\n" +#: .././io/mmap.c:588 +msgid "mmap a range in the current file, show mappings" +msgstr "odwzorowanie przedziału w bieżącym pliku, pokazanie odwzorowań" -#: .././repair/phase6.c:2424 -#, c-format -msgid "free block %u for directory inode % bad header\n" -msgstr "błędny nagłówek wolnego bloku %u dla i-węzła katalogu %\n" +#: .././io/mmap.c:597 +msgid "[-r] [off len]" +msgstr "[-r] [offset długość]" -#: .././repair/phase6.c:2436 -#, c-format -msgid "free block %u entry %i for directory ino % bad\n" -msgstr "błędny wpis wolnego bloku %u numer %i dla i-węzła katalogu %\n" +#: .././io/mmap.c:599 +msgid "reads data from a region in the current memory mapping" +msgstr "odczyt danych z regionu w bieżącym odwzorowaniu pamięci" -#: .././repair/phase6.c:2446 -#, c-format -msgid "free block %u for directory inode % bad nused\n" -msgstr "błędna liczba nused w wolnym bloku %u dla i-węzła katalogu %\n" +#: .././io/mmap.c:608 +msgid "[-ais] [off len]" +msgstr "[-ais] [offset długość]" -#: .././repair/phase6.c:2457 -#, c-format -msgid "missing freetab entry %u for directory inode %\n" -msgstr "brak wpisu freetab %u dla i-węzła katalogu %\n" +#: .././io/mmap.c:609 +msgid "flush a region in the current memory mapping" +msgstr "zrzucenie regionu w bieżącym odwzorowaniu pamięci" -#: .././repair/phase6.c:2497 -#, c-format -msgid "malloc failed in longform_dir2_entry_check (% bytes)\n" -msgstr "malloc nie powiodło się w longform_dir2_entry_check (% bajtów)\n" +#: .././io/mmap.c:618 +msgid "unmaps the current memory mapping" +msgstr "usunięcie bieżącego odwzorowania pamięci" -#: .././repair/phase6.c:2527 -#, c-format -msgid "realloc failed in longform_dir2_entry_check (%zu bytes)\n" -msgstr "realloc nie powiodło się w longform_dir2_entry_check (%zu bajtów)\n" +#: .././io/mmap.c:626 +msgid "[-r] [-S seed] [off len]" +msgstr "[-r] [-S wartość] [offset długość]" -#: .././repair/phase6.c:2533 -#, c-format -msgid "can't read data block %u for directory inode %\n" -msgstr "nie można odczytać bloku danych %u dla i-węzła katalogu %\n" +#: .././io/mmap.c:628 +msgid "writes data into a region in the current memory mapping" +msgstr "zapis danych do regionu w bieżącym odwzorowaniu pamięci" -#: .././repair/phase6.c:2639 -#, c-format -msgid "shortform dir inode % has null data entries \n" -msgstr "i-węzeł krótkiego katalogu % ma zerowe wpisy danych\n" +#: .././io/open.c:68 +msgid "socket" +msgstr "gniazdo" -#: .././repair/phase6.c:2707 -#, c-format -msgid "entry \"%s\" in shortform dir % references non-existent ino %\n" -msgstr "wpis \"%s\" w krótkim katalogu % odwołuje się do nie istniejącego i-węzła %\n" +#: .././io/open.c:70 +msgid "directory" +msgstr "katalog" -#: .././repair/phase6.c:2720 -#, c-format -msgid "entry \"%s\" in shortform dir inode % points to free inode %\n" -msgstr "wpis \"%s\" w i-węźle krótkiego katalogu % wskazuje na wolny i-węzeł %\n" +#: .././io/open.c:72 +msgid "char device" +msgstr "urządzenie znakowe" -#: .././repair/phase6.c:2776 -#, c-format -msgid "entry \"%s\" in dir % references already connected dir ino %.\n" -msgstr "wpis \"%s\" w katalogu % odwołuje się do już podłączonego i-węzła katalogu %.\n" +#: .././io/open.c:74 +msgid "block device" +msgstr "urządzenie blokowe" -#: .././repair/phase6.c:2793 -#, c-format -msgid "entry \"%s\" in dir % not consistent with .. value (%) in dir ino %.\n" -msgstr "wpis \"%s\" w katalogu % niespójny z wartością .. (%) w i-węźle katalogu %.\n" +#: .././io/open.c:76 +msgid "regular file" +msgstr "plik zwykły" -#: .././repair/phase6.c:2833 .././repair/phase6.c:3166 -msgid "junking entry\n" -msgstr "wyrzucono wpis\n" +#: .././io/open.c:78 +msgid "symbolic link" +msgstr "dowiązanie symboliczne" -#: .././repair/phase6.c:2837 .././repair/phase6.c:3170 -msgid "would junk entry\n" -msgstr "wpis zostałby wyrzucony\n" +#: .././io/open.c:80 +msgid "fifo" +msgstr "potok" -#: .././repair/phase6.c:2876 .././repair/phase6.c:3228 +#: .././io/open.c:95 .././io/open.c:707 #, c-format -msgid "setting size to % bytes to reflect junked entries\n" -msgstr "ustawiono rozmiar na %, aby odzwierciedlał wyrzucone wpisy\n" +msgid "fd.path = \"%s\"\n" +msgstr "fd.path = \"%s\"\n" -#: .././repair/phase6.c:2928 +#: .././io/open.c:96 #, c-format -msgid "would set .. in sf dir inode % to %\n" -msgstr "wpis .. w i-węźle katalogu sf % zostałby ustawiony na %\n" +msgid "fd.flags = %s,%s,%s%s%s%s%s\n" +msgstr "fd.flags = %s,%s,%s%s%s%s%s\n" -#: .././repair/phase6.c:2932 +#: .././io/open.c:107 #, c-format -msgid "setting .. in sf dir inode % to %\n" -msgstr "ustawiono wpis .. w i-węźle katalogu sf % na %\n" +msgid "stat.ino = %lld\n" +msgstr "stat.ino = %lld\n" -#: .././repair/phase6.c:3036 +#: .././io/open.c:108 #, c-format -msgid "entry \"%s\" in shortform directory % references non-existent inode %\n" -msgstr "wpis \"%s\" w krótkim katalogu % odwołuje się do nie istniejącego i-węzła %\n" +msgid "stat.type = %s\n" +msgstr "stat.type = %s\n" -#: .././repair/phase6.c:3050 +#: .././io/open.c:109 #, c-format -msgid "entry \"%s\" in shortform directory inode % points to free inode %\n" -msgstr "wpis \"%s\" w i-węźle krótkiego katalogu % wskazuje na wolny i-węzeł %\n" +msgid "stat.size = %lld\n" +msgstr "stat.size = %lld\n" -#: .././repair/phase6.c:3103 +#: .././io/open.c:110 #, c-format -msgid "entry \"%s\" in directory inode % references already connected inode %.\n" -msgstr "wpis \"%s\" w i-węźle katalogu % odwołuje się do już podłączonego i-węzła %.\n" +msgid "stat.blocks = %lld\n" +msgstr "stat.blocks = %lld\n" -#: .././repair/phase6.c:3123 +#: .././io/open.c:112 #, c-format -msgid "entry \"%s\" in directory inode % not consistent with .. value (%) in inode %,\n" -msgstr "wpis \"%s\" w i-węźle katalogu % niespójny z wartością .. (%) w i-węźle %,\n" +msgid "stat.atime = %s" +msgstr "stat.atime = %s" -#: .././repair/phase6.c:3194 +#: .././io/open.c:113 #, c-format -msgid "would fix i8count in inode %\n" -msgstr "i8count w i-węźle % zostałoby poprawione\n" +msgid "stat.mtime = %s" +msgstr "stat.mtime = %s" -#: .././repair/phase6.c:3207 +#: .././io/open.c:114 #, c-format -msgid "fixing i8count in inode %\n" -msgstr "poprawiono i8count w i-węźle %\n" - -#: .././repair/phase6.c:3382 -msgid "missing root directory .. entry, cannot fix in V1 dir filesystem\n" -msgstr "brak wpisu .. w głównym katalogu, nie można naprawić w systemie plików V1\n" +msgid "stat.ctime = %s" +msgstr "stat.ctime = %s" -#: .././repair/phase6.c:3389 +#: .././io/open.c:123 #, c-format -msgid "%d bad entries found in dir inode %, cannot fix in V1 dir filesystem\n" -msgstr "znaleziono %d błędnych wpisów w i-węźle katalogu %, nie można naprawić w systemie plików V1\n" +msgid "fsxattr.xflags = 0x%x " +msgstr "fsxattr.xflags = 0x%x " -#: .././repair/phase6.c:3396 +#: .././io/open.c:125 #, c-format -msgid "missing \".\" entry in dir ino %, cannot in fix V1 dir filesystem\n" -msgstr "brak wpisu \".\" w i-węźle katalogu %, nie można naprawić w systemie plików V1\n" +msgid "fsxattr.projid = %u\n" +msgstr "fsxattr.projid = %u\n" -#: .././repair/phase6.c:3414 -msgid "recreating root directory .. entry\n" -msgstr "ponowne tworzenie wpisu .. głównego katalogu\n" +#: .././io/open.c:126 +#, c-format +msgid "fsxattr.extsize = %u\n" +msgstr "fsxattr.extsize = %u\n" -#: .././repair/phase6.c:3434 +#: .././io/open.c:127 #, c-format -msgid "can't make \"..\" entry in root inode %, createname error %d\n" -msgstr "nie można utworzyć wpisu \"..\" w i-węźle głównego katalogu %, błąd createname %d\n" +msgid "fsxattr.nextents = %u\n" +msgstr "fsxattr.nextents = %u\n" -#: .././repair/phase6.c:3445 -msgid "would recreate root directory .. entry\n" -msgstr "wpis .. głównego katalogu zostałby ponownie utworzony\n" +#: .././io/open.c:128 +#, c-format +msgid "fsxattr.naextents = %u\n" +msgstr "fsxattr.naextents = %u\n" -#: .././repair/phase6.c:3469 +#: .././io/open.c:133 #, c-format -msgid "would create missing \".\" entry in dir ino %\n" -msgstr "brakujący wpis \".\" w i-węźle katalogu % zostałby utworzony\n" +msgid "dioattr.mem = 0x%x\n" +msgstr "dioattr.mem = 0x%x\n" -#: .././repair/phase6.c:3476 +#: .././io/open.c:134 #, c-format -msgid "creating missing \".\" entry in dir ino %\n" -msgstr "tworzenie brakującego wpisu \".\" w i-węźle katalogu %\n" +msgid "dioattr.miniosz = %u\n" +msgstr "dioattr.miniosz = %u\n" -#: .././repair/phase6.c:3500 +#: .././io/open.c:135 #, c-format -msgid "can't make \".\" entry in dir ino %, createname error %d\n" -msgstr "nie można utworzyć wpisu \".\" w i-węźle katalogu %, błąd createname %d\n" +msgid "dioattr.maxiosz = %u\n" +msgstr "dioattr.maxiosz = %u\n" -#: .././repair/phase6.c:3589 +#: .././io/open.c:254 #, c-format -msgid "disconnected dir inode %, " -msgstr "odłączony i-węzeł katalogu %, " +msgid "" +"\n" +" opens a new file in the requested mode\n" +"\n" +" Example:\n" +" 'open -cd /tmp/data' - creates/opens data file read-write for direct IO\n" +"\n" +" Opens a file for subsequent use by all of the other xfs_io commands.\n" +" With no arguments, open uses the stat command to show the current file.\n" +" -a -- open with the O_APPEND flag (append-only mode)\n" +" -d -- open with O_DIRECT (non-buffered IO, note alignment constraints)\n" +" -f -- open with O_CREAT (create the file if it doesn't exist)\n" +" -m -- permissions to use in case a new file is created (default 0600)\n" +" -n -- open with O_NONBLOCK\n" +" -r -- open with O_RDONLY, the default is O_RDWR\n" +" -s -- open with O_SYNC\n" +" -t -- open with O_TRUNC (truncate the file to zero length if it exists)\n" +" -R -- mark the file as a realtime XFS file immediately after opening it\n" +" -T -- open with O_TMPFILE (create a file not visible in the namespace)\n" +" Note1: usually read/write direct IO requests must be blocksize aligned;\n" +" some kernels, however, allow sectorsize alignment for direct IO.\n" +" Note2: the bmap for non-regular files can be obtained provided the file\n" +" was opened correctly (in particular, must be opened read-only).\n" +"\n" +msgstr "" +"\n" +" otwarcie nowego pliku w żądanym trybie\n" +"\n" +" Przykład:\n" +" 'open -cd /tmp/data' - utworzenie/otwarcie pliku danych do odczytu i zapisu\n" +" z bezpośrednim we/wy\n" +"\n" +" open otwiera plik do późniejszego wykorzystania przez wszystkie inne polecenia\n" +" xfs_io.\n" +" Bez argumentów używa polecenia stat do pokazania bieżącego pliku.\n" +" -a - otwarcie z flagą O_APPEND (w trybie tylko dopisywania)\n" +" -d - otwarcie z flagą O_DIRECT (niebuforowane we/wy, ograniczenia wyrównania)\n" +" -f - otwarcie z flagą O_CREAT (utworzenie pliku jeśli nie istnieje)\n" +" -m - uprawnienia do użycia w przypadku tworzenia pliku (domyślnie 0600)\n" +" -n - otwarcie z flagą O_NONBLOCK\n" +" -r - otwarcie z flagą O_RDONLY (domyślne jest O_RDWR)\n" +" -s - otwarcie z flagą O_SYNC\n" +" -t - otwarcie z flagą O_TRUNC (ucięcie do zerowej długości jeśli istnieje)\n" +" -R - oznaczenie pliku jako realtime na XFS-ie zaraz po otwarciu\n" +" -T - otwarcie z flagą O_TMPFILE (utworzenie pliku niewidocznego w przestrzni\n" +" nazw)\n" +" Uwaga1: zwykle żądania bezpośredniego we/wy muszą być wyrównane do rozmiaru\n" +" bloku; niektóre jądra pozwalają na wyrównanie do rozmiaru sektora\n" +" Uwaga2: bmap dla plików innych niż zwykłe można uzyskać pod warunkiem, że\n" +" plik zostanie poprawnie otwarty (w szczególności tylko do odczytu).\n" +"\n" -#: .././repair/phase6.c:3591 +#: .././io/open.c:346 #, c-format -msgid "disconnected inode %, " -msgstr "odłączony i-węzeł %, " +msgid "-T and -r options are incompatible\n" +msgstr "Opcje -T i -r nie są zgodne ze sobą\n" -#: .././repair/phase6.c:3593 -msgid "cannot fix in V1 dir filesystem\n" -msgstr "nie można naprawić w systemie plików katalogów V1\n" +#: .././io/open.c:401 +#, c-format +msgid "" +"\n" +" displays the project identifier associated with the current path\n" +"\n" +" Options:\n" +" -R -- recursively descend (useful when current path is a directory)\n" +" -D -- recursively descend, but only list projects on directories\n" +"\n" +msgstr "" +"\n" +" wyświetlenie identyfikatora projektu związanego z bieżącą ścieżką\n" +"\n" +" Opcje:\n" +" -R - rekurencyjne zagłębianie się (przydatne kiedy bieżący plik jest katalogiem)\n" +" -D - rekurencyjne zagłębianie się, ale wypisywanie projektów tylko katalogów\n" +"\n" -#: .././repair/phase6.c:3597 +#: .././io/open.c:467 #, c-format -msgid "moving to %s\n" -msgstr "przeniesiono do %s\n" +msgid "projid = %u\n" +msgstr "projid = %u\n" -#: .././repair/phase6.c:3600 +#: .././io/open.c:475 #, c-format -msgid "would move to %s\n" -msgstr "zostałby przeniesiony do %s\n" +msgid "" +"\n" +" modifies the project identifier associated with the current path\n" +"\n" +" -R -- recursively descend (useful when current path is a directory)\n" +" -D -- recursively descend, only modifying projects on directories\n" +"\n" +msgstr "" +"\n" +" modyfikacja identyfikatora projektu związanego z bieżącą ścieżką\n" +"\n" +" -R - rekurencyjne zagłębianie się (przydatne kiedy bieżący plik jest katalogiem)\n" +" -D - rekurencyjne zagłębianie się, ale zmiana projektów tylko katalogów\n" +"\n" -#: .././repair/phase6.c:3691 -msgid "Phase 6 - check inode connectivity...\n" -msgstr "Faza 6 - sprawdzanie łączności i-węzłów...\n" +#: .././io/open.c:534 +#, c-format +msgid "invalid project ID -- %s\n" +msgstr "nieprawidłowy ID projektu - %s\n" -#: .././repair/phase6.c:3705 -msgid "need to reinitialize root directory, but not supported on V1 dir filesystem\n" -msgstr "trzeba ponownie utworzyć główny katalog, co nie jest obsługiwane w systemie plików V1\n" +#: .././io/open.c:550 +#, c-format +msgid "" +"\n" +" report or modify preferred extent size (in bytes) for the current path\n" +"\n" +" -R -- recursively descend (useful when current path is a directory)\n" +" -D -- recursively descend, only modifying extsize on directories\n" +"\n" +msgstr "" +"\n" +" odczyt lub zmiana preferowanego rozmiaru ekstentu (w bajtach) dla bieżącej\n" +" ścieżki\n" +"\n" +" -R - rekurencyjne zagłębianie się (przydatne kiedy bieżący plik jest katalogiem)\n" +" -D - rekurencyjne zagłębianie się, ale zmiana extsize tylko katalogów\n" +"\n" -#: .././repair/phase6.c:3708 -msgid "reinitializing root directory\n" -msgstr "ponowne inicjowanie głównego katalogu\n" +#: .././io/open.c:593 +#, c-format +msgid "invalid target file type - file %s\n" +msgstr "nieprawidłowy rodzaj bliku docelowego - plik %s\n" -#: .././repair/phase6.c:3713 -msgid "would reinitialize root directory\n" -msgstr "główny katalog zostałby ponownie zainicjowany\n" +#: .././io/open.c:679 +#, c-format +msgid "non-numeric extsize argument -- %s\n" +msgstr "nieliczbowy argument extsize - %s\n" -#: .././repair/phase6.c:3719 -msgid "reinitializing realtime bitmap inode\n" -msgstr "ponowne inicjowanie i-węzła bitmapy realtime\n" +#: .././io/open.c:711 +#, c-format +msgid "statfs.f_bsize = %lld\n" +msgstr "statfs.f_bsize = %lld\n" -#: .././repair/phase6.c:3723 -msgid "would reinitialize realtime bitmap inode\n" -msgstr "i-węzeł bitmapy realtime zostałby ponownie zainicjowany\n" +#: .././io/open.c:712 +#, c-format +msgid "statfs.f_blocks = %lld\n" +msgstr "statfs.f_blocks = %lld\n" -#: .././repair/phase6.c:3729 -msgid "reinitializing realtime summary inode\n" -msgstr "ponowne inicjowanie i-węzła opisu realtime\n" +#: .././io/open.c:714 +#, c-format +msgid "statfs.f_frsize = %lld\n" +msgstr "statfs.f_frsize = %lld\n" -#: .././repair/phase6.c:3733 -msgid "would reinitialize realtime summary inode\n" -msgstr "i-węzeł opisu realtime zostałby ponownie zainicjowany\n" +#: .././io/open.c:716 +#, c-format +msgid "statfs.f_bavail = %lld\n" +msgstr "statfs.f_bavail = %lld\n" -#: .././repair/phase6.c:3739 -msgid " - resetting contents of realtime bitmap and summary inodes\n" -msgstr " - przestawianie zawartości i-węzłów bitmapy i opisu realtime\n" +#: .././io/open.c:718 +#, c-format +msgid "statfs.f_files = %lld\n" +msgstr "statfs.f_files = %lld\n" -#: .././repair/phase6.c:3742 .././repair/phase6.c:3747 -msgid "Warning: realtime bitmap may be inconsistent\n" -msgstr "Uwaga: bitmapa realtime może być niespójna\n" +#: .././io/open.c:719 +#, c-format +msgid "statfs.f_ffree = %lld\n" +msgstr "statfs.f_ffree = %lld\n" -#: .././repair/phase6.c:3753 -msgid " - traversing filesystem ...\n" -msgstr " - przechodzenie systemu plików...\n" +#: .././io/open.c:726 +#, c-format +msgid "geom.bsize = %u\n" +msgstr "geom.bsize = %u\n" -#: .././repair/phase6.c:3776 -msgid " - traversal finished ...\n" -msgstr " - przechodzenie zakończone...\n" +#: .././io/open.c:727 +#, c-format +msgid "geom.agcount = %u\n" +msgstr "geom.agcount = %u\n" -#: .././repair/phase6.c:3777 +#: .././io/open.c:728 #, c-format -msgid " - moving disconnected inodes to %s ...\n" -msgstr " - przenoszenie odłączonych i-węzłów do %s...\n" +msgid "geom.agblocks = %u\n" +msgstr "geom.agblocks = %u\n" -#: .././repair/progress.c:16 -msgid "inodes" -msgstr "i-węzłów" +#: .././io/open.c:729 +#, c-format +msgid "geom.datablocks = %llu\n" +msgstr "geom.datablocks = %llu\n" -#: .././repair/progress.c:18 .././db/freesp.c:406 -msgid "blocks" -msgstr "bloków" +#: .././io/open.c:731 +#, c-format +msgid "geom.rtblocks = %llu\n" +msgstr "geom.rtblocks = %llu\n" -#: .././repair/progress.c:20 -msgid "directories" -msgstr "katalogów" +#: .././io/open.c:733 +#, c-format +msgid "geom.rtextents = %llu\n" +msgstr "geom.rtextents = %llu\n" -#: .././repair/progress.c:22 -msgid "allocation groups" -msgstr "grup alokacji" +#: .././io/open.c:735 +#, c-format +msgid "geom.rtextsize = %u\n" +msgstr "geom.rtextsize = %u\n" -#: .././repair/progress.c:24 -msgid "AGI unlinked buckets" -msgstr "odłączonych kubełków AGI" +#: .././io/open.c:736 +#, c-format +msgid "geom.sunit = %u\n" +msgstr "geom.sunit = %u\n" -#: .././repair/progress.c:26 .././db/freesp.c:406 -msgid "extents" -msgstr "ekstentów" +#: .././io/open.c:737 +#, c-format +msgid "geom.swidth = %u\n" +msgstr "geom.swidth = %u\n" -#: .././repair/progress.c:28 -msgid "realtime extents" -msgstr "ekstentów realtime" +#: .././io/open.c:742 +#, c-format +msgid "counts.freedata = %llu\n" +msgstr "counts.freedata = %llu\n" -#: .././repair/progress.c:30 -msgid "unlinked lists" -msgstr "odłączonych list" +#: .././io/open.c:744 +#, c-format +msgid "counts.freertx = %llu\n" +msgstr "counts.freertx = %llu\n" -#: .././repair/progress.c:37 +#: .././io/open.c:746 #, c-format -msgid " - %02d:%02d:%02d: %s - %llu of %llu %s done\n" -msgstr " - %02d:%02d:%02d: %s - sprawdzono %llu z %llu %s\n" +msgid "counts.freeino = %llu\n" +msgstr "counts.freeino = %llu\n" -#: .././repair/progress.c:39 +#: .././io/open.c:748 #, c-format -msgid " - %02d:%02d:%02d: %s - %llu %s done\n" -msgstr " - %02d:%02d:%02d: %s - sprawdzono %llu %s\n" +msgid "counts.allocino = %llu\n" +msgstr "counts.allocino = %llu\n" -#: .././repair/progress.c:51 -msgid "scanning filesystem freespace" -msgstr "przeszukiwanie wolnego miejsca w systemie plików" +#: .././io/open.c:763 +msgid "[-acdrstxT] [path]" +msgstr "[-acdrstxT] [ścieżka]" -#: .././repair/progress.c:53 -msgid "scanning agi unlinked lists" -msgstr "przeszukiwanie odłączonych list agi" +#: .././io/open.c:764 +msgid "open the file specified by path" +msgstr "otwarcie pliku określonego ścieżką" -#: .././repair/progress.c:55 -msgid "check uncertain AG inodes" -msgstr "sprawdzanie niepewnych i-węzłów AG" +#: .././io/open.c:772 +msgid "[-v]" +msgstr "[-v]" -#: .././repair/progress.c:57 -msgid "process known inodes and inode discovery" -msgstr "przetwarzanie znanych i-węzłów i rozpoznawanie i-węzłów" +#: .././io/open.c:773 +msgid "statistics on the currently open file" +msgstr "statystyki dla aktualnie otwartego pliku" -#: .././repair/progress.c:59 -msgid "process newly discovered inodes" -msgstr "przetwarzanie nowo rozpoznanych i-węzłów" +#: .././io/open.c:781 +msgid "close the current open file" +msgstr "zamknięcie bieżącego otwartego pliku" -#: .././repair/progress.c:61 -msgid "setting up duplicate extent list" -msgstr "tworzenie listy powtórzonych ekstentów" +#: .././io/open.c:787 +msgid "statistics on the filesystem of the currently open file" +msgstr "statystyki dla systemu plików aktualnie otwartego pliku" -#: .././repair/progress.c:63 -msgid "initialize realtime bitmap" -msgstr "inicjowanie bitmapy realtime" +#: .././io/open.c:791 +msgid "[-D | -R] projid" +msgstr "[-D | -R] projid" -#: .././repair/progress.c:65 -msgid "reset realtime bitmaps" -msgstr "ponowne tworzenie bitmapy realtime" +#: .././io/open.c:796 +msgid "change project identifier on the currently open file" +msgstr "zmiana identyfikatora projektu aktualnie otwartego pliku" -#: .././repair/progress.c:67 -msgid "check for inodes claiming duplicate blocks" -msgstr "szukanie i-węzłów odwołujących się do powtórzonych bloków" +#: .././io/open.c:801 +msgid "[-D | -R]" +msgstr "[-D | -R]" -#: .././repair/progress.c:69 -msgid "rebuild AG headers and trees" -msgstr "przebudowywanie nagłówków i drzew AG" +#: .././io/open.c:806 +msgid "list project identifier set on the currently open file" +msgstr "wypisanie identyfikatora projektu aktualnie otwartego pliku" -#: .././repair/progress.c:71 -msgid "traversing filesystem" -msgstr "przechodzenie systemu plików" +#: .././io/open.c:811 +msgid "[-D | -R] [extsize]" +msgstr "[-D | -R] [rozmiar_fragmentu]" -#: .././repair/progress.c:73 -msgid "traversing all unattached subtrees" -msgstr "przechodzenie wszystkich odłączonych poddrzew" +#: .././io/open.c:816 +msgid "get/set preferred extent size (in bytes) for the open file" +msgstr "pobranie/ustawienie preferowanego rozmiaru ekstentu (w bajtach) dla otwartego pliku" -#: .././repair/progress.c:75 -msgid "moving disconnected inodes to lost+found" -msgstr "przenoszenie odłączonych i-węzłów do lost+found" +#: .././io/parent.c:49 +#, c-format +msgid "%s%s" +msgstr "%s%s" -#: .././repair/progress.c:77 -msgid "verify and correct link counts" -msgstr "sprawdzanie i poprawianie liczby dowiązań" +#: .././io/parent.c:54 +#, c-format +msgid "inode-path for inode: %llu is incorrect - path \"%s\" non-existent\n" +msgstr "inode-path dla i-węzła: %llu jest niepoprawna - ścieżka \"%s\" nie istnieje\n" -#: .././repair/progress.c:79 -msgid "verify link counts" -msgstr "sprawdzanie liczby dowiązań" +#: .././io/parent.c:58 +#, c-format +msgid "path \"%s\" does not stat for inode: %llu; err = %s\n" +msgstr "ścieżka \"%s\" nie pozwala na stat dla i-węzła: %llu; błąd = %s\n" -#: .././repair/progress.c:118 -msgid "cannot malloc pointer to done vector\n" -msgstr "nie udało się przydzielić wskaźnika do wektora wykonania\n" +#: .././io/parent.c:67 +#, c-format +msgid "path \"%s\" found\n" +msgstr "ścieżki \"%s\" nie znaleziono\n" -#: .././repair/progress.c:134 -msgid "unable to create progress report thread\n" -msgstr "nie udało się utworzyć wątku raportowania postępu\n" +#: .././io/parent.c:73 +#, c-format +msgid "inode-path for inode: %llu is incorrect - wrong inode#\n" +msgstr "inode-path dla i-węzła: %llu jest niepoprawna - niewłaściwy numer i-węzła\n" -#: .././repair/progress.c:173 -msgid "progress_rpt: cannot malloc progress msg buffer\n" -msgstr "progress_rpt: nie udało się przydzielić bufora komunikatów postępu\n" +#: .././io/parent.c:77 .././io/parent.c:107 +#, c-format +msgid "ino mismatch for path \"%s\" %llu vs %llu\n" +msgstr "niezgodność i-węzła dla ścieżki \"%s\" %llu vs %llu\n" -#: .././repair/progress.c:187 -msgid "progress_rpt: cannot create timer\n" -msgstr "progress_rpt: nie można utworzyć zegara\n" +#: .././io/parent.c:85 +#, c-format +msgid "inode number match: %llu\n" +msgstr "zgodność numeru i-węzła: %llu\n" -#: .././repair/progress.c:190 -msgid "progress_rpt: cannot set timer\n" -msgstr "progress_rpt: nie można ustawić zegara\n" +#: .././io/parent.c:95 +#, c-format +msgid "parent path \"%s\" does not stat: %s\n" +msgstr "ścieżka nadrzędna \"%s\" nie pozwala na stat: %s\n" -#: .././repair/progress.c:214 -msgid "progress_rpt: cannot lock progress mutex\n" -msgstr "progress_rpt: nie można zablokować muteksu\n" +#: .././io/parent.c:103 +#, c-format +msgid "inode-path for inode: %llu is incorrect - wrong parent inode#\n" +msgstr "inode-path dla i-węzła: %llu jest niepoprawna - niewłaściwy numer i-węzła nadrzędnego\n" -#: .././repair/progress.c:251 .././repair/progress.c:354 +#: .././io/parent.c:116 #, c-format -msgid "%s" -msgstr "%s" +msgid "parent ino match for %llu\n" +msgstr "zgodność numeru i-węzła nadrzędnego dla %llu\n" -#: .././repair/progress.c:259 +#: .././io/parent.c:138 #, c-format -msgid "\t- %02d:%02d:%02d: Phase %d: elapsed time %s - processed %d %s per minute\n" -msgstr "\t- %02d:%02d:%02d: Faza %d: miniony czas %s - przetworzono %d %s na minutę\n" +msgid "parentpaths failed for ino %llu: %s\n" +msgstr "parentpaths nie powiodło się dla i-węzła %llu: %s\n" -#: .././repair/progress.c:264 +#: .././io/parent.c:149 #, c-format -msgid "\t- %02d:%02d:%02d: Phase %d: %%% done - estimated remaining time %s\n" -msgstr "\t- %02d:%02d:%02d: Faza %d: %%% zrobione - przewidywany pozostały czas %s\n" +msgid "inode-path for inode: %llu is missing\n" +msgstr "brak inode-path dla i-węzła: %llu\n" -#: .././repair/progress.c:272 -msgid "progress_rpt: error unlock msg mutex\n" -msgstr "progress_rpt: błąd odblokowywania muteksu komunikatów\n" +#: .././io/parent.c:173 +#, c-format +msgid "can't stat mount point \"%s\": %s\n" +msgstr "nie można wykonać stat na punkcie montowania \"%s\": %s\n" -#: .././repair/progress.c:278 -msgid "cannot delete timer\n" -msgstr "nie można usunąć zegara\n" +#: .././io/parent.c:194 +#, c-format +msgid "failed to get bulkstat information for inode %llu\n" +msgstr "nie udało się uzyskać informacji bulkstat dla i-węzła %llu\n" -#: .././repair/progress.c:292 -msgid "set_progress_msg: cannot lock progress mutex\n" -msgstr "set_progress_msg: nie można zablokować mutekstu postępu\n" +#: .././io/parent.c:200 +#, c-format +msgid "failed to get valid bulkstat information for inode %llu\n" +msgstr "nie udało się uzyskać prawidłowych informacji bulkstat dla i-węzła %llu\n" -#: .././repair/progress.c:302 -msgid "set_progress_msg: cannot unlock progress mutex\n" -msgstr "set_progress_msg: nie można odblokować mutekstu postępu\n" +#: .././io/parent.c:212 +#, c-format +msgid "checking inode %llu\n" +msgstr "sprawdzanie i-węzła %llu\n" -#: .././repair/progress.c:322 -msgid "print_final_rpt: cannot lock progress mutex\n" -msgstr "print_final_rpt: nie można zablokować mutekstu postępu\n" +#: .././io/parent.c:227 +#, c-format +msgid "syssgi bulkstat failed: %s\n" +msgstr "syssgi bulkstat nie powiodło się: %s\n" -#: .././repair/progress.c:358 -msgid "print_final_rpt: cannot unlock progress mutex\n" -msgstr "print_final_rpt: nie można odblokować muteksu postępu\n" +#: .././io/parent.c:249 +#, c-format +msgid "unable to open \"%s\" for jdm: %s\n" +msgstr "nie udało się otworzyć \"%s\" dla jdm: %s\n" -#: .././repair/progress.c:407 +#: .././io/parent.c:259 #, c-format -msgid "%02d:%02d:%02d" -msgstr "%02d:%02d:%02d" +msgid "unable to allocate buffers: %s\n" +msgstr "nie udało się przydzielić buforów: %s\n" -#: .././repair/progress.c:429 +#: .././io/parent.c:270 #, c-format -msgid "%d week" -msgstr "%d tygodni" +msgid "num errors: %d\n" +msgstr "liczba błędów: %d\n" -#: .././repair/progress.c:430 .././repair/progress.c:440 -#: .././repair/progress.c:456 .././repair/progress.c:474 -#: .././repair/progress.c:489 -msgid "s" -msgstr " " +#: .././io/parent.c:272 +#, c-format +msgid "succeeded checking %llu inodes\n" +msgstr "udało się sprawdzić %llu i-węzłów\n" -# XXX: ngettext() -#: .././repair/progress.c:439 +#: .././io/parent.c:283 #, c-format -msgid "%d day" -msgstr "%d dni" +msgid "p_ino = %llu\n" +msgstr "p_ino = %llu\n" -#: .././repair/progress.c:446 .././repair/progress.c:463 -#: .././repair/progress.c:481 .././repair/progress.c:491 -msgid ", " -msgstr ", " +#: .././io/parent.c:284 +#, c-format +msgid "p_gen = %u\n" +msgstr "p_gen = %u\n" -#: .././repair/progress.c:455 +#: .././io/parent.c:285 #, c-format -msgid "%d hour" -msgstr "%d godzin" +msgid "p_reclen = %u\n" +msgstr "p_reclen = %u\n" -#: .././repair/progress.c:473 +#: .././io/parent.c:287 #, c-format -msgid "%d minute" -msgstr "%d minut" +msgid "p_name = \"%s%s\"\n" +msgstr "p_name = \"%s%s\"\n" -#: .././repair/progress.c:488 +#: .././io/parent.c:289 #, c-format -msgid "%d second" -msgstr "%d sekund" +msgid "p_name = \"%s\"\n" +msgstr "p_name = \"%s\"\n" -#: .././repair/progress.c:509 +#: .././io/parent.c:311 #, c-format -msgid "" -"\n" -" XFS_REPAIR Summary %s\n" -msgstr "" -"\n" -" Podsumowanie XFS_REPAIR %s\n" +msgid "%s: failed path_to_fshandle \"%s\": %s\n" +msgstr "%s: path_to_fshandle nie powiodło się dla \"%s\": %s\n" -#: .././repair/progress.c:511 -msgid "Phase\t\tStart\t\tEnd\t\tDuration\n" -msgstr "Faza\t\tPoczątek\tKoniec\t\tCzas trwania\n" +#: .././io/parent.c:318 +#, c-format +msgid "%s: path_to_handle failed for \"%s\"\n" +msgstr "%s: path_to_handle nie powiodło się dla \"%s\"\n" -#: .././repair/progress.c:516 .././repair/progress.c:519 +#: .././io/parent.c:325 #, c-format -msgid "Phase %d:\tSkipped\n" -msgstr "Faza %d:\tPominięta\n" +msgid "%s: unable to allocate parent buffer: %s\n" +msgstr "%s: nie udało się przydzielić bufora nadrzędnego: %s\n" -#: .././repair/progress.c:523 +#: .././io/parent.c:346 #, c-format -msgid "Phase %d:\t%02d/%02d %02d:%02d:%02d\t%02d/%02d %02d:%02d:%02d\t%s\n" -msgstr "Faza %d:\t%02d.%02d %02d:%02d:%02d\t%02d.%02d %02d:%02d:%02d\t%s\n" +msgid "%s: %s call failed for \"%s\": %s\n" +msgstr "%s: wywołanie %s nie powiodło się dla \"%s\": %s\n" -#: .././repair/progress.c:529 +#: .././io/parent.c:355 +#, c-format +msgid "%s: inode-path is missing\n" +msgstr "%s: brak inode-path\n" + +#: .././io/parent.c:386 +#, c-format +msgid "file argument, \"%s\", is not in a mounted XFS filesystem\n" +msgstr "argument plikowy \"%s\" nie jest na podmontowanym systemie plików XFS\n" + +#: .././io/parent.c:426 #, c-format msgid "" "\n" -"Total run time: %s\n" +" list the current file's parents and their filenames\n" +"\n" +" -c -- check the current file's file system for parent consistency\n" +" -p -- list the current file's parents and their full paths\n" +" -v -- verbose mode\n" +"\n" msgstr "" "\n" -"Całkowity czas trwania: %s\n" +" wypisanie rodziców bieżącego pliku i ich nazw\n" +"\n" +" -c - sprawdzenie systemu plików pod kątem spójności rodziców pliku\n" +" -p - wypisanie rodziców bieżącego pliku i ich pełnych ścieżek\n" +" -v - tryb szczegółowy\n" +"\n" -#: .././repair/phase2.c:65 -#, c-format -msgid "zero_log: cannot find log head/tail (xlog_find_tail=%d), zeroing it anyway\n" -msgstr "zero_log: nie znaleziono początku/końca logu (xlog_find_tail=%d), wyzerowano go\n" +#: .././io/parent.c:442 +msgid "[-cpv]" +msgstr "[-cpv]" -#: .././repair/phase2.c:71 +#: .././io/parent.c:444 +msgid "print or check parent inodes" +msgstr "wypisanie lub sprawdzenie i-węzłów nadrzędnych" + +#: .././io/pread.c:33 #, c-format -msgid "zero_log: head block % tail block %\n" -msgstr "zero_log: blok początku % blok końca %\n" - -#: .././repair/phase2.c:77 -msgid "" -"ALERT: The filesystem has valuable metadata changes in a log which is being\n" -"destroyed because the -L option was used.\n" -msgstr "" -"UWAGA: system plików zawiera wartościowe zmiany metadanych w logu, który jest\n" -"niszczony, ponieważ użyto opcji -L.\n" - -#: .././repair/phase2.c:81 msgid "" -"ERROR: The filesystem has valuable metadata changes in a log which needs to\n" -"be replayed. Mount the filesystem to replay the log, and unmount it before\n" -"re-running xfs_repair. If you are unable to mount the filesystem, then use\n" -"the -L option to destroy the log and attempt a repair.\n" -"Note that destroying the log may cause corruption -- please attempt a mount\n" -"of the filesystem before doing this.\n" +"\n" +" reads a range of bytes in a specified block size from the given offset\n" +"\n" +" Example:\n" +" 'pread -v 512 20' - dumps 20 bytes read from 512 bytes into the file\n" +"\n" +" Reads a segment of the currently open file, optionally dumping it to the\n" +" standard output stream (with -v option) for subsequent inspection.\n" +" The reads are performed in sequential blocks starting at offset, with the\n" +" blocksize tunable using the -b option (default blocksize is 4096 bytes),\n" +" unless a different pattern is requested.\n" +" -B -- read backwards through the range from offset (backwards N bytes)\n" +" -F -- read forwards through the range of bytes from offset (default)\n" +" -v -- be verbose, dump out buffers (used when reading forwards)\n" +" -R -- read at random offsets in the range of bytes\n" +" -Z N -- zeed the random number generator (used when reading randomly)\n" +" (heh, zorry, the -s/-S arguments were already in use in pwrite)\n" +" -V N -- use vectored IO with N iovecs of blocksize each (preadv)\n" +"\n" +" When in \"random\" mode, the number of read operations will equal the\n" +" number required to do a complete forward/backward scan of the range.\n" +" Note that the offset within the range is chosen at random each time\n" +" (an offset may be read more than once when operating in this mode).\n" +"\n" msgstr "" -"BŁĄD: system plików zawiera wartościowe zmiany metadanych w logu, który\n" -"musi być odtworzony. Należy podmontować system plików, aby odtworzyć log,\n" -"a następnie odmontować go przed ponownym uruchomieniem xfs_repair. Jeśli\n" -"systemu plików nie da się podmontować, można użyć opcji -L, aby zniszczyć\n" -"log i spróbować naprawić system plików.\n" -"Należy zauważyć, że zniszczenie logu może spowodować uszkodzenia danych -\n" -"proszę najpierw spróbować podmontować system plików.\n" - -#: .././repair/phase2.c:123 -msgid "This filesystem has an external log. Specify log device with the -l option.\n" -msgstr "Ten system plików ma zewnętrzny log. Należy podać urządzenie logu przy użyciu opcji -l.\n" +"\n" +" odczytanie przedziału bajtów w podanym rozmiarze bloku od podanego offsetu\n" +"\n" +" Przykład:\n" +" 'pread -v 512 20' - zrzucenie 20 bajtów odczytanych od 512 bajtu w pliku\n" +"\n" +" pread odczytuje segment aktualnie otwartego pliku, opcjonalnie zrzucając\n" +" zawartość na strumień standardowego wyjścia (z opcją -v) dla dalszych badań.\n" +" Odczyty są wykonywane sekwencyjnie blokami począwszy od offsetu z rozmiarem\n" +" bloku ustawianym przy użyciu opcji -b (domyślny rozmiar bloku to 4096 bajtów),\n" +" chyba że zażądano innego schematu.\n" +" -B - odczyt przedziału od tyłu począwszy od offsetu (N bajtów do tyłu)\n" +" -F - odczyt przedziału od przodu począwszy od offsetu (domyślny)\n" +" -v - tryb szczegółowy, zrzucenie bufora (przy odczycie od przodu)\n" +" -R - odczyt losowych offsetów z przedziału bajtów\n" +" -Z N - (\"zeed\") nakarmienie generatora liczb losowych (przy odczycie losowym)\n" +" (nieztety opcje -s/-S pasujące do \"seed\" były już zajęte w pwrite)\n" +" -V N - użycie wektorowego we/wy z N iovec, każdym o rozmiarze blocksize\n" +" (preadv)\n" +"\n" +" W przypadku trybu losowego liczba operacji odczytu będzie równa liczbie\n" +" potrzebnej do pełnego przeskanowania od przodu lub od tyłu całego przedziału.\n" +" Należy zauważyć, że offset w przedziale jest wybierany za każdym razem losowo\n" +" (dowolny offset może być w tym trybie czytany więcej niż raz).\n" +"\n" -#: .././repair/phase2.c:126 +#: .././io/pread.c:398 .././io/pwrite.c:269 #, c-format -msgid "Phase 2 - using external log on %s\n" -msgstr "Faza 2 - użycie zewnętrznego logu na %s\n" +msgid "non-numeric bsize -- %s\n" +msgstr "nieliczbowy rozmiar bloku - %s\n" -#: .././repair/phase2.c:128 -msgid "Phase 2 - using internal log\n" -msgstr "Faza 2 - użycie wewnętrznego logu\n" +#: .././io/pread.c:428 .././io/pwrite.c:316 +#, c-format +msgid "non-numeric vector count == %s\n" +msgstr "nieliczbowa liczba wektorów - %s\n" -#: .././repair/phase2.c:132 -msgid " - zero log...\n" -msgstr " - zerowanie logu...\n" +#: .././io/pread.c:497 +#, c-format +msgid "read %lld/%lld bytes at offset %lld\n" +msgstr "odczytano %lld/%lld bajtów od offsetu %lld\n" -#: .././repair/phase2.c:136 -msgid " - scan filesystem freespace and inode maps...\n" -msgstr " - przeszukiwanie wolnego miejsca i map i-węzłów w systemie plików...\n" +#: .././io/pread.c:499 .././io/pwrite.c:396 .././io/sendfile.c:163 +#, c-format +msgid "%s, %d ops; %s (%s/sec and %.4f ops/sec)\n" +msgstr "%s, %d operacji; %s (%s/sek i %.4f operacji/sek)\n" -#: .././repair/phase2.c:152 -msgid "root inode chunk not found\n" -msgstr "nie znaleziono danych głównego i-węzła\n" +#: .././io/pread.c:518 +msgid "[-b bs] [-v] [-i N] [-FBR [-Z N]] off len" +msgstr "[-b rozm_bloku] [-v] [-i N] [-FBR [-Z N]] offset długość" -#: .././repair/phase2.c:171 -msgid " - found root inode chunk\n" -msgstr " - znaleziono dane głównego i-węzła\n" +#: .././io/pread.c:519 +msgid "reads a number of bytes at a specified offset" +msgstr "odczyt podanej liczby bajtów od podanego offsetu" -#: .././repair/phase2.c:177 -msgid "root inode marked free, " -msgstr "główny i-węzeł oznaczony jako wolny, " +#: .././io/prealloc.c:273 .././io/prealloc.c:281 .././io/prealloc.c:289 +#: .././io/prealloc.c:297 .././io/prealloc.c:307 .././io/prealloc.c:333 +#: .././io/prealloc.c:343 +msgid "off len" +msgstr "offset długość" -#: .././repair/phase2.c:186 -msgid "realtime bitmap inode marked free, " -msgstr "i-węzeł bitmapy realtime oznaczony jako wolny, " +#: .././io/prealloc.c:274 +msgid "allocates zeroed space for part of a file" +msgstr "przydzielenie wyzerowanej przestrzeni dla części pliku" -#: .././repair/phase2.c:195 -msgid "realtime summary inode marked free, " -msgstr "i-węzeł opisu realtime oznaczony jako wolny, " +#: .././io/prealloc.c:282 +msgid "frees space associated with part of a file" +msgstr "zwolnienie miejsca związanego z częścią pliku" -#: .././repair/rt.c:47 -msgid "couldn't allocate memory for incore realtime bitmap.\n" -msgstr "nie udało się przydzielić pamięci dla bitmapy realtime.\n" +#: .././io/prealloc.c:291 +msgid "reserves space associated with part of a file" +msgstr "zarezerwowanie miejsca związanego z częścią pliku" -#: .././repair/rt.c:51 -msgid "couldn't allocate memory for incore realtime summary info.\n" -msgstr "nie udało się przydzielić pamięci dla opisu realtime.\n" +#: .././io/prealloc.c:300 +msgid "frees reserved space associated with part of a file" +msgstr "zwolnienie zarezerwowanego miejsca związanego z częścią pliku" -#: .././repair/rt.c:151 .././db/check.c:1568 -#, c-format -msgid "rt summary mismatch, size %d block %llu, file: %d, computed: %d\n" -msgstr "opis rt nie zgadza się, rozmiar %d bloku %llu, plik: %d, obliczono: %d\n" +#: .././io/prealloc.c:309 +msgid "Converts the given range of a file to allocated zeros" +msgstr "Zamiana podanego przedziału pliku na przydzielone zera" -#: .././repair/rt.c:203 -#, c-format -msgid "can't find block %d for rtbitmap inode\n" -msgstr "nie można odnaleźć bloku %d dla i-węzła bitmapy realtime\n" +#: .././io/prealloc.c:323 +msgid "[-c] [-k] [-p] off len" +msgstr "[-c] [-k] [-p] offset długość" -#: .././repair/rt.c:211 -#, c-format -msgid "can't read block %d for rtbitmap inode\n" -msgstr "nie można odczytać bloku %d dla i-węzła bitmapy realtime\n" +#: .././io/prealloc.c:325 +msgid "allocates space associated with part of a file via fallocate" +msgstr "przydzielenie miejsca powiązanego z częścią pliku przez fallocate" -#: .././repair/rt.c:265 -#, c-format -msgid "block %d for rtsummary inode is missing\n" -msgstr "brak bloku %d dla i-węzła opisu realtime\n" +#: .././io/prealloc.c:335 +msgid "de-allocates space assocated with part of a file via fallocate" +msgstr "zwolnienie miejsca powiązanego z częścią pliku przez fallocate" -#: .././repair/rt.c:273 -#, c-format -msgid "can't read block %d for rtsummary inode\n" -msgstr "nie można odczytać bloku %d dla i-węzła opisu realtime\n" +#: .././io/prealloc.c:345 +msgid "de-allocates space and eliminates the hole by shifting extents" +msgstr "zwolnienie miejsca i usunięcie dziury poprzez przesunięcie ekstentów" + +#: .././io/prealloc.c:353 +msgid "[-k] off len" +msgstr "[-k] offset długość" + +#: .././io/prealloc.c:355 +msgid "zeroes space and eliminates holes by preallocating" +msgstr "wyzerowanie miejsca i usunięcie dziur poprzez prealokację" -#: .././quota/free.c:29 +#: .././io/pwrite.c:32 #, c-format msgid "" "\n" -" reports the number of free disk blocks and inodes\n" +" writes a range of bytes (in block size increments) from the given offset\n" "\n" -" This command reports the number of total, used, and available disk blocks.\n" -" It can optionally report the same set of numbers for inodes and realtime\n" -" disk blocks, and will report on all known XFS filesystem mount points and\n" -" project quota paths by default (see 'print' command for a list).\n" -" -b -- report the block count values\n" -" -i -- report the inode count values\n" -" -r -- report the realtime block count values\n" -" -h -- report in a human-readable format\n" -" -N -- suppress the header from the output\n" +" Example:\n" +" 'pwrite 512 20' - writes 20 bytes at 512 bytes into the open file\n" +"\n" +" Writes into a segment of the currently open file, using either a buffer\n" +" filled with a set pattern (0xcdcdcdcd) or data read from an input file.\n" +" The writes are performed in sequential blocks starting at offset, with the\n" +" blocksize tunable using the -b option (default blocksize is 4096 bytes),\n" +" unless a different write pattern is requested.\n" +" -S -- use an alternate seed number for filling the write buffer\n" +" -i -- input file, source of data to write (used when writing forward)\n" +" -d -- open the input file for direct IO\n" +" -s -- skip a number of bytes at the start of the input file\n" +" -w -- call fdatasync(2) at the end (included in timing results)\n" +" -W -- call fsync(2) at the end (included in timing results)\n" +" -B -- write backwards through the range from offset (backwards N bytes)\n" +" -F -- write forwards through the range of bytes from offset (default)\n" +" -R -- write at random offsets in the specified range of bytes\n" +" -Z N -- zeed the random number generator (used when writing randomly)\n" +" (heh, zorry, the -s/-S arguments were already in use in pwrite)\n" +" -V N -- use vectored IO with N iovecs of blocksize each (pwritev)\n" "\n" msgstr "" "\n" -" informacje o liczbie wolnych bloków i i-węzłów dysku\n" +" zapisanie przedziału bajtów w podanym rozmiarze bloku od podanego offsetu\n" "\n" -" To polecenie informuje o liczbie wszystkich, używanych i dostępnych bloków\n" -" dysku. Opcjonalnie informuje o tym samym zestawie liczb dla i-węzłów i bloków\n" -" realtime oraz domyślnie zgłasza wszystkie znane punkty montowania systemu\n" -" plików XFS i ścieżki quot projektów (patrz lista w poleceniu 'print').\n" -" -b - informacje o liczbach bloków\n" -" -i - informacje o liczbach i-węzłów\n" -" -r - informacje o liczbach bloków realtime\n" -" -h - informacje w postaci czytelnej dla człowieka\n" -" -N - pominięcie nagłówka z wyjścia\n" +" Przykład:\n" +" 'pwrite 512 20' - zapisanie 20 bajtów odczytanych od 512 bajtu w pliku\n" +"\n" +" pwrite zapisuje segment aktualnie otwartego pliku, używając bufora wypełnionego\n" +" ustawionym wzorcem (0xcdcdcdcd) lub danymi odczytanymi z pliku wejściowego.\n" +" Zapisy są wykonywane sekwencyjnie blokami począwszy od offsetu z rozmiarem\n" +" bloku ustawianym przy użyciu opcji -b (domyślny rozmiar bloku to 4096 bajtów),\n" +" chyba że zażądano innego schematu.\n" +" -S - użycie innej liczby do wypełnienia bufora zapisu\n" +" -i - plik wejściowy, źródło danych do zapisania (przy pisaniu od przodu)\n" +" -d - otwarcie pliku wejściowego dla bezpośredniego we/wy\n" +" -s - pominięcie podanej liczby bajtów od początku pliku wejściowego\n" +" -w - wywołanie fdatasync(2) na końcu (wliczane w wyniki czasowe)\n" +" -W - wywołanie fsync(2) na końcu (wliczane w wyniki czasowe)\n" +" -B - zapis przedziału od tyłu począwszy od offsetu (N bajtów do tyłu)\n" +" -F - zapis przedziału od przodu począwszy od offsetu (domyślny)\n" +" -R - zapis losowych offsetów z przedziału bajtów\n" +" -Z N - (\"zeed\") nakarmienie generatora liczb losowych (przy zapisie losowym)\n" +" (niestety opcje -s/-S pasujące do \"seed\" były już zajęte w pwrite)\n" +" -V N - użycie wektorowego we/wy z N iovec, każdym o rozmiarze blocksize\n" +" (pwritev)\n" "\n" -#: .././quota/free.c:154 +#: .././io/pwrite.c:296 #, c-format -msgid "%s: project quota flag not set on %s\n" -msgstr "%s: flaga quot projektu nie ustawiona dla %s\n" +msgid "non-numeric skip -- %s\n" +msgstr "nieliczbowy liczba bajtów do pominięcia - %s\n" -#: .././quota/free.c:163 +#: .././io/pwrite.c:394 #, c-format -msgid "%s: project ID %u (%s) doesn't match ID %u (%s)\n" -msgstr "%s: ID projektu %u (%s) nie zgadza się z ID %u (%s)\n" +msgid "wrote %lld/%lld bytes at offset %lld\n" +msgstr "zapisano %lld/%lld bajtów od offsetu %lld\n" -#: .././quota/free.c:230 -#, c-format -msgid "Filesystem " -msgstr "System plików " +#: .././io/pwrite.c:419 +msgid "[-i infile [-d] [-s skip]] [-b bs] [-S seed] [-wW] [-FBR [-Z N]] [-V N] off len" +msgstr "[-i plik_wej [-d] [-s do_pominięcia]] [-b rozm_bloku] [-S zarodek] [-wW] [-FBR [-Z N]] [-V N] offset długość" -#: .././quota/free.c:230 -#, c-format -msgid "Filesystem " -msgstr "System plików " +#: .././io/pwrite.c:421 +msgid "writes a number of bytes at a specified offset" +msgstr "zapis podanej liczby bajtów od podanego offsetu" -#: .././quota/free.c:233 +#: .././io/readdir.c:182 #, c-format -msgid " Size Used Avail Use%%" -msgstr " Rozmiar Użyto Dost. %%uż." +msgid "read %llu bytes from offset %lld\n" +msgstr "odczytano %llu bajtów z offsetu %lld\n" -#: .././quota/free.c:234 +#: .././io/readdir.c:183 #, c-format -msgid " 1K-blocks Used Available Use%%" -msgstr " Bloki 1K Użyto Dostępnych %%uż." +msgid "%s, %d ops, %s (%s/sec and %.4f ops/sec)\n" +msgstr "%s, %d operacji; %s (%s/sek i %.4f operacji/sek)\n" -#: .././quota/free.c:237 +#: .././io/readdir.c:196 +msgid "[-v][-o offset][-l length]" +msgstr "[-v][-o offset][-l długość]" + +#: .././io/readdir.c:197 +msgid "read directory entries" +msgstr "odczyt wpisów katalogu" + +#: .././io/resblks.c:39 #, c-format -msgid " Inodes Used Free Use%%" -msgstr " I-węzły Użyto Wolne %%uż." +msgid "non-numeric argument -- %s\n" +msgstr "nieliczbowy argument - %s\n" -#: .././quota/free.c:238 +#: .././io/resblks.c:51 #, c-format -msgid " Inodes IUsed IFree IUse%%" -msgstr " I-węzły UżytoI WolneI %%użI" +msgid "reserved blocks = %llu\n" +msgstr "zarezerwowane bloki = %llu\n" -#: .././quota/free.c:239 +#: .././io/resblks.c:53 #, c-format -msgid " Pathname\n" -msgstr " Ścieżka\n" +msgid "available reserved blocks = %llu\n" +msgstr "dostępne zarezerwowane bloki = %llu\n" -#: .././quota/free.c:371 -msgid "[-bir] [-hn] [-f file]" -msgstr "[-bir] [hn] [-f plik]" +#: .././io/resblks.c:66 +msgid "[blocks]" +msgstr "[bloki]" -#: .././quota/free.c:372 -msgid "show free and used counts for blocks and inodes" -msgstr "pokazanie liczby wolnych i zajętych bloków i i-węzłów" - -#: .././quota/init.c:48 -#, c-format -msgid "Usage: %s [-p prog] [-c cmd]... [-d project]... [path]\n" -msgstr "Składnia: %s [-p program] [-c polecenie]... [-d projekt]... [ścieżka]\n" - -#: .././quota/path.c:39 -#, c-format -msgid "%sFilesystem Pathname\n" -msgstr "%sSystem plików Ścieżka\n" - -#: .././quota/path.c:40 -msgid " " -msgstr " " - -#: .././quota/path.c:43 -#, c-format -msgid "%c%03d%c " -msgstr "%c%03d%c " - -#: .././quota/path.c:45 -#, c-format -msgid "%-19s %s" -msgstr "%-19s %s" - -#: .././quota/path.c:48 -#, c-format -msgid " (project %u" -msgstr " (projekt %u" - -#: .././quota/path.c:50 -#, c-format -msgid ", %s" -msgstr ", %s" - -#: .././quota/path.c:103 -#, c-format -msgid "No paths are available\n" -msgstr "Brak ścieżek\n" - -#: .././quota/path.c:112 .././io/sendfile.c:103 .././io/file.c:81 -#, c-format -msgid "value %d is out of range (0-%d)\n" -msgstr "wartość %d jest spoza zakresu (0-%d)\n" - -#: .././quota/path.c:126 .././io/file.c:94 -msgid "[N]" -msgstr "[N]" - -#: .././quota/path.c:131 -msgid "set current path, or show the list of paths" -msgstr "ustawienie bieżącej ścieżki lub pokazanie listy ścieżek" - -#: .././quota/path.c:139 -msgid "list known mount points and projects" -msgstr "wypisanie znanych punktów montowań i projektów" +#: .././io/resblks.c:68 +msgid "get and/or set count of reserved filesystem blocks" +msgstr "pobranie i/lub ustawienie liczby zarezerwowanych bloków w systemie plików" -#: .././quota/project.c:45 +#: .././io/seek.c:33 #, c-format msgid "" "\n" -" list projects or setup a project tree for tree quota management\n" +" returns the next hole and/or data offset at or after the requested offset\n" "\n" " Example:\n" -" 'project -c logfiles'\n" -" (match project 'logfiles' to a directory, and setup the directory tree)\n" +" 'seek -d 512'\t\t- offset of data at or following offset 512\n" +" 'seek -a -r 0'\t- offsets of all data and hole in entire file\n" "\n" -" Without arguments, report all projects found in the /etc/projects file.\n" -" The project quota mechanism in XFS can be used to implement a form of\n" -" directory tree quota, where a specified directory and all of the files\n" -" and subdirectories below it (i.e. a tree) can be restricted to using a\n" -" subset of the available space in the filesystem.\n" +" Returns the offset of the next data and/or hole. There is an implied hole\n" +" at the end of file. If the specified offset is past end of file, or there\n" +" is no data past the specified offset, EOF is returned.\n" +" -a\t-- return the next data and hole starting at the specified offset.\n" +" -d\t-- return the next data starting at the specified offset.\n" +" -h\t-- return the next hole starting at the specified offset.\n" +" -r\t-- return all remaining type(s) starting at the specified offset.\n" +" -s\t-- also print the starting offset.\n" "\n" -" A managed tree must be setup initially using the -c option with a project.\n" -" The specified project name or identifier is matched to one or more trees\n" -" defined in /etc/projects, and these trees are then recursively descended\n" -" to mark the affected inodes as being part of that tree - which sets inode\n" -" flags and the project identifier on every file.\n" -" Once this has been done, new files created in the tree will automatically\n" -" be accounted to the tree based on their project identifier. An attempt to\n" -" create a hard link to a file in the tree will only succeed if the project\n" -" identifier matches the project identifier for the tree. The xfs_io utility\n" -" can be used to set the project ID for an arbitrary file, but this can only\n" -" be done by a privileged user.\n" +msgstr "" "\n" -" A previously setup tree can be cleared from project quota control through\n" -" use of the -C option, which will recursively descend the tree, clearing\n" -" the affected inodes from project quota control.\n" +" zwrócenie offsetu następnej dziury i/lub danych pod lub za żądanym offsetem\n" "\n" -" The -c option can be used to check whether a tree is setup, it reports\n" -" nothing if the tree is correct, otherwise it reports the paths of inodes\n" -" which do not have the project ID of the rest of the tree, or if the inode\n" -" flag is not set.\n" +" Przykłady:\n" +" 'seek -d 512' - offset danych pod lub za offsetem 512\n" +" 'seek -a -r 0' - offsety wszystkich danych i dziur w całym pliku\n" "\n" -" The -p option can be used to manually specify project path without\n" -" need to create /etc/projects file. This option can be used multiple times\n" -" to specify multiple paths. When using this option only one projid/name can\n" -" be specified at command line. Note that /etc/projects is also used if exists.\n" +" seek zwraca offset następnych danych i/lub dziury. Istnieje domyślna dziura\n" +" na końcu pliku. Jeśli podany offset jest za końcem pliku lub nie ma danych\n" +" za podanym offsetem, zwracany jest EOF.\n" +" -a\t- następne dane i dziura od podanego offsetu\n" +" -d\t- następne dane począwszy od podanego offsetu\n" +" -h\t- następna dziura począwszy od podanego offsetu\n" +" -r\t- wszystkie pozostałe typy fragmentów od podanego offsetu\n" +" -s\t- wypisane także offsetu początkowego\n" +"\n" + +#: .././io/seek.c:219 +msgid "-a | -d | -h [-r] off" +msgstr "-a | -d | -h [-r] offset" + +#: .././io/seek.c:220 +msgid "locate the next data and/or hole" +msgstr "odnalezienie następnych danych i/lub dziury" + +#: .././io/sendfile.c:32 +#, c-format +msgid "" "\n" -" The -d option allows to descend at most levels of directories\n" -" below the command line arguments. -d 0 means only apply the actions\n" -" to the top level of the projects. -d -1 means no recursion limit (default).\n" +" transfer a range of bytes from the given offset between files\n" "\n" -" The /etc/projid and /etc/projects file formats are simple, and described\n" -" on the xfs_quota man page.\n" +" Example:\n" +" 'send -f 2 512 20' - writes 20 bytes at 512 bytes into the open file\n" +"\n" +" Copies data between one file descriptor and another. Because this copying\n" +" is done within the kernel, sendfile does not need to transfer data to and\n" +" from user space.\n" +" -f -- specifies an input file from which to source data to write\n" +" -i -- specifies an input file name from which to source data to write.\n" +" An offset and length in the source file can be optionally specified.\n" "\n" msgstr "" "\n" -" wypisanie projektów lub ustanowienie drzewa projektu do zarządzania limitami\n" +" przesłanie między plikami przedziału bajtów od podanego offsetu\n" "\n" " Przykład:\n" -" 'project -c logfiles'\n" -" (dopasowanie projektu 'logfiles' do katalogu i ustanowienie drzewa katalogów)\n" +" 'send -f 2 512 20' - zapisanie 20 bajtów od 512 bajtu do otwartego pliku\n" "\n" -" Bez argumentów project wypisuje wszystkie projekty znalezione w pliku\n" -" /etc/projects. Mechanizm quota dla projektów w XFS-ie może być używany do\n" -" zaimplementowania formy limitów dla drzewa katalogów, gdzie podany katalog\n" -" i wszystkie pliki i podkatalogi poniżej niego (czyli drzewo) mogą być\n" -" ograniczone do używania podzbioru miejsca dostępnego w systemie plików.\n" +" sendfile kopiuje dane między jednym deskryptorem pliku a innym. Ponieważ to\n" +" kopiowanie jest wykonywane przez jądro, sendfile nie potrzebuje przesyłać\n" +" danych do i z przestrzeni użytkownika.\n" +" -f - podanie plików wejściowego z którego dane mają być czytane\n" +" -i - podanie nazwy pliku wejściowego z którego dane mają być czytane\n" +" Opcjonalnie można podać offset i długość danych w pliku źródłowym.\n" "\n" -" Zarządzane drzewo musi być ustanowione początkowo przy użyciu opcji project -c.\n" -" Podana nazwa lub identyfikator projektu jest dopasowywany do jednego lub\n" -" większej liczby drzew zdefiniowanych w /etc/projects, a następnie te drzewa są\n" -" rekurencyjnie przechodzone w celu oznaczenia i-węzłów jako będących częścią\n" -" tego drzewa - co ustawia flagi i-węzłów i identyfikator projektu dla każdego\n" -" pliku.\n" -" Po zrobieniu tego nowe pliki tworzone w drzewie będą automatycznie liczone jako\n" -" część drzewa o ich identyfikatorze projektu. Próba utworzenia dowiązania\n" -" zwykłego do pliku w drzewie powiedzie się tylko jeśli identyfikator projektu\n" -" pasuje do identyfikatora projektu drzewa. Można użyć narzędzia xfs_io do\n" -" ustawienia ID projektu dla dowolnego pliku, ale może tego dokonać tylko\n" -" uprzywilejowany użytkownik.\n" + +#: .././io/sendfile.c:161 +#, c-format +msgid "sent %lld/%lld bytes from offset %lld\n" +msgstr "przesłano %lld/%lld bajtów od offsetu %lld\n" + +#: .././io/sendfile.c:186 +msgid "-i infile | -f N [off len]" +msgstr "-i plik_wej | -f N [offset długość]" + +#: .././io/sendfile.c:188 +msgid "Transfer data directly between file descriptors" +msgstr "Przesłanie danych bezpośrednio między deskryptorami plików" + +#: .././io/shutdown.c:59 +msgid "[-f]" +msgstr "[-f]" + +#: .././io/shutdown.c:61 +msgid "shuts down the filesystem where the current file resides" +msgstr "wyłączenie systemu plików na którym znajduje się bieżący plik" + +#: .././io/sync_file_range.c:31 +#, c-format +msgid "" "\n" -" Poprzednio ustanowione drzewa można usunąć z kontroli limitów projektu poprzez\n" -" użycie opcji -C, która rekurencyjnie przejdzie drzewo, usuwając i-węzły spod\n" -" kontroli limitów projektu.\n" +" Trigger specific writeback commands on a range of the current file\n" "\n" -" Opcji -c można użyć do sprawdzenia czy drzewo zostało ustanowione - nie\n" -" informuje o niczym jeśli drzewo jest poprawne, a w przeciwnym wypadku zgłasza\n" -" ścieżki i-węzłów nie mające ID projektu takiego jak reszta drzewa lub nie\n" -" mające ustawionej flagi.\n" +" With no options, the SYNC_FILE_RANGE_WRITE is implied.\n" +" -a -- wait for IO to finish after writing (SYNC_FILE_RANGE_WAIT_AFTER).\n" +" -b -- wait for IO to finish before writing (SYNC_FILE_RANGE_WAIT_BEFORE).\n" +" -w -- write dirty data in range (SYNC_FILE_RANGE_WRITE).\n" "\n" -" Opcja -p <ścieżka> umożliwia podanie ścieżki projektu w linii poleceń\n" -" bez potrzeby tworzenia pliku /etc/projects. Ta opcja może być używana\n" -" wielokrotnie w celu przekazanie wielu ścieżek projektu. Tylko jeden\n" -" identyfikator projektu może być podawy w linii poleceń w momencie\n" -" używania opcji -p. Jeśli plik /etc/projects istnieje to także jest używany\n" -" oprócz ścieżek w linii poleceń.\n" +msgstr "" "\n" -" Opcja -d pozwala na ograniczanie zagłębiania się w podkatalogach\n" -" projektu do granicy . -d 0 oznacza najwyższy poziom. -d 1 oznacza\n" -" brak limitu zagłębiania (domyślny).\n" +" Wyzwolenie określonych poleceń zapisu w tle na pewnym zakresie bieżącego pliku\n" "\n" -" Format plików /etc/projid i /etc/projects jest prosty i opisany na stronie\n" -" manuala xfs_quota.\n" +" Bez opcji przyjmowana jest operacja SYNC_FILE_RANGE_WRITE.\n" +" -a - oczekiwanie na zakończenie we/wy po zapisie (SYNC_FILE_RANGE_WAIT_AFTER).\n" +" -b - oczekiwanie na zakończenie we/wy przedtem (SYNC_FILE_RANGE_WAIT_BEFORE).\n" +" -w - zapis zmodyfikowanych danych z zakresu (SYNC_FILE_RANGE_WRITE).\n" "\n" -#: .././quota/project.c:108 .././quota/project.c:153 .././quota/project.c:200 -#, c-format -msgid "%s: cannot stat file %s\n" -msgstr "%s: nie można wykonać stat na pliku %s\n" +#: .././io/sync_file_range.c:102 +msgid "[-abw] off len" +msgstr "[-abw] offset długość" -#: .././quota/project.c:112 .././quota/project.c:157 .././quota/project.c:204 +#: .././io/sync_file_range.c:103 +msgid "Control writeback on a range of a file" +msgstr "Sterowanie zapisem w tle dla zakresu pliku" + +#: .././io/truncate.c:38 #, c-format -msgid "%s: skipping special file %s\n" -msgstr "%s: pominięto plik specjalny %s\n" +msgid "non-numeric truncate argument -- %s\n" +msgstr "nieliczbowy argument truncate - %s\n" -#: .././quota/project.c:118 .././quota/project.c:163 .././quota/project.c:210 -#: .././mkfs/proto.c:284 .././libxfs/init.c:110 .././io/attr.c:171 -#: .././io/attr.c:247 .././io/open.c:397 .././io/open.c:469 .././io/open.c:593 -#: .././io/open.c:615 +#: .././io/truncate.c:58 +msgid "off" +msgstr "offset" + +#: .././io/truncate.c:60 +msgid "truncates the current file at the given offset" +msgstr "ucięcie bieżącego pliku na podanym offsecie" + +#: .././libdisk/dm.c:57 #, c-format -msgid "%s: cannot open %s: %s\n" -msgstr "%s: nie można otworzyć %s: %s\n" +msgid "Warning - device mapper device, but no dmsetup(8) found\n" +msgstr "Uwaga - urządzenie device mappera, ale nie znaleziono dmsetup(8)\n" -#: .././quota/project.c:122 .././quota/project.c:168 .././quota/project.c:215 -#: .././io/attr.c:174 .././io/attr.c:221 .././io/attr.c:250 .././io/attr.c:321 +#: .././libdisk/dm.c:73 .././libdisk/lvm.c:70 #, c-format -msgid "%s: cannot get flags on %s: %s\n" -msgstr "%s: nie można pobrać flag %s: %s\n" +msgid "Could not open pipe\n" +msgstr "Nie udało się otworzyć potoku\n" -#: .././quota/project.c:126 +#: .././libdisk/dm.c:88 .././libdisk/lvm.c:85 #, c-format -msgid "%s - project identifier is not set (inode=%u, tree=%u)\n" -msgstr "%s - identyfikator projektu nie ustawiony (i-węzeł=%u, drzewo=%u)\n" +msgid "Failed to execute %s\n" +msgstr "Nie udało się wywołać %s\n" -#: .././quota/project.c:130 +#: .././libdisk/dm.c:92 #, c-format -msgid "%s - project inheritance flag is not set\n" -msgstr "%s - flaga dziedziczenia projektu nie ustawiona\n" +msgid "Failed forking dmsetup process\n" +msgstr "Nie udało się odgałęzić procesu dmsetup\n" -#: .././quota/project.c:178 +#: .././libdisk/drivers.c:35 #, c-format -msgid "%s: cannot clear project on %s: %s\n" -msgstr "%s: nie można usunąć projektu z %s: %s\n" +msgid "Cannot stat %s: %s\n" +msgstr "Nie można wykonać stat na %s: %s\n" -#: .././quota/project.c:225 +#: .././libdisk/lvm.c:60 #, c-format -msgid "%s: cannot set project on %s: %s\n" -msgstr "%s: nie można ustawić projektu na %s: %s\n" +msgid "Warning - LVM device, but no lvdisplay(8) found\n" +msgstr "Uwaga - urządzenie LVM, ale nie znaleziono lvdisplay(8)\n" -#: .././quota/project.c:240 +#: .././libdisk/lvm.c:89 #, c-format -msgid "Checking project %s (path %s)...\n" -msgstr "Sprawdzanie projektu %s (ścieżka %s)...\n" +msgid "Failed forking lvdisplay process\n" +msgstr "Nie udało się odgałęzić procesu lvdisplay\n" -#: .././quota/project.c:244 +#: .././libdisk/md.c:61 #, c-format -msgid "Setting up project %s (path %s)...\n" -msgstr "Ustanawianie projektu %s (ścieżka %s)...\n" +msgid "Error getting MD array device from %s\n" +msgstr "Błąd podczas pobierania urządzenia macierzy MD z %s\n" -#: .././quota/project.c:248 +#: .././libdisk/md.c:68 #, c-format -msgid "Clearing project %s (path %s)...\n" -msgstr "Usuwanie projektu %s (ścieżka %s)...\n" +msgid "Couldn't malloc device string\n" +msgstr "Nie można przydzielić łańcucha nazwy urządzenia\n" -#: .././quota/project.c:271 +#: .././libdisk/md.c:84 #, c-format -msgid "Processed %d (%s and cmdline) paths for project %s with recursion depth %s (%d).\n" -msgstr "" -"Przetworzono %d (z %s oraz z linii poleceń) ścieżek dla projektu %s\n" -"z ograniczeniem %s (%d)\n" +msgid "Error getting MD array info from %s\n" +msgstr "Błąd podczas pobierania informacji o macierzy MD z %s\n" -#: .././quota/project.c:274 -msgid "infinite" -msgstr "nieaktywnym" +#: .././libxcmd/command.c:85 +#, c-format +msgid "bad argument count %d to %s, expected at least %d arguments\n" +msgstr "błędna liczba argumentów %d dla %s, oczekiwano co najmniej %d argumentów\n" -#: .././quota/project.c:274 -msgid "limited" -msgstr "aktywnym" +#: .././libxcmd/command.c:89 +#, c-format +msgid "bad argument count %d to %s, expected %d arguments\n" +msgstr "błędna liczba argumentów %d dla %s, oczekiwano %d argumentów\n" -#: .././quota/project.c:319 +#: .././libxcmd/command.c:93 #, c-format -msgid "projects file \"%s\" doesn't exist\n" -msgstr "plik projektów \"%s\" nie istnieje\n" +msgid "bad argument count %d to %s, expected between %d and %d arguments\n" +msgstr "błędna liczba argumentów %d dla %s, oczekiwano od %d do %d argumentów\n" -#: .././quota/project.c:326 +#: .././libxcmd/command.c:155 #, c-format -msgid "%s: only one projid/name can be specified when using -p , %d found.\n" -msgstr "%s: tylko jeden id projektu/nazwa może być podana kiedy opcja -p <ścieżka> jest w użyciu. Znaleziono %d.\n" +msgid "cannot strdup command '%s': %s\n" +msgstr "nie można wykonać strdup na poleceniu '%s': %s\n" -#: .././quota/project.c:336 +#: .././libxcmd/command.c:171 .././libxcmd/command.c:189 #, c-format -msgid "%s - no such project in %s or invalid project number\n" -msgstr "%s - nie ma takiego projektu w %s lub błędny numer projektu\n" +msgid "command \"%s\" not found\n" +msgstr "nie znaleziono polecenia \"%s\"\n" -#: .././quota/project.c:353 -msgid "[-c|-s|-C|-d |-p ] project ..." -msgstr "[-c|-s|-C| -d |-p <ścieżka>] projekt ..." +#: .././libxcmd/paths.c:264 +#, c-format +msgid "%s: unable to extract mount options for \"%s\"\n" +msgstr "%s: nie udało się wydobyć opcji montowania dla \"%s\"\n" -#: .././quota/project.c:356 -msgid "check, setup or clear project quota trees" -msgstr "sprawdzenie, ustanowienie lub usunięcie drzew projektów" +#: .././libxcmd/paths.c:344 +#, c-format +msgid "%s: getmntinfo() failed: %s\n" +msgstr "%s: getmntinfo() nie powiodło się: %s\n" -#: .././quota/quot.c:55 +#: .././libxcmd/paths.c:413 #, c-format -msgid "" -"\n" -" display a summary of filesystem ownership\n" -"\n" -" -a -- summarise for all local XFS filesystem mount points\n" -" -c -- display three columns giving file size in kilobytes, number of files\n" -" of that size, and cumulative total of kilobytes in that size or\n" -" smaller file. The last row is used as an overflow bucket and is the\n" -" total of all files greater than 500 kilobytes.\n" -" -v -- display three columns containing the number of kilobytes not\n" -" accessed in the last 30, 60, and 90 days.\n" -" -g -- display group summary\n" -" -p -- display project summary\n" -" -u -- display user summary\n" -" -b -- display number of blocks used\n" -" -i -- display number of inodes used\n" -" -r -- display number of realtime blocks used\n" -" -n -- skip identifier-to-name translations, just report IDs\n" -" -N -- suppress the initial header\n" -" -f -- send output to a file\n" -" The (optional) user/group/project can be specified either by name or by\n" -" number (i.e. uid/gid/projid).\n" -"\n" -msgstr "" -"\n" -" wyświetlenie podsumowania własności systemu plików\n" -"\n" -" -a - podsumowanie dla wszystkich punktów montowania systemów plików XFS\n" -" -c - wyświetlenie trzech kolumn z rozmiarem plików w kilobajtach, liczbą\n" -" plików tego rozmiaru i sumą kilobajtów w plikach o tym lub mniejszym\n" -" rozmiarze. Ostatni wiersz podsumowuje pliki większe niż 500 kilobajtów.\n" -" -v - wyświetlenie trzech kolumn zawierających liczbę kilobajtów, do których\n" -" nie było odwołań przez ostatnie 30, 60 i 90 dni.\n" -" -g - wyświetlenie podsumowania dla grup\n" -" -p - wyświetlenie podsumowania dla projektów\n" -" -u - wyświetlenie podsumowania dla użytkowników\n" -" -b - wyświetlenie liczby wykorzystanych bloków\n" -" -i - wyświetlenie liczby wykorzystanych i-węzłów\n" -" -r - wyświetlenie liczby wykorzystanych blików realtime\n" -" -n - pominięcie tłumaczenia identyfikatorów na nazwy, wypisywanie ID\n" -" -N - pominięcie początkowego nagłówka\n" -" -f - zapisanie wyjścia do pliku\n" -" (opcjonalny) użytkownik/grupa/projekt może być podany za pomocą nazwy lub\n" -" numeru (tzn. uid/gid/projid).\n" +msgid "%s: cannot setup path for mount %s: %s\n" +msgstr "%s: nie można ustawić ścieżki dla montowania %s: %s\n" -#: .././quota/quot.c:219 +#: .././libxcmd/paths.c:435 #, c-format -msgid "%s (%s) %s:\n" -msgstr "%s (%s) %s:\n" +msgid "%s: cannot find mount point for path `%s': %s\n" +msgstr "%s: nie można znaleźć punktu montowania dla ścieżki `%s': %s\n" -#: .././quota/quot.c:295 +#: .././libxcmd/paths.c:463 #, c-format -msgid "%s (%s):\n" -msgstr "%s (%s):\n" +msgid "%s: cannot setup path for project %s: %s\n" +msgstr "%s: nie można ustawić ścieżki dla projektu %s: %s\n" -#: .././quota/quot.c:300 .././quota/quot.c:304 +#: .././libxcmd/paths.c:504 #, c-format -msgid "%d\t%llu\t%llu\n" -msgstr "%d\t%llu\t%llu\n" +msgid "%s: cannot initialise path table: %s\n" +msgstr "%s: nie można zainicjować tabeli ścieżek: %s\n" -#: .././quota/quot.c:418 -msgid "[-bir] [-gpu] [-acv] [-f file]" -msgstr "[-bir] [-gpu] [-acv] [-f plik]" +#: .././libxcmd/paths.c:524 +#, c-format +msgid "%s: cannot setup path for project dir %s: %s\n" +msgstr "%s: nie można ustawić ścieżki dla katalogu projektu %s: %s\n" -#: .././quota/quot.c:419 -msgid "summarize filesystem ownership" -msgstr "podsumowanie własności systemu plików" +#: .././libxcmd/quit.c:42 +msgid "exit the program" +msgstr "wyjście z programu" -#: .././quota/quota.c:32 +#: .././libxfs/darwin.c:41 #, c-format -msgid "" -"\n" -" display usage and quota information\n" -"\n" -" -g -- display group quota information\n" -" -p -- display project quota information\n" -" -u -- display user quota information\n" -" -b -- display number of blocks used\n" -" -i -- display number of inodes used\n" -" -r -- display number of realtime blocks used\n" -" -h -- report in a human-readable format\n" -" -n -- skip identifier-to-name translations, just report IDs\n" -" -N -- suppress the initial header\n" -" -v -- increase verbosity in reporting (also dumps zero values)\n" -" -f -- send output to a file\n" -" The (optional) user/group/project can be specified either by name or by\n" -" number (i.e. uid/gid/projid).\n" -"\n" -msgstr "" -"\n" -" wyświetlenie informacji o wykorzystaniu miejsca i limitach\n" -"\n" -" -g - wyświetlenie informacji o limitach grup\n" -" -p - wyświetlenie informacji o limitach projektów\n" -" -u - wyświetlenie informacji o limitach użytkowników\n" -" -b - wyświetlenie liczby wykorzystanych bloków\n" -" -i - wyświetlenie liczby wykorzystanych i-węzłów\n" -" -r - wyświetlenie liczby wykorzystanych bloków realtime\n" -" -h - użycie formatu czytelnego dla człowieka\n" -" -n - pominięcie tłumaczenia identyfikatorów na nazwy, wypisywanie ID\n" -" -N - pominięcie początkowego nagłówka\n" -" -v - zwiększenie szczegółowości (wypisywanie także wartości zerowych)\n" -" -f - zapisanie wyjścia do pliku\n" -" (opcjonalny) użytkownik/grupa/projekt może być podany za pomocą nazwy lub\n" -" numeru (tzn. uid/gid/projid).\n" +msgid "%s: error opening the device special file \"%s\": %s\n" +msgstr "%s: błąd podczas otwierania pliku specjalnego urządzenia \"%s\": %s\n" -#: .././quota/quota.c:85 +#: .././libxfs/darwin.c:48 #, c-format -msgid "" -"Disk quotas for %s %s (%u)\n" -"Filesystem%s" -msgstr "" -"Limity dyskowe (quota) dla %s %s (%u)\n" -"System plików%s" +msgid "%s: can't tell if \"%s\" is writable: %s\n" +msgstr "%s: nie można stwierdzić czy \"%s\" jest zapisywalny: %s\n" -#: .././quota/quota.c:90 +#: .././libxfs/darwin.c:76 .././libxfs/freebsd.c:116 .././libxfs/irix.c:58 +#: .././libxfs/linux.c:138 #, c-format -msgid " Blocks Quota Limit Warn/Time " -msgstr " Bloki Quota Limit Czas ostrz. " +msgid "%s: cannot stat the device file \"%s\": %s\n" +msgstr "%s: nie można wykonać stat na pliku urządzenia \"%s\": %s\n" -#: .././quota/quota.c:91 +#: .././libxfs/darwin.c:86 #, c-format -msgid " Blocks Quota Limit Warn/Time " -msgstr " Bloki Quota Limit Czas ostrz. " +msgid "%s: can't determine device size: %s\n" +msgstr "%s: nie można określić rozmiaru urządzenia: %s\n" -#: .././quota/quota.c:94 +#: .././libxfs/darwin.c:139 .././libxfs/freebsd.c:196 .././libxfs/irix.c:106 +#: .././libxfs/linux.c:226 #, c-format -msgid " Files Quota Limit Warn/Time " -msgstr " Pliki Quota Limit Czas ostrz. " +msgid "%s: can't determine memory size\n" +msgstr "%s: nie można określić rozmiaru pamięci\n" -#: .././quota/quota.c:95 +#: .././libxfs/freebsd.c:49 #, c-format -msgid " Files Quota Limit Warn/Time " -msgstr " Pliki Quota Limit Czas ostrz. " +msgid "%s: %s possibly contains a mounted filesystem\n" +msgstr "%s: %s może zawierać podmontowany system plików\n" -#: .././quota/quota.c:98 +#: .././libxfs/freebsd.c:60 .././libxfs/linux.c:67 #, c-format -msgid "Realtime Quota Limit Warn/Time " -msgstr "Realtime Quota Limit Czas ostrz. " +msgid "%s: %s contains a mounted filesystem\n" +msgstr "%s: %s zawiera podmontowany system plików\n" -#: .././quota/quota.c:99 +#: .././libxfs/freebsd.c:75 .././libxfs/linux.c:85 #, c-format -msgid " Realtime Quota Limit Warn/Time " -msgstr " Realtime Quota Limit Czas ostrz. " +msgid "%s: %s contains a possibly writable, mounted filesystem\n" +msgstr "%s: %s zawiera podmontowany, być może zapisywalny system plików\n" -#: .././quota/quota.c:235 +#: .././libxfs/freebsd.c:89 .././libxfs/linux.c:99 #, c-format -msgid "%s: cannot find user %s\n" -msgstr "%s: nie można odnaleźć użytkownika %s\n" +msgid "%s: %s contains a mounted and writable filesystem\n" +msgstr "%s: %s zawiera podmontowany, zapisywalny system plików\n" -#: .././quota/quota.c:285 +#: .././libxfs/freebsd.c:129 #, c-format -msgid "%s: cannot find group %s\n" -msgstr "%s: nie można odnaleźć grupy %s\n" +msgid "%s: Not a device or file: \"%s\"\n" +msgstr "%s: Nie jest urządzeniem ani plikiem: \"%s\"\n" -#: .././quota/quota.c:342 +#: .././libxfs/freebsd.c:135 #, c-format -msgid "%s: must specify a project name/ID\n" -msgstr "%s: należy podać nazwę/ID projektu\n" +msgid "%s: DIOCGMEDIASIZE failed on \"%s\": %s\n" +msgstr "%s: DIOCGMEDIASIE nie powiodło się dla \"%s\": %s\n" -#: .././quota/quota.c:355 +#: .././libxfs/freebsd.c:141 #, c-format -msgid "%s: cannot find project %s\n" -msgstr "%s: nie można odnaleźć projektu %s\n" +msgid "%s: DIOCGSECTORSIZE failed on \"%s\": %s\n" +msgstr "%s: DIOCGSECTORSIZE nie powiodło się dla \"%s\": %s\n" -#: .././quota/quota.c:460 -msgid "[-bir] [-gpu] [-hnNv] [-f file] [id|name]..." -msgstr "[-bir] [-gpu] [-hnNv] [-f plik] [id|nazwa]..." +#: .././libxfs/init.c:79 .././libxfs/init.c:178 +#, c-format +msgid "%s: %s: device %lld is not open\n" +msgstr "%s: %s: urządzenie %lld nie jest otwarte\n" -#: .././quota/quota.c:461 -msgid "show usage and limits" -msgstr "pokazanie wykorzystania i limitów" +#: .././libxfs/init.c:115 +#, c-format +msgid "%s: cannot stat %s: %s\n" +msgstr "%s: nie można wykonać stat na %s: %s\n" -#: .././quota/report.c:33 .././quota/report.c:647 .././quota/edit.c:697 -msgid "[-gpu] [-f file]" -msgstr "[-gpu] [-f plik]" +#: .././libxfs/init.c:140 +#, c-format +msgid "%s: device %lld is already open\n" +msgstr "%s: urządzenie %lld jest już otwarte\n" -#: .././quota/report.c:34 .././quota/report.c:648 -msgid "dump quota information for backup utilities" -msgstr "zrzucenie informacji o limitach (quota) dla narzędzi backupowych" +#: .././libxfs/init.c:153 +#, c-format +msgid "%s: %s: too many open devices\n" +msgstr "%s: %s: zbyt dużo otwartych urządzeń\n" -#: .././quota/report.c:36 +#: .././libxfs/init.c:196 #, c-format -msgid "" -"\n" -" create a backup file which contains quota limits information\n" -" -g -- dump out group quota limits\n" -" -p -- dump out project quota limits\n" -" -u -- dump out user quota limits (default)\n" -" -f -- write the dump out to the specified file\n" -"\n" -msgstr "" -"\n" -" utworzenie pliku kopii zapasowej zawierającego informacje o limitach (quota)\n" -" -g - zrzucenie limitów dla grup\n" -" -p - zrzucenie limitów dla projektów\n" -" -u - zrzucenie limitów dla użytkowników (domyślne)\n" -" -f - zapisanie zrzutu do podanego pliku\n" -"\n" - -#: .././quota/report.c:48 -msgid "[-bir] [-gpu] [-ahntLNU] [-f file]" -msgstr "[-bir] [-gpu] [-ahntLNU] [-f plik]" - -#: .././quota/report.c:49 .././quota/report.c:657 -msgid "report filesystem quota information" -msgstr "raportowanie informacji o limitach (quota) w systemie plików" +msgid "%s: can't find a character device matching %s\n" +msgstr "%s: nie można odnaleźć urządzenia znakowego odpowiadającego %s\n" -#: .././quota/report.c:51 +#: .././libxfs/init.c:202 #, c-format -msgid "" -"\n" -" report used space and inodes, and quota limits, for a filesystem\n" -" Example:\n" -" 'report -igh'\n" -" (reports inode usage for all groups, in an easy-to-read format)\n" -" This command is the equivalent of the traditional repquota command, which\n" -" prints a summary of the disk usage and quotas for the current filesystem,\n" -" or all filesystems.\n" -" -a -- report for all mounted filesystems with quota enabled\n" -" -h -- report in a human-readable format\n" -" -n -- skip identifier-to-name translations, just report IDs\n" -" -N -- suppress the header from the output\n" -" -t -- terse output format, hides rows which are all zero\n" -" -L -- lower ID bound to report on\n" -" -U -- upper ID bound to report on\n" -" -g -- report group usage and quota information\n" -" -p -- report project usage and quota information\n" -" -u -- report user usage and quota information\n" -" -b -- report blocks-used information only\n" -" -i -- report inodes-used information only\n" -" -r -- report realtime-blocks-used information only\n" -"\n" -msgstr "" -"\n" -" informacje o wykorzystanym miejscu i i-węzłach oraz limitach quota dla systemu\n" -" plików\n" -"\n" -" Przykład:\n" -" 'report -igh'\n" -" (raport o wykorzystaniu i-węzłów dla wszystkich grup w czytelnym formacie)\n" -"\n" -" To polecenie jest odpowiednikiem tradycyjnego polecenia repquota, wypisującego\n" -" podsumowanie wykorzystania dysku i limitów dla bieżącego systemu plików lub\n" -" wszystkich systemów plików.\n" -" -a - informacje o wszystkich zamontowanych systemach plików z limitami\n" -" -h - informacje w formacie czytelnym dla człowieka\n" -" -n - pominięcie tłumaczenia identyfikatorów na nazwy, wypisywanie ID\n" -" -N - pominięcie początkowego nagłówka\n" -" -t - zwięzły format, ukrycie wierszy zerowych\n" -" -L - dolna granica ID dla wypisywanych informacji\n" -" -U - górna granica ID dla wypisywanych informacji\n" -" -g - informacje o wykorzystanym miejscu i limitach dla grup\n" -" -p - informacje o wykorzystanym miejscu i limitach dla projektów\n" -" -u - informacje o wykorzystanym miejscu i limitach dla użytkowników\n" -" -b - tylko informacje o wykorzystanych blokach\n" -" -i - tylko informacje o wykorzystanych i-węzłach\n" -" -r - tylko informacje o wykorzystanych blokach realtime\n" -"\n" +msgid "%s: can't find a block device matching %s\n" +msgstr "%s: nie można odnaleźć urządzenia blokowego odpowiadającego %s\n" -#: .././quota/report.c:228 +#: .././libxfs/init.c:319 #, c-format -msgid "%s quota on %s (%s)\n" -msgstr "limit %s na %s (%s)\n" +msgid "%s: can't get size for data subvolume\n" +msgstr "%s: nie można pobrać rozmiaru podwolumenu danych\n" -#: .././quota/report.c:253 .././quota/report.c:261 +#: .././libxfs/init.c:324 #, c-format -msgid " Used Soft Hard Warn/Grace " -msgstr " Użyto Miękki Twardy Ostrzeżenie " +msgid "%s: can't get size for log subvolume\n" +msgstr "%s: nie można pobrać rozmiaru podwolumenu logu\n" -#: .././quota/report.c:254 .././quota/report.c:262 +#: .././libxfs/init.c:329 #, c-format -msgid " Used Soft Hard Warn/Grace " -msgstr " Użyto Miękki Twardy Ostrzeżenie " +msgid "%s: can't get size for realtime subvolume\n" +msgstr "%s: nie można pobrać rozmiaru podwolumenu realtime\n" -#: .././quota/report.c:257 +#: .././libxfs/init.c:423 #, c-format -msgid " Used Soft Hard Warn/Grace " -msgstr " Użyto Miękki Twardy Ostrzeżenie" +msgid "%s: filesystem has a realtime subvolume\n" +msgstr "%s: system plików ma podwolumen realtime\n" -#: .././quota/report.c:258 +#: .././libxfs/init.c:445 #, c-format -msgid " Used Soft Hard Warn/ Grace " -msgstr " Użyto Miękki Twardy Ostrzeżenie " - -#: .././quota/report.c:656 -msgid "[-bir] [-gpu] [-ahnt] [-f file]" -msgstr "[-bir] [-gpu] [-ahnt] [-f plik]" +msgid "%s: realtime init - %llu != %llu\n" +msgstr "%s: inicjalizacja realtime - %llu != %llu\n" -#: .././quota/state.c:33 +#: .././libxfs/init.c:453 #, c-format -msgid "" -"\n" -" turn filesystem quota off, both accounting and enforcement\n" -"\n" -" Example:\n" -" 'off -uv' (switch off user quota on the current filesystem)\n" -" This command is the equivalent of the traditional quotaoff command,\n" -" which disables quota completely on a mounted filesystem.\n" -" Note that there is no 'on' command - for XFS filesystems (with the\n" -" exception of the root filesystem on IRIX) quota can only be enabled\n" -" at mount time, through the use of one of the quota mount options.\n" -"\n" -" The state command is useful for displaying the current state. Using\n" -" the -v (verbose) option with the 'off' command will display the quota\n" -" state for the affected filesystem once the operation is complete.\n" -" The affected quota type is -g (groups), -p (projects) or -u (users)\n" -" and defaults to user quota (multiple types can be specified).\n" -"\n" -msgstr "" -"\n" -" wyłączenie podsystemu quota (zarówno rozliczania jak i wymuszania)\n" -"\n" -" Przykład:\n" -" 'off -uv' (wyłączenie limitów użytkownika w bieżącym systemie plików)\n" -"\n" -" To polecenie jest odpowiednikiem tradycyjnego polecenia quotaoff,\n" -" wyłączającego całkowicie limity na podmontowanym systemie plików.\n" -" Należy zauważyć, że nie ma polecenia 'on' - dla systemów plików XFS\n" -" (z wyjątkiem głównego systemu plików pod systemem IRIX) limity można\n" -" włączyć wyłącznie na etapie montowania, poprzez użycie jednej z opcji\n" -" quota programu mount.\n" -"\n" -" Polecenie state jest przydatne do wyświetlania aktualnego stanu. Użycie\n" -" opcji -v (szczegółowość) dla polecenia 'off' wyświetli stan quoty dla\n" -" danego systemu plików po zakończeniu operacji.\n" -" Rodzaj limitu którego dotyczy polecenie można wybrać opcją -g (grupy),\n" -" -p (projekty) lub -u (użytkownicy); domyślnie polecenie dotyczy limitów\n" -" użytkowników (można podać wiele rodzajów).\n" -"\n" +msgid "%s: realtime size check failed\n" +msgstr "%s: sprawdzenie rozmiaru realtime nie powiodło się\n" -#: .././quota/state.c:56 +#: .././libxfs/init.c:573 #, c-format -msgid "" -"\n" -" query the state of quota on the current filesystem\n" -"\n" -" This is a verbose status command, reporting whether or not accounting\n" -" and/or enforcement are enabled for a filesystem, which inodes are in\n" -" use as the quota state inodes, and how many extents and blocks are\n" -" presently being used to hold that information.\n" -" The quota type is specified via -g (groups), -p (projects) or -u (users)\n" -" and defaults to user quota (multiple types can be specified).\n" -"\n" -msgstr "" -"\n" -" odczytanie stanu podsystemu quota w bieżącym systemie plików\n" -"\n" -" Jest to polecenie szczegółowo informujące o stanie, opisujące czy włączone\n" -" jest rozliczanie i/lub wymuszanie limitów w systemie plików, które i-węzły\n" -" są wykorzystywane jako i-węzły stanu quot oraz ile ekstentów i bloków jest\n" -" aktualnie używana do przechowywania tych informacji.\n" -" Rodzaj limitów podaje się opcją -g (grupy), -p (projekty) lub -u (użytkownicy);\n" -" domyślnie polecenie dotyczy limitów użytkowników (można podać wiele rodzajów).\n" -"\n" +msgid "%s: buftarg init failed\n" +msgstr "%s: nie udało się zainicjować buftarg\n" -#: .././quota/state.c:72 +#: .././libxfs/init.c:594 #, c-format -msgid "" -"\n" -" enable quota enforcement on a filesystem\n" -"\n" -" If a filesystem is mounted and has quota accounting enabled, but not\n" -" quota enforcement, enforcement can be enabled with this command.\n" -" With the -v (verbose) option, the status of the filesystem will be\n" -" reported after the operation is complete.\n" -" The affected quota type is -g (groups), -p (projects) or -u (users)\n" -" and defaults to user quota (multiple types can be specified).\n" -"\n" -msgstr "" -"\n" -" włączenie wymuszania limitów w systemie plików\n" -"\n" -" Jeśli system plików jest podmontowany i ma włączone rozliczanie limitów,\n" -" ale nie ma wymuszania limitów, można włączyć wymuszanie tym poleceniem.\n" -" Z opcją -v (szczegółowość) po zakończeniu operacji zostanie zraportowany\n" -" stan systemu plików.\n" -" Rodzaj limitów podaje się opcją -g (grupy), -p (projekty) lub -u (użytkownicy);\n" -" domyślnie polecenie dotyczy limitów użytkowników (można podać wiele rodzajów).\n" -"\n" +msgid "%s: bad buftarg reinit, ddev\n" +msgstr "%s: błędna reinicjacja buftarg, ddev\n" -#: .././quota/state.c:88 +#: .././libxfs/init.c:601 #, c-format -msgid "" -"\n" -" disable quota enforcement on a filesystem\n" -"\n" -" If a filesystem is mounted and is currently enforcing quota, this\n" -" provides a mechanism to switch off the enforcement, but continue to\n" -" perform used space (and used inodes) accounting.\n" -" The affected quota type is -g (groups), -p (projects) or -u (users).\n" -"\n" -msgstr "" -"\n" -" wyłączenie wymuszania limitów w systemie plików\n" -"\n" -" Jeśli system plików jest podmontowany i aktualnie wymusza przestrzeganie\n" -" limitów, tym poleceniem można wyłączyć wymuszanie, ale nadal pozostawić\n" -" rozliczanie wykorzystanego miejsca (oraz i-węzłów).\n" -" Rodzaj limitów podaje się opcją -g (grupy), -p (projekty) lub -u (użytkownicy).\n" -"\n" +msgid "%s: bad buftarg reinit, ldev mismatch\n" +msgstr "%s: błędna reinicjacja buftarg, niezgodność ldev\n" -#: .././quota/state.c:102 +#: .././libxfs/init.c:608 #, c-format -msgid "" -"\n" -" remove any space being used by the quota subsystem\n" -"\n" -" Once quota has been switched 'off' on a filesystem, the space that\n" -" was allocated to holding quota metadata can be freed via this command.\n" -" The affected quota type is -g (groups), -p (projects) or -u (users)\n" -" and defaults to user quota (multiple types can be specified).\n" -"\n" -msgstr "" -"\n" -" zwolnienie miejsca zajmowanego przez podsystem quota\n" -"\n" -" Po wyłączeniu limitów dla systemu plików można tym poleceniem zwolnić miejsce\n" -" przydzielone na przechowywanie metadanych quot.\n" -" Rodzaj limitów podaje się opcją -g (grupy), -p (projekty) lub -u (użytkownicy);\n" -" domyślnie polecenie dotyczy limitów użytkowników (można podać wiele rodzajów).\n" -"\n" +msgid "%s: bad buftarg reinit, logdev\n" +msgstr "%s: błędna reinicjacja buftarg, logdev\n" -#: .././quota/state.c:121 +#: .././libxfs/init.c:615 #, c-format -msgid "%s quota state on %s (%s)\n" -msgstr "stan limitów %s na %s (%s)\n" +msgid "%s: bad buftarg reinit, rtdev\n" +msgstr "%s: błędna reinicjacja buftarg, rtdev\n" -#: .././quota/state.c:123 +#: .././libxfs/init.c:707 #, c-format -msgid " Accounting: %s\n" -msgstr " Rozliczanie: %s\n" - -#: .././quota/state.c:123 .././quota/state.c:124 -msgid "ON" -msgstr "WŁĄCZONE" - -#: .././quota/state.c:123 .././quota/state.c:124 -msgid "OFF" -msgstr "WYŁĄCZONE" +msgid "%s: size check failed\n" +msgstr "%s: sprawdzenie rozmiaru nie powiodło się\n" -#: .././quota/state.c:124 +#: .././libxfs/init.c:716 #, c-format -msgid " Enforcement: %s\n" -msgstr " Wymuszanie: %s\n" +msgid "%s: V1 directories unsupported. Please try an older xfsprogs.\n" +msgstr "%s: katalogi V1 nie są obsługiwane. Proszę spróbować starszą wersją xfsprogs.\n" -#: .././quota/state.c:126 +#: .././libxfs/init.c:737 #, c-format -msgid " Inode: #%llu (%llu blocks, %lu extents)\n" -msgstr " I-węzeł: #%llu (%llu bloków, %lu ekstentów)\n" +msgid "%s: data size check failed\n" +msgstr "%s: sprawdzenie rozmiaru danych nie powiodło się\n" -#: .././quota/state.c:131 +#: .././libxfs/init.c:751 #, c-format -msgid " Inode: N/A\n" -msgstr " I-węzeł: N/A\n" +msgid "%s: log size checks failed\n" +msgstr "%s: sprawdzenie rozmiaru logu nie powiodło się\n" -#: .././quota/state.c:140 +#: .././libxfs/init.c:762 #, c-format -msgid "%s grace time: %s\n" -msgstr "czas pobłażliwości %s: %s\n" +msgid "%s: realtime device init failed\n" +msgstr "%s: inicjalizacja urządzenia realtime nie powiodła się\n" -#: .././quota/state.c:157 +#: .././libxfs/init.c:769 #, c-format -msgid "%s quota are not enabled on %s\n" -msgstr "Limity %s nie są włączone na %s\n" +msgid "%s: perag init failed\n" +msgstr "%s: nie udało się zainicjować perag\n" -#: .././quota/state.c:527 .././quota/state.c:543 .././quota/state.c:551 -#: .././quota/state.c:559 -msgid "[-gpu] [-v]" -msgstr "[-gpu] [-v]" +#: .././libxfs/kmem.c:15 +#, c-format +msgid "%s: zone init failed (%s, %d bytes): %s\n" +msgstr "%s: inicjalizacja strefy nie powiodła się (%s, %d bajtów): %s\n" -#: .././quota/state.c:528 -msgid "permanently switch quota off for a path" -msgstr "wyłączenie limitów na stałe dla ścieżki" +#: .././libxfs/kmem.c:32 +#, c-format +msgid "%s: zone alloc failed (%s, %d bytes): %s\n" +msgstr "%s: przydzielenie strefy nie powiodło się (%s, %d bajtów): %s\n" -#: .././quota/state.c:535 -msgid "[-gpu] [-a] [-v] [-f file]" -msgstr "[-gpu] [-a] [-v] [-f plik]" +#: .././libxfs/kmem.c:56 +#, c-format +msgid "%s: malloc failed (%d bytes): %s\n" +msgstr "%s: malloc nie powiodło się (%d bajtów): %s\n" -#: .././quota/state.c:536 -msgid "get overall quota state information" -msgstr "uzyskanie ogólnych informacji o stanie quot" +#: .././libxfs/kmem.c:77 +#, c-format +msgid "%s: realloc failed (%d bytes): %s\n" +msgstr "%s: realloc nie powiodło się (%d bajtów): %s\n" -#: .././quota/state.c:544 -msgid "enable quota enforcement" -msgstr "włączenie wymuszania limitów" +#: .././libxfs/linux.c:114 +#, c-format +msgid "%s: %s - cannot set blocksize %d on block device %s: %s\n" +msgstr "%s: %s - nie można ustawić rozmiaru bloku %d dla urządzenia blokowego %s: %s\n" -#: .././quota/state.c:552 -msgid "disable quota enforcement" -msgstr "wyłączenie wymuszania limitów" +#: .././libxfs/linux.c:171 +#, c-format +msgid "%s: can't determine device size\n" +msgstr "%s: nie można określić rozmiaru urządzenia\n" -#: .././quota/state.c:560 -msgid "remove quota extents from a filesystem" -msgstr "usunięcie ekstentów związanych z limitami z systemu plików" +#: .././libxfs/linux.c:179 +#, c-format +msgid "%s: warning - cannot get sector size from block device %s: %s\n" +msgstr "%s: uwaga - nie można pobrać rozmiaru sektora urządzenia blokowego %s: %s\n" -#: .././quota/util.c:59 +#: .././libxfs/rdwr.c:68 #, c-format -msgid "[-none-]" -msgstr "[-brak-]" +msgid "%s: %s can't memalign %d bytes: %s\n" +msgstr "%s: %s nie można wykonać memalign dla %d bajtów: %s\n" -#: .././quota/util.c:59 +#: .././libxfs/rdwr.c:78 #, c-format -msgid "[--none--]" -msgstr "[--brak--]" +msgid "%s: %s seek to offset %llu failed: %s\n" +msgstr "%s: %s zmiana offsetu na %llu nie powiodła się: %s\n" -#: .././quota/util.c:62 +#: .././libxfs/rdwr.c:88 #, c-format -msgid "[------]" -msgstr "[------]" +msgid "%s: %s write failed: %s\n" +msgstr "%s: %s zapis nie powiódł się: %s\n" -#: .././quota/util.c:62 +#: .././libxfs/rdwr.c:92 #, c-format -msgid "[--------]" -msgstr "[--------]" +msgid "%s: %s not progressing?\n" +msgstr "%s: %s nie postępuje?\n" -# XXX: ngettext() -#: .././quota/util.c:66 .././quota/util.c:69 -msgid "day" -msgstr "dzień" +#: .././libxfs/rdwr.c:409 +#, c-format +msgid "%s: %s can't memalign %u bytes: %s\n" +msgstr "%s: %s nie można wykonać memalign dla %u bajtów: %s\n" -#: .././quota/util.c:66 .././quota/util.c:69 -msgid "days" -msgstr "dni" +#: .././libxfs/rdwr.c:441 +#, c-format +msgid "%s: %s can't malloc %u bytes: %s\n" +msgstr "%s: %s nie można przydzielić %u bajtów: %s\n" -#: .././quota/util.c:194 -msgid "Blocks" -msgstr "Bloki" +#: .././libxfs/rdwr.c:522 +#, c-format +msgid "%s: %s invalid map %p or nmaps %d\n" +msgstr "%s: %s nieprawidłowa mapa %p lub nmaps %d\n" -#: .././quota/util.c:194 -msgid "Inodes" -msgstr "I-węzły" +#: .././libxfs/rdwr.c:529 +#, c-format +msgid "%s: %s map blkno 0x%llx doesn't match key 0x%llx\n" +msgstr "%s: %s map blkno 0x%llx nie pasuje do klucza 0x%llx\n" -#: .././quota/util.c:194 -msgid "Realtime Blocks" -msgstr "Bloki realtime" +#: .././libxfs/rdwr.c:574 +#, c-format +msgid "Warning: recursive buffer locking at block % detected\n" +msgstr "Uwaga: wykryto rekurencyjną blokadę bufora na bloku %\n" -#: .././quota/util.c:209 -msgid "User" -msgstr "użytkowników" +#: .././libxfs/rdwr.c:710 +#, c-format +msgid "%s: read failed: %s\n" +msgstr "%s: odczyt nie powiódł się: %s\n" -#: .././quota/util.c:209 -msgid "Group" -msgstr "grup" +#: .././libxfs/rdwr.c:716 +#, c-format +msgid "%s: error - read only %d of %d bytes\n" +msgstr "%s: błąd - odczytano tylko %d z %d bajtów\n" -#: .././quota/util.c:209 -msgid "Project" -msgstr "projektów" +#: .././libxfs/rdwr.c:878 +#, c-format +msgid "%s: pwrite64 failed: %s\n" +msgstr "%s: pwrite64 nie powiodło się: %s\n" -#: .././quota/util.c:417 +#: .././libxfs/rdwr.c:884 #, c-format -msgid "%s: open on %s failed: %s\n" -msgstr "%s: open dla %s nie powiodło się: %s\n" +msgid "%s: error - pwrite64 only %d of %d bytes\n" +msgstr "%s: błąd - wykonano pwrite64 tylko %d z %d bajtów\n" -#: .././quota/util.c:423 +#: .././libxfs/rdwr.c:920 #, c-format -msgid "%s: fdopen on %s failed: %s\n" -msgstr "%s: fdopen dla %s nie powiodło się: %s\n" +msgid "%s: write verifer failed on bno 0x%llx/0x%x\n" +msgstr "%s: weryfikacja zapisu nie powiodła się na bno 0x%llx/0x%x\n" -#: .././quota/edit.c:36 +#: .././libxfs/trans.c:56 +#, c-format +msgid "%s: lidp calloc failed (%d bytes): %s\n" +msgstr "%s: calloc lidp nie powiodło się (%d bajtów): %s\n" + +#: .././libxfs/trans.c:151 +#, c-format +msgid "%s: xact calloc failed (%d bytes): %s\n" +msgstr "%s: xact calloc nie powiodło się (%d bajtów): %s\n" + +#: .././libxfs/trans.c:676 +#, c-format +msgid "%s: warning - imap_to_bp failed (%d)\n" +msgstr "%s: uwaga - imap_to_bp nie powiodło się (%d)\n" + +#: .././libxfs/trans.c:684 +#, c-format +msgid "%s: warning - iflush_int failed (%d)\n" +msgstr "%s: uwaga - iflush_int nie powiodło się (%d)\n" + +#: .././libxfs/trans.c:744 .././libxfs/trans.c:799 +#, c-format +msgid "%s: unrecognised log item type\n" +msgstr "%s: nierozpoznany typ elementu logu\n" + +#: .././libxfs/util.c:691 +#, c-format +msgid "%s: cannot reserve space: %s\n" +msgstr "%s: nie można zarezerwować przestrzeni: %s\n" + +#: .././libxlog/util.c:37 #, c-format msgid "" -"\n" -" modify quota limits for the specified user\n" -"\n" -" Example:\n" -" 'limit bsoft=100m bhard=110m tanya\n" -"\n" -" Changes the soft and/or hard block limits, inode limits and/or realtime\n" -" block limits that are currently being used for the specified user, group,\n" -" or project. The filesystem identified by the current path is modified.\n" -" -d -- set the default values, used the first time a file is created\n" -" -g -- modify group quota limits\n" -" -p -- modify project quota limits\n" -" -u -- modify user quota limits\n" -" The block limit values can be specified with a units suffix - accepted\n" -" units are: k (kilobytes), m (megabytes), g (gigabytes), and t (terabytes).\n" -" The user/group/project can be specified either by name or by number.\n" -"\n" +"* ERROR: mismatched uuid in log\n" +"* SB : %s\n" +"* log: %s\n" msgstr "" -"\n" -" zmiana limitów quot dla podanego użytkownika\n" -"\n" -"Przykład:\n" -" 'limit bsoft=100m bhard=110m tanya'\n" -"\n" -" limit zmienia miękki i/lub twardy limit bloków, limity i-węzłów i/lub limity\n" -" bloków realtime aktualnie używane dla podanego użytkownika, grupy lub projektu.\n" -" System plików określony bieżącą ścieżką jest modyfikowany.\n" -" -d - ustawienie wartości domyślnych, użytych pierwszy raz przy tworzeniu pliku\n" -" -g - zmiana limitów quot grupy\n" -" -p - zmiana limitów quot projektu\n" -" -u - zmiana limitów quot użytkownika\n" -" Wartości limitów bloków mogą być podane z końcówką jednostki - przyjmowane\n" -" jednostki to: k (kilobajty), m (megabajty), g (gigabajty) i t (terabajty).\n" -" Użytkownik/grupa/projekt może być podany za pomocą nazwy lub numeru.\n" -"\n" +"* BŁĄD: niepasujący uuid w logu\n" +" SB : %s\n" +" log: %s\n" -#: .././quota/edit.c:59 +#: .././libxlog/util.c:50 #, c-format msgid "" "\n" -" modify quota enforcement timeout for the current filesystem\n" -"\n" -" Example:\n" -" 'timer -i 3days'\n" -" (soft inode limit timer is changed to 3 days)\n" -"\n" -" Changes the timeout value associated with the block limits, inode limits\n" -" and/or realtime block limits for all users, groups, or projects on the\n" -" current filesystem.\n" -" As soon as a user consumes the amount of space or number of inodes set as\n" -" the soft limit, a timer is started. If the timer expires and the user is\n" -" still over the soft limit, the soft limit is enforced as the hard limit.\n" -" The default timeout is 7 days.\n" -" -d -- set the default values, used the first time a file is created\n" -" -g -- modify group quota timer\n" -" -p -- modify project quota timer\n" -" -u -- modify user quota timer\n" -" -b -- modify the blocks-used timer\n" -" -i -- modify the inodes-used timer\n" -" -r -- modify the blocks-used timer for the (optional) realtime subvolume\n" -" The timeout value is specified as a number of seconds, by default.\n" -" However, a suffix may be used to alternatively specify minutes (m),\n" -" hours (h), days (d), or weeks (w) - either the full word or the first\n" -" letter of the word can be used.\n" -"\n" +"LOG REC AT LSN cycle %d block %d (0x%x, 0x%x)\n" msgstr "" "\n" -" zmiana czasu wymuszenia limitów dla bieżącego systemu plików\n" -"\n" -" Przykład:\n" -" 'timer -i 3days'\n" -" (zmiana czasu wymuszenia miękkiego limitu i-węzłów na 3 dni)\n" -"\n" -" timer zmienia wartość ograniczenia czasu związanego z limitami bloków,\n" -" limitami i-węzłów i/lub limitami bloków realtime dla wszystkich użytkowników,\n" -" grup lub projektów na bieżącym systemie plików.\n" -" Po tym jak użytkownik wykorzysta ilość miejsca lub liczbę i-węzłów ustawioną\n" -" jako miękki limit, zaczyna działać zegar. Kiedy czas minie, a użytkownik nadal\n" -" przekracza miękki limit, miękki limit staje się twardym.\n" -" Domyślne ograniczenie czasowe to 7 dni.\n" -" -d - ustawienie wartości domyślnych, użytych pierwszy raz przy tworzeniu pliku\n" -" -g - zmiana czasu dla limitów quot grup\n" -" -p - zmiana czasu dla limitów quot projektów\n" -" -u - zmiana czasu dla limitów quot użytkowników\n" -" -b - zmiana czasu dla użytych bloków\n" -" -i - zmiana czasu dla użytych i-węzłów\n" -" -r - zmiana czasu dla użytych bloków na (opcjonalnym) podwolumenie realtime\n" -" Wartość ograniczenia czasu jest podawana domyślnie jako liczba sekund.\n" -" Jednak można dodać końcówkę, aby podać czas w minutach (m), godzinach (h),\n" -" dniach (d) lub tygodniach (w) - można użyć pełnego słowa lub pierwsze litery.\n" -"\n" +"LOG REC AT LSN cykl %d blok %d (0x%x, 0x%x)\n" -#: .././quota/edit.c:91 +#: .././libxlog/util.c:58 #, c-format -msgid "" -"\n" -" modify the number of quota warnings sent to the specified user\n" -"\n" -" Example:\n" -" 'warn 2 jimmy'\n" -" (tell the quota system that two warnings have been sent to user jimmy)\n" -"\n" -" Changes the warning count associated with the block limits, inode limits\n" -" and/or realtime block limits for the specified user, group, or project.\n" -" When a user has been warned the maximum number of times allowed, the soft\n" -" limit is enforced as the hard limit. It is intended as an alternative to\n" -" the timeout system, where the system administrator updates a count of the\n" -" number of warnings issued to people, and they are penalised if the warnings\n" -" are ignored.\n" -" -d -- set maximum warning count, which triggers soft limit enforcement\n" -" -g -- set group quota warning count\n" -" -p -- set project quota warning count\n" -" -u -- set user quota warning count\n" -" -b -- set the blocks-used warning count\n" -" -i -- set the inodes-used warning count\n" -" -r -- set the blocks-used warn count for the (optional) realtime subvolume\n" -" The user/group/project can be specified either by name or by number.\n" -"\n" -msgstr "" -"\n" -" zmiana liczby ostrzeżeń quot wysyłanych do podanego użytkownika\n" -"\n" -" Przykład:\n" -" 'warn 2 jimmy'\n" -" (przekazanie systemowi quota, że wysłano 2 ostrzeżenia do użytkownika jimmy)\n" -"\n" -" warn zmienia liczbę ostrzeżeń związanych z limitami bloków, limitami i-węzłów\n" -" i/lub limitami bloków realtime dla podanego użytkownika, grupy lub projektu.\n" -" Kiedy użytkownik został ostrzeżony maksymalną dozwoloną liczbę razy, miękki\n" -" limit staje się twardym. Jest to pomyślane jako alternatywa dla systemu\n" -" ograniczeń czasowych, gdzie administrator uaktualnia licznik ostrzeżeń\n" -" wysłanych do ludzi i karze użytkowników ignorujących ostrzeżenia.\n" -" -d - ustawienie maksymalnej liczby ostrzeżeń, po której wymuszane są limity\n" -" -g - ustawienie liczby ostrzeżeń dla grupy\n" -" -p - ustawienie liczby ostrzeżeń dla projektu\n" -" -u - ustawienie liczby ostrzeżeń dla grupy\n" -" -b - ustawienie liczby ostrzeżeń dla użytych bloków\n" -" -i - ustawienie liczby ostrzeżeń dla użytych i-węzłów\n" -" -r - ustawienie liczby ostrzeżeń dla użytych bloków na podwolumenie realtime\n" -" Użytkownik/grupa/projekt może być podany za pomocą nazwy lub numeru.\n" -"\n" +msgid "* ERROR: bad magic number in log header: 0x%x\n" +msgstr "* BŁĄD: błędna liczba magiczna w nagłówku logu: 0x%x\n" -#: .././quota/edit.c:145 +#: .././libxlog/util.c:67 #, c-format -msgid "%s: cannot set limits: %s\n" -msgstr "%s: nie można ustawić limitów: %s\n" +msgid "* ERROR: log format incompatible (log=%d, ours=%d)\n" +msgstr "* BŁĄD: niekompatybilny format logu (log=%d, nasz=%d)\n" -#: .././quota/edit.c:166 .././quota/edit.c:569 -#, c-format -msgid "%s: invalid user name: %s\n" -msgstr "%s: nieprawidłowa nazwa użytkownika: %s\n" +#: .././libxlog/util.c:77 .././libxlog/util.c:89 +msgid "Bad log" +msgstr "Błędny log" -#: .././quota/edit.c:189 .././quota/edit.c:586 +#: .././logprint/log_copy.c:44 .././logprint/log_dump.c:43 #, c-format -msgid "%s: invalid group name: %s\n" -msgstr "%s: nieprawidłowa nazwa grupy: %s\n" +msgid "%s: read error (%lld): %s\n" +msgstr "%s: błąd odczytu (%lld): %s\n" -#: .././quota/edit.c:212 .././quota/edit.c:603 +#: .././logprint/log_copy.c:49 .././logprint/log_dump.c:48 #, c-format -msgid "%s: invalid project name: %s\n" -msgstr "%s: nieprawidłowa nazwa projektu: %s\n" +msgid "%s: physical end of log at %lld\n" +msgstr "%s: fizyczny koniec logu na %lld\n" -#: .././quota/edit.c:237 +#: .././logprint/log_copy.c:53 #, c-format -msgid "%s: Error: could not parse size %s.\n" -msgstr "%s: Błąd: nie udało się przeanalizować rozmiaru %s.\n" +msgid "%s: short read? (%lld)\n" +msgstr "%s: skrócony odczyt? (%lld)\n" -#: .././quota/edit.c:243 +#: .././logprint/log_copy.c:60 #, c-format -msgid "%s: Warning: `%s' in quota blocks is 0 (unlimited).\n" -msgstr "%s: Uwaga: `%s' w blokach limitów wynosi 0 (bez ograniczeń).\n" +msgid "%s: write error (%lld): %s\n" +msgstr "%s: błąd zapisu (%lld): %s\n" -#: .././quota/edit.c:332 +#: .././logprint/log_copy.c:65 #, c-format -msgid "%s: unrecognised argument %s\n" -msgstr "%s: nierozpoznany argument %s\n" +msgid "%s: short write? (%lld)\n" +msgstr "%s: skrócony zapis? (%lld)\n" -#: .././quota/edit.c:339 +#: .././logprint/log_dump.c:56 #, c-format -msgid "%s: cannot find any valid arguments\n" -msgstr "%s: nie można znaleźć żadnych poprawnych argumentów\n" +msgid "%6lld HEADER Cycle %d tail %d:%06d len %6d ops %d\n" +msgstr "%6lld NAGŁÓWEK Cykl %d koniec %d:%06d len %6d ops %d\n" -#: .././quota/edit.c:447 +#: .././logprint/log_dump.c:67 #, c-format -msgid "%s: fopen on %s failed: %s\n" -msgstr "%s: fopen na %s nie powiodło się: %s\n" +msgid "[%05lld - %05lld] Cycle 0x%08x New Cycle 0x%08x\n" +msgstr "[%05lld - %05lld] Cykl 0x%08x Nowy cykl 0x%08x\n" -#: .././quota/edit.c:479 +#: .././logprint/log_misc.c:131 #, c-format -msgid "%s: cannot set timer: %s\n" -msgstr "%s: nie można ustawić czasu: %s\n" +msgid "Oper (%d): tid: %x len: %d clientid: %s " +msgstr "Operacja (%d): tid: %x len: %d clientid: %s " -#: .././quota/edit.c:553 +#: .././logprint/log_misc.c:136 #, c-format -msgid "%s: cannot set warnings: %s\n" -msgstr "%s: nie można ustawić ostrzeżeń: %s\n" - -#: .././quota/edit.c:689 -msgid "[-gpu] bsoft|bhard|isoft|ihard|rtbsoft|rtbhard=N -d|id|name" -msgstr "[-gpu] bsoft|bhard|isoft|ihard|rtbsoft|rtbhard=N -d|id|nazwa" - -#: .././quota/edit.c:690 -msgid "modify quota limits" -msgstr "zmiana limitów quot" - -#: .././quota/edit.c:698 -msgid "restore quota limits from a backup file" -msgstr "odtworzenie limitów quot z pliku kopii zapasowej" - -#: .././quota/edit.c:704 .././quota/edit.c:712 -msgid "[-bir] [-gpu] value -d|id|name" -msgstr "[-bir] [-gpu] wartość -d|id|nazwa" - -#: .././quota/edit.c:705 -msgid "get/set quota enforcement timeouts" -msgstr "pobranie/ustawienie czasu wymuszenia quot" - -#: .././quota/edit.c:713 -msgid "get/set enforcement warning counter" -msgstr "pobranie/ustawienie licznika ostrzeżeń" +msgid "flags: " +msgstr "flagi: " -#: .././mkfs/proto.c:60 +#: .././logprint/log_misc.c:230 #, c-format -msgid "%s: failed to open %s: %s\n" -msgstr "%s: nie udało się otworzyć %s: %s\n" +msgid " Not enough data to decode further\n" +msgstr " Za mało danych do dalszego dekodowania\n" -#: .././mkfs/proto.c:66 .././mkfs/proto.c:291 +#: .././logprint/log_misc.c:234 #, c-format -msgid "%s: read failed on %s: %s\n" -msgstr "%s: odczyt nie powiódł się dla %s: %s\n" +msgid " type: %s tid: %x num_items: %d\n" +msgstr " typ: %s tid: %x num_items: %d\n" -#: .././mkfs/proto.c:71 +#: .././logprint/log_misc.c:282 #, c-format -msgid "%s: proto file %s premature EOF\n" -msgstr "%s: plik prototypu %s skończył się przedwcześnie\n" - -#: .././mkfs/proto.c:108 -msgid "cannot reserve space" -msgstr "nie można zarezerwować miejsca" +msgid "#regs: %d start blkno: %lld (0x%llx) len: %d bmap size: %d flags: 0x%x\n" +msgstr "#regs: %d start blkno: %lld (0x%llx) len: %d bmap size: %d flags: 0x%x\n" -#: .././mkfs/proto.c:161 +#: .././logprint/log_misc.c:288 #, c-format -msgid "%s: premature EOF in prototype file\n" -msgstr "%s: przedwczesny EOF w pliku prototypu\n" - -#: .././mkfs/proto.c:180 -msgid "error reserving space for a file" -msgstr "błąd podczas rezerwowania miejsca na plik" - -#: .././mkfs/proto.c:249 -msgid "error allocating space for a file" -msgstr "błąd podczas przydzielania miejsca na plik" +msgid "#regs: %d Not printing rest of data\n" +msgstr "#regs: %d Bez wypisywania reszty danych\n" -#: .././mkfs/proto.c:253 +#: .././logprint/log_misc.c:305 #, c-format -msgid "%s: cannot allocate space for file\n" -msgstr "%s: nie można przydzielić miejsca na plik\n" - -#: .././mkfs/proto.c:316 -msgid "directory createname error" -msgstr "błąd tworzenia nazwy katalogu" - -#: .././mkfs/proto.c:330 -msgid "directory create error" -msgstr "błąd tworzenia katalogu" +msgid "SUPER BLOCK Buffer: " +msgstr "Bufor SUPER BLOKU: " -#: .././mkfs/proto.c:396 .././mkfs/proto.c:408 .././mkfs/proto.c:419 -#: .././mkfs/proto.c:426 +#: .././logprint/log_misc.c:307 .././logprint/log_misc.c:371 +#: .././logprint/log_misc.c:397 #, c-format -msgid "%s: bad format string %s\n" -msgstr "%s: błędny łańcuch formatujący %s\n" - -#: .././mkfs/proto.c:447 .././mkfs/proto.c:486 .././mkfs/proto.c:501 -#: .././mkfs/proto.c:513 .././mkfs/proto.c:525 .././mkfs/proto.c:536 -msgid "Inode allocation failed" -msgstr "Przydzielanie i-węzła nie powiodło się" - -#: .././mkfs/proto.c:464 -msgid "Inode pre-allocation failed" -msgstr "Wczesne przydzielanie i-węzła nie powiodło się" - -#: .././mkfs/proto.c:474 -msgid "Pre-allocated file creation failed" -msgstr "Tworzenie wcześnie przydzielonego pliku nie powiodło się" - -#: .././mkfs/proto.c:556 -msgid "Directory creation failed" -msgstr "Tworzenie katalogu nie powiodło się" - -#: .././mkfs/proto.c:580 -msgid "Error encountered creating file from prototype file" -msgstr "Wystąpił błąd podczas tworzenia pliku z pliku prototypu" - -#: .././mkfs/proto.c:630 -msgid "Realtime bitmap inode allocation failed" -msgstr "Przydzielanie i-węzła bitmapy realtime nie powiodło się" - -#: .././mkfs/proto.c:648 -msgid "Realtime summary inode allocation failed" -msgstr "Tworzenie i-węzła opisu realtime nie powiodło się" - -#: .././mkfs/proto.c:675 -msgid "Allocation of the realtime bitmap failed" -msgstr "Przydzielenie bitmapy realtime nie powiodło się" - -#: .././mkfs/proto.c:688 -msgid "Completion of the realtime bitmap failed" -msgstr "Uzupełnienie bitmapy realtime nie powiodło się" - -#: .././mkfs/proto.c:712 -msgid "Allocation of the realtime summary failed" -msgstr "Przydzielenie opisu realtime nie powiodło się" - -#: .././mkfs/proto.c:724 -msgid "Completion of the realtime summary failed" -msgstr "Uzupełnienie opisu realtime nie powiodło się" - -#: .././mkfs/proto.c:741 -msgid "Error initializing the realtime space" -msgstr "Błąd podczas inicjalizacji przestrzeni realtime" - -#: .././mkfs/proto.c:746 -msgid "Error completing the realtime space" -msgstr "Błąd podczas uzupełniania przestrzeni realtime" +msgid "Out of space\n" +msgstr "Brak miejsca na dysku\n" -#: .././mkfs/xfs_mkfs.c:220 +#: .././logprint/log_misc.c:315 #, c-format -msgid "data su/sw must not be used in conjunction with data sunit/swidth\n" -msgstr "su/sw danych nie można użyć w połączeniu z sunit/swidth danych\n" +msgid "icount: %llu ifree: %llu " +msgstr "icount: %llu ifree: %llu " -#: .././mkfs/xfs_mkfs.c:227 +#: .././logprint/log_misc.c:320 #, c-format -msgid "both data sunit and data swidth options must be specified\n" -msgstr "trzeba podać obie opcje sunit i swidth dla danych\n" +msgid "fdblks: %llu frext: %llu\n" +msgstr "fdblks: %llu frext: %llu\n" -#: .././mkfs/xfs_mkfs.c:236 +#: .././logprint/log_misc.c:327 #, c-format -msgid "data sunit/swidth must not be used in conjunction with data su/sw\n" -msgstr "sunit/swidth danych nie można użyć w połączeniu z su/sw danych\n" +msgid "AGI Buffer: XAGI " +msgstr "Bufor AGI: XAGI " -#: .././mkfs/xfs_mkfs.c:243 +#: .././logprint/log_misc.c:330 #, c-format -msgid "both data su and data sw options must be specified\n" -msgstr "trzeba podać obie opcje su i sw dla danych\n" +msgid "out of space\n" +msgstr "brak miejsca na dysku\n" -#: .././mkfs/xfs_mkfs.c:250 +#: .././logprint/log_misc.c:333 #, c-format -msgid "data su must be a multiple of the sector size (%d)\n" -msgstr "su danych musi być wielokrotnością rozmiaru sektora (%d)\n" +msgid "ver: %d " +msgstr "wersja: %d " -#: .././mkfs/xfs_mkfs.c:261 +#: .././logprint/log_misc.c:335 #, c-format -msgid "data stripe width (%d) must be a multiple of the data stripe unit (%d)\n" -msgstr "szerokość pasa danych (%d) musi być wielokrotnością jednostki pasa danych (%d)\n" +msgid "seq#: %d len: %d cnt: %d root: %d\n" +msgstr "seq#: %d len: %d cnt: %d root: %d\n" -#: .././mkfs/xfs_mkfs.c:271 +#: .././logprint/log_misc.c:340 #, c-format -msgid "log su should not be used in conjunction with log sunit\n" -msgstr "su logu nie powinno być używane w połączeniu z sunit logu\n" +msgid "level: %d free#: 0x%x newino: 0x%x\n" +msgstr "level: %d free#: 0x%x newino: 0x%x\n" -#: .././mkfs/xfs_mkfs.c:280 +#: .././logprint/log_misc.c:350 #, c-format -msgid "log sunit should not be used in conjunction with log su\n" -msgstr "sunit logu nie powinno być używane w połączeniu z su logu\n" +msgid "AGI unlinked data skipped " +msgstr "Pominięto niedowiązane dane AGI " -#: .././mkfs/xfs_mkfs.c:350 .././mkfs/xfs_mkfs.c:474 +#: .././logprint/log_misc.c:351 #, c-format -msgid "%s: %s appears to contain an existing filesystem (%s).\n" -msgstr "%s: %s zdaje się zawierać istniejący system plików (%s).\n" +msgid "(CONTINUE set, no space)\n" +msgstr "(KONTYNUACJA, brak miejsca)\n" -#: .././mkfs/xfs_mkfs.c:354 .././mkfs/xfs_mkfs.c:480 +#: .././logprint/log_misc.c:357 .././logprint/log_print_all.c:146 #, c-format -msgid "%s: %s appears to contain a partition table (%s).\n" -msgstr "%s: %s zdaje się zawierać tablicę partycji (%s).\n" +msgid "bucket[%d - %d]: " +msgstr "kubełek[%d - %d]: " -#: .././mkfs/xfs_mkfs.c:358 +#: .././logprint/log_misc.c:369 #, c-format -msgid "%s: %s appears to contain something weird according to blkid\n" -msgstr "%s: %s zdaje się zawierać coś dziwnego wg blkid\n" +msgid "AGF Buffer: XAGF " +msgstr "Bufor AGF: XAGF " -#: .././mkfs/xfs_mkfs.c:368 +#: .././logprint/log_misc.c:374 #, c-format -msgid "%s: probe of %s failed, cannot detect existing filesystem.\n" -msgstr "%s: test %s nie powiódł się, nie można wykryć istniejącego systemu plików.\n" +msgid "ver: %d seq#: %d len: %d \n" +msgstr "ver: %d seq#: %d len: %d \n" -#: .././mkfs/xfs_mkfs.c:421 +#: .././logprint/log_misc.c:378 #, c-format -msgid "warning: device is not properly aligned %s\n" -msgstr "uwaga: urządzenie nie jest właściwie wyrównane: %s\n" +msgid "root BNO: %d CNT: %d\n" +msgstr "root BNO: %d CNT: %d\n" -#: .././mkfs/xfs_mkfs.c:426 +#: .././logprint/log_misc.c:381 #, c-format -msgid "Use -f to force usage of a misaligned device\n" -msgstr "Można użyć -f do wymuszenia użycia źle wyrównanego urządzenia\n" +msgid "level BNO: %d CNT: %d\n" +msgstr "level BNO: %d CNT: %d\n" -#: .././mkfs/xfs_mkfs.c:440 +#: .././logprint/log_misc.c:384 #, c-format -msgid "warning: unable to probe device toplology for device %s\n" -msgstr "uwaga: nie udało się odczytać topologii urządzenia %s\n" +msgid "1st: %d last: %d cnt: %d freeblks: %d longest: %d\n" +msgstr "1st: %d last: %d cnt: %d freeblks: %d longest: %d\n" -#: .././mkfs/xfs_mkfs.c:549 +#: .././logprint/log_misc.c:394 #, c-format -msgid "log size %lld is not a multiple of the log stripe unit %d\n" -msgstr "rozmiar logu %lld nie jest wielokrotnością jednostki pasa logu %d\n" +msgid "DQUOT Buffer: DQ " +msgstr "Bufor DQUOT: DQ " -#: .././mkfs/xfs_mkfs.c:577 +#: .././logprint/log_misc.c:401 #, c-format -msgid "Due to stripe alignment, the internal log size (%lld) is too large.\n" -msgstr "Ze względu na wyrównanie do rozmiaru pasa rozmiar wewnętrznego logu (%lld) jest zbyt duży.\n" +msgid "ver: %d flags: 0x%x id: %d \n" +msgstr "ver: %d flags: 0x%x id: %d \n" -#: .././mkfs/xfs_mkfs.c:579 +#: .././logprint/log_misc.c:404 #, c-format -msgid "Must fit within an allocation group.\n" -msgstr "Musi zmieścić się wewnątrz grupy alokacji.\n" +msgid "blk limits hard: %llu soft: %llu\n" +msgstr "blk limits hard: %llu soft: %llu\n" -#: .././mkfs/xfs_mkfs.c:590 +#: .././logprint/log_misc.c:409 #, c-format -msgid "log size %lld blocks too small, minimum size is %d blocks\n" -msgstr "rozmiar logu %lld bloków jest zbyt mały, minimalny rozmiar to %d bloków\n" +msgid "blk count: %llu warns: %d timer: %d\n" +msgstr "blk count: %llu warns: %d timer: %d\n" -#: .././mkfs/xfs_mkfs.c:596 +#: .././logprint/log_misc.c:413 #, c-format -msgid "log size %lld blocks too large, maximum size is %lld blocks\n" -msgstr "rozmiar logu %lld bloków jest zbyt duży, maksymalny rozmiar to %lld bloków\n" +msgid "ino limits hard: %llu soft: %llu\n" +msgstr "ino limits hard: %llu soft: %llu\n" -#: .././mkfs/xfs_mkfs.c:602 +#: .././logprint/log_misc.c:418 #, c-format -msgid "log size %lld bytes too large, maximum size is %lld bytes\n" -msgstr "rozmiar logu %lld bajtów jest zbyt duży, maksymalny rozmiar to %lld bajtów\n" +msgid "ino count: %llu warns: %d timer: %d\n" +msgstr "ino count: %llu warns: %d timer: %d\n" -#: .././mkfs/xfs_mkfs.c:710 +#: .././logprint/log_misc.c:424 #, c-format -msgid "agsize (%lldb) too small, need at least %lld blocks\n" -msgstr "agsize (%lldb) zbyt małe, potrzeba co najmniej %lld bloków\n" +msgid "BUF DATA\n" +msgstr "DANE BUFORA\n" -#: .././mkfs/xfs_mkfs.c:718 +#: .././logprint/log_misc.c:466 #, c-format -msgid "agsize (%lldb) too big, maximum is %lld blocks\n" -msgstr "agsize (%lldb) zbyt duże, maksimum to %lld bloków\n" +msgid "EFD: #regs: %d num_extents: %d id: 0x%llx\n" +msgstr "EFD: #regs: %d num_extents: %d id: 0x%llx\n" -#: .././mkfs/xfs_mkfs.c:726 +#: .././logprint/log_misc.c:473 #, c-format -msgid "agsize (%lldb) too big, data area is %lld blocks\n" -msgstr "agsize (%lldb) zbyt duże, obszar danych to %lld bloków\n" +msgid "EFD: Not enough data to decode further\n" +msgstr "EFD: Za mało danych do dalszego dekodowania\n" -#: .././mkfs/xfs_mkfs.c:733 +#: .././logprint/log_misc.c:497 .././logprint/log_misc.c:513 #, c-format -msgid "too many allocation groups for size = %lld\n" -msgstr "zbyt dużo grup alokacji dla rozmiaru = %lld\n" +msgid "%s: xlog_print_trans_efi: malloc failed\n" +msgstr "%s: xlog_print_trans_efi: malloc nie powiodło się\n" -#: .././mkfs/xfs_mkfs.c:735 +#: .././logprint/log_misc.c:507 #, c-format -msgid "need at most %lld allocation groups\n" -msgstr "potrzeba najwyżej %lld grup alokacji\n" +msgid "EFI: Not enough data to decode further\n" +msgstr "EFI: Za mało danych do dalszego dekodowania\n" -#: .././mkfs/xfs_mkfs.c:743 +#: .././logprint/log_misc.c:521 #, c-format -msgid "too few allocation groups for size = %lld\n" -msgstr "zbyt mało grup alokacji dla rozmiaru = %lld\n" +msgid "EFI: #regs: %d num_extents: %d id: 0x%llx\n" +msgstr "EFI: #regs: %d num_extents: %d id: 0x%llx\n" -#: .././mkfs/xfs_mkfs.c:745 +#: .././logprint/log_misc.c:525 #, c-format -msgid "need at least %lld allocation groups\n" -msgstr "potrzeba co najmniej %lld grup alokacji\n" +msgid "EFI free extent data skipped (CONTINUE set, no space)\n" +msgstr "Pominięto dane wolnego ekstentu EFI (KONTYNUACJA, brak miejsca)\n" -#: .././mkfs/xfs_mkfs.c:758 +#: .././logprint/log_misc.c:554 #, c-format -msgid "last AG size %lld blocks too small, minimum size is %lld blocks\n" -msgstr "rozmiar ostatniej AG %lld bloków zbyt mały, minimalny rozmiar to %lld bloków\n" +msgid "QOFF: #regs: %d flags: 0x%x\n" +msgstr "QOFF: #regs: %d flags: 0x%x\n" -#: .././mkfs/xfs_mkfs.c:769 +#: .././logprint/log_misc.c:557 #, c-format -msgid "%lld allocation groups is too many, maximum is %lld\n" -msgstr "%lld grup alokacji to zbyt dużo, maksimum to %lld\n" +msgid "QOFF: Not enough data to decode further\n" +msgstr "QOFF: Za mało danych do dalszego dekodowania\n" -#: .././mkfs/xfs_mkfs.c:793 +#: .././logprint/log_misc.c:566 #, c-format -msgid "error reading existing superblock -- failed to memalign buffer\n" -msgstr "błąd podczas odczytu istniejącego superbloku - nie udało się wykonać memalign dla bufora\n" +msgid "INODE CORE\n" +msgstr "RDZEŃ I-WĘZŁA\n" -#: .././mkfs/xfs_mkfs.c:799 +#: .././logprint/log_misc.c:567 #, c-format -msgid "existing superblock read failed: %s\n" -msgstr "odczyt istniejącego superbloku nie powiódł się: %s\n" +msgid "magic 0x%hx mode 0%ho version %d format %d\n" +msgstr "magic 0x%hx mode 0%ho version %d format %d\n" -#: .././mkfs/xfs_mkfs.c:1098 +#: .././logprint/log_misc.c:570 #, c-format -msgid "%s: Specify data sunit in 512-byte blocks, no unit suffix\n" -msgstr "%s: sunit danych należy podać w 512-bajtowych blokach, bez jednostki\n" +msgid "nlink %hd uid %d gid %d\n" +msgstr "nlink %hd uid %d gid %d\n" -#: .././mkfs/xfs_mkfs.c:1114 +#: .././logprint/log_misc.c:572 #, c-format -msgid "%s: Specify data swidth in 512-byte blocks, no unit suffix\n" -msgstr "%s: swidth danych należy podać w 512-bajtowych blokach, bez jednostki\n" +msgid "atime 0x%x mtime 0x%x ctime 0x%x\n" +msgstr "atime 0x%x mtime 0x%x ctime 0x%x\n" -#: .././mkfs/xfs_mkfs.c:1141 +#: .././logprint/log_misc.c:574 #, c-format -msgid "%s: Specify data sw as multiple of su, no unit suffix\n" -msgstr "%s: sw danych należy podać jako wielokrotność su, bez jednostki\n" +msgid "size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n" +msgstr "size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n" -#: .././mkfs/xfs_mkfs.c:1370 +#: .././logprint/log_misc.c:577 #, c-format -msgid "Specify log sunit in 512-byte blocks, no size suffix\n" -msgstr "sunit należy podać w 512-bajtowych blokach, bez jednostki\n" +msgid "naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n" +msgstr "naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n" -#: .././mkfs/xfs_mkfs.c:1630 +#: .././logprint/log_misc.c:580 #, c-format -msgid "extra arguments\n" -msgstr "nadmiarowe argumenty\n" +msgid "flags 0x%x gen 0x%x\n" +msgstr "flags 0x%x gen 0x%x\n" -#: .././mkfs/xfs_mkfs.c:1636 +#: .././logprint/log_misc.c:596 #, c-format -msgid "cannot specify both %s and -d name=%s\n" -msgstr "nie można podać jednocześnie %s i -d name=%s\n" +msgid "SHORTFORM DIRECTORY size %d\n" +msgstr "Rozmiar KATALOGU W POSTACI KRÓTKIEJ %d\n" -#: .././mkfs/xfs_mkfs.c:1653 +#: .././logprint/log_misc.c:602 #, c-format -msgid "illegal block size %d\n" -msgstr "niedozwolony rozmiar bloku %d\n" +msgid "SHORTFORM DIRECTORY size %d count %d\n" +msgstr "KATALOG W POSTACI KRÓTKIEJ: rozmiar %d liczba %d\n" -#: .././mkfs/xfs_mkfs.c:1688 +#: .././logprint/log_misc.c:605 #, c-format -msgid "specified blocksize %d is less than device physical sector size %d\n" -msgstr "podany rozmiar bloku %d jest mniejszy niż rozmiar fizycznego sektora urządzenia (%d)\n" +msgid ".. ino 0x%llx\n" +msgstr ".. ino 0x%llx\n" -#: .././mkfs/xfs_mkfs.c:1691 +#: .././logprint/log_misc.c:613 #, c-format -msgid "switching to logical sector size %d\n" -msgstr "przełączono na rozmiar sektora logicznego %d\n" +msgid "%s ino 0x%llx namelen %d\n" +msgstr "%s ino 0x%llx namelen %d\n" -#: .././mkfs/xfs_mkfs.c:1709 +#: .././logprint/log_misc.c:652 #, c-format -msgid "illegal sector size %d\n" -msgstr "niedozwolony rozmiar sektora %d\n" +msgid "INODE: " +msgstr "I-WĘZEŁ: " -#: .././mkfs/xfs_mkfs.c:1712 +#: .././logprint/log_misc.c:653 #, c-format -msgid "block size %d cannot be smaller than logical sector size %d\n" -msgstr "rozmiar bloku %d nie może być mniejszy niż rozmiar sektora logicznego %d\n" +msgid "#regs: %d ino: 0x%llx flags: 0x%x dsize: %d\n" +msgstr "#regs: %d ino: 0x%llx flags: 0x%x dsize: %d\n" -#: .././mkfs/xfs_mkfs.c:1717 +#: .././logprint/log_misc.c:656 #, c-format -msgid "illegal sector size %d; hw sector is %d\n" -msgstr "niedozwolony rozmiar sektora %d; sektor sprzętowy ma %d\n" +msgid " blkno: %lld len: %d boff: %d\n" +msgstr " blkno: %lld len: %d boff: %d\n" -#: .././mkfs/xfs_mkfs.c:1723 +#: .././logprint/log_misc.c:661 #, c-format -msgid "illegal log sector size %d\n" -msgstr "niedozwolony rozmiar sektora logu %d\n" +msgid "INODE: #regs: %d Not printing rest of data\n" +msgstr "I-WĘZEŁ: #regs: %d Bez wypisywania reszty danych\n" -#: .././mkfs/xfs_mkfs.c:1733 +#: .././logprint/log_misc.c:692 #, c-format -msgid "illegal directory block size %d\n" -msgstr "niedozwolony rozmiar bloku katalogu %d\n" +msgid "DEV inode: no extra region\n" +msgstr "I-węzeł DEV: brak dodatkowego regionu\n" -#: .././mkfs/xfs_mkfs.c:1747 +#: .././logprint/log_misc.c:695 #, c-format -msgid "both -d agcount= and agsize= specified, use one or the other\n" -msgstr "podano jednocześnie -d agcount= i agsize=, można użyć tylko jednej z tych opcji\n" +msgid "UUID inode: no extra region\n" +msgstr "I-węzeł UUID: brak dodatkowego regionu\n" -#: .././mkfs/xfs_mkfs.c:1753 +#: .././logprint/log_misc.c:712 #, c-format -msgid "if -d file then -d name and -d size are required\n" -msgstr "jeśli podano -d file, to -d name i -d size są wymagane\n" +msgid "EXTENTS inode data\n" +msgstr "EKSTENTY danych i-węzła\n" -#: .././mkfs/xfs_mkfs.c:1762 +#: .././logprint/log_misc.c:715 #, c-format -msgid "illegal data length %lld, not a multiple of %d\n" -msgstr "niedozwolona długość danych %lld, nie jest wielokrotnością %d\n" +msgid "BTREE inode data\n" +msgstr "B-DRZEWO danych i-węzła\n" -#: .././mkfs/xfs_mkfs.c:1768 +#: .././logprint/log_misc.c:718 #, c-format -msgid "warning: data length %lld not a multiple of %d, truncated to %lld\n" -msgstr "uwaga: długość danych %lld nie jest wielokrotnością %d, ucięto do %lld\n" +msgid "LOCAL inode data\n" +msgstr "LOKALNE dane i-węzła\n" -#: .././mkfs/xfs_mkfs.c:1782 +#: .././logprint/log_misc.c:739 #, c-format -msgid "if -l file then -l name and -l size are required\n" -msgstr "jeśli podano -l file to -l name i -l size są wymagane\n" +msgid "EXTENTS attr data\n" +msgstr "EKSTENTY danych atrybutów\n" -#: .././mkfs/xfs_mkfs.c:1791 +#: .././logprint/log_misc.c:742 #, c-format -msgid "illegal log length %lld, not a multiple of %d\n" -msgstr "niedozwolona długość logu %lld, nie jest wielokrotnością %d\n" +msgid "BTREE attr data\n" +msgstr "B-DRZEWO danych atrybutów\n" -#: .././mkfs/xfs_mkfs.c:1798 +#: .././logprint/log_misc.c:745 #, c-format -msgid "warning: log length %lld not a multiple of %d, truncated to %lld\n" -msgstr "uwaga: długość logu %lld nie jest wielokrotnością %d, ucięto do %lld\n" +msgid "LOCAL attr data\n" +msgstr "LOKALNE dane atrybutów\n" -#: .././mkfs/xfs_mkfs.c:1804 +#: .././logprint/log_misc.c:783 #, c-format -msgid "if -r file then -r name and -r size are required\n" -msgstr "jeśli podano -r file, to -r name i -r size są wymagane\n" +msgid "#regs: %d id: 0x%x" +msgstr "#regs: %d id: 0x%x" -#: .././mkfs/xfs_mkfs.c:1813 +#: .././logprint/log_misc.c:784 #, c-format -msgid "illegal rt length %lld, not a multiple of %d\n" -msgstr "niedozwolona długość rt %lld, nie jest wielokrotnością %d\n" +msgid " blkno: %lld len: %d boff: %d\n" +msgstr " blkno: %lld len: %d boff: %d\n" -#: .././mkfs/xfs_mkfs.c:1820 +#: .././logprint/log_misc.c:788 #, c-format -msgid "warning: rt length %lld not a multiple of %d, truncated to %lld\n" -msgstr "uwaga: długość rt %lld nie jest wielokrotnością %d, ucięto do %lld\n" +msgid "DQUOT: #regs: %d Not printing rest of data\n" +msgstr "DQUOT: #regs: %d Bez wypisywania reszty danych\n" -#: .././mkfs/xfs_mkfs.c:1833 +#: .././logprint/log_misc.c:807 #, c-format -msgid "illegal rt extent size %lld, not a multiple of %d\n" -msgstr "niedozwolony rozmiar ekstentu rt %lld, nie jest wielokrotnością %d\n" +msgid "DQUOT: magic 0x%hx flags 0%ho\n" +msgstr "DQUOT: magic 0x%hx flags 0%ho\n" -#: .././mkfs/xfs_mkfs.c:1839 +#: .././logprint/log_misc.c:833 #, c-format -msgid "rt extent size %s too large, maximum %d\n" -msgstr "rozmiar ekstentu rt %s zbyt duży, maksimum to %d\n" +msgid "ICR: split header, not printing\n" +msgstr "ICR: nagłówek podzielony, bez wypisywania\n" -#: .././mkfs/xfs_mkfs.c:1845 +#: .././logprint/log_misc.c:837 #, c-format -msgid "rt extent size %s too small, minimum %d\n" -msgstr "rozmiar ekstentu rt %s zbyt mały, minimum to %d\n" +msgid "" +"ICR: #ag: %d agbno: 0x%x len: %d\n" +" cnt: %d isize: %d gen: 0x%x\n" +msgstr "" +"ICR: #ag: %d agbno: 0x%x len: %d\n" +" cnt: %d isize: %d gen: 0x%x\n" -#: .././mkfs/xfs_mkfs.c:1890 +#: .././logprint/log_misc.c:863 #, c-format -msgid "illegal inode size %d\n" -msgstr "niedozwolony rozmiar i-węzła %d\n" +msgid "%s: lseek64 to %lld failed: %s\n" +msgstr "%s: lseek64 na %lld nie powiodło się: %s\n" -#: .././mkfs/xfs_mkfs.c:1895 +#: .././logprint/log_misc.c:909 #, c-format -msgid "allowable inode size with %d byte blocks is %d\n" -msgstr "dozwolony rozmiar i-węzła przy blokach %d-bajtowych to %d\n" +msgid "%s: xlog_print_record: malloc failed\n" +msgstr "%s: xlog_print_record: malloc nie powiodło się\n" -#: .././mkfs/xfs_mkfs.c:1899 +#: .././logprint/log_misc.c:918 #, c-format -msgid "allowable inode size with %d byte blocks is between %d and %d\n" -msgstr "dozwolone rozmiary i-węzła przy blokach %d-bajtowych są od %d do %d\n" +msgid "%s: xlog_print_record: read error\n" +msgstr "%s: xlog_print_record: błąd odczytu\n" -#: .././mkfs/xfs_mkfs.c:1907 +#: .././logprint/log_misc.c:1013 .././logprint/log_misc.c:1083 #, c-format -msgid "log stripe unit specified, using v2 logs\n" -msgstr "podano jednostkę pasa logu, użyto logów v2\n" +msgid "Left over region from split log item\n" +msgstr "Region pozostały z podziału elementu logu\n" -#: .././mkfs/xfs_mkfs.c:1922 +#: .././logprint/log_misc.c:1068 #, c-format -msgid "no device name given in argument list\n" -msgstr "nie podano nazwy urządzenia w liście argumentów\n" +msgid "Unmount filesystem\n" +msgstr "Niezamontowany system plików\n" -#: .././mkfs/xfs_mkfs.c:1947 +#: .././logprint/log_misc.c:1075 #, c-format -msgid "%s: Use the -f option to force overwrite.\n" -msgstr "%s: Można użyć opcji -f do wymuszenia nadpisania.\n" - -#: .././mkfs/xfs_mkfs.c:1966 -msgid "internal log" -msgstr "log wewnętrzny" +msgid "%s: unknown log operation type (%x)\n" +msgstr "%s: nieznany typ operacji w logu (%x)\n" -#: .././mkfs/xfs_mkfs.c:1968 -msgid "volume log" -msgstr "log na wolumenie" +#: .././logprint/log_misc.c:1116 +#, c-format +msgid "Header 0x%x wanted 0x%x\n" +msgstr "Nagłówek 0x%x, pożądany 0x%x\n" -#: .././mkfs/xfs_mkfs.c:1970 +#: .././logprint/log_misc.c:1130 #, c-format -msgid "no log subvolume or internal log\n" -msgstr "brak podwolumenu logu ani logu wewnętrznego\n" +msgid "cycle: %d\tversion: %d\t" +msgstr "cykl: %d\twersja: %d\t" -#: .././mkfs/xfs_mkfs.c:1977 -msgid "volume rt" -msgstr "wolumen rt" +#: .././logprint/log_misc.c:1136 +#, c-format +msgid "length of Log Record: %d\tprev offset: %d\t\tnum ops: %d\n" +msgstr "długość rekordu logu: %d\tpoprz.offset: %d\t\tl.oper.: %d\n" -#: .././mkfs/xfs_mkfs.c:1979 .././logprint/log_misc.c:152 -#: .././growfs/xfs_growfs.c:86 .././db/io.c:157 +#: .././logprint/log_misc.c:1142 .././logprint/log_misc.c:1184 #, c-format -msgid "none" -msgstr "brak" +msgid "cycle num overwrites: " +msgstr "liczba nadpisań cyklu: " -#: .././mkfs/xfs_mkfs.c:1982 +#: .././logprint/log_misc.c:1151 #, c-format -msgid "size %s specified for data subvolume is too large, maximum is %lld blocks\n" -msgstr "rozmiar %s podany dla podwolumenu danych jest zbyt duży, maksimum to %lld bloków\n" +msgid "uuid: %s format: " +msgstr "uuid: %s format: " -#: .././mkfs/xfs_mkfs.c:1989 +#: .././logprint/log_misc.c:1154 #, c-format -msgid "can't get size of data subvolume\n" -msgstr "nie można pobrać rozmiaru podwolumenu danych\n" +msgid "unknown\n" +msgstr "nieznany\n" -#: .././mkfs/xfs_mkfs.c:1994 +#: .././logprint/log_misc.c:1157 #, c-format -msgid "size %lld of data subvolume is too small, minimum %d blocks\n" -msgstr "rozmiar %lld dla podwolumenu danych jest zbyt mały, minimum to %d bloków\n" +msgid "little endian linux\n" +msgstr "Linux little endian\n" -#: .././mkfs/xfs_mkfs.c:2001 +#: .././logprint/log_misc.c:1160 #, c-format -msgid "can't have both external and internal logs\n" -msgstr "nie można mieć jednocześnie zewnętrznego i wewnętrznego logu\n" +msgid "big endian linux\n" +msgstr "Linux big endian\n" -#: .././mkfs/xfs_mkfs.c:2005 +#: .././logprint/log_misc.c:1163 #, c-format -msgid "data and log sector sizes must be equal for internal logs\n" -msgstr "rozmiary sektora danych i logu muszą być równe dla logów wewnętrznych\n" +msgid "big endian irix\n" +msgstr "IRIX big endian\n" -#: .././mkfs/xfs_mkfs.c:2011 +#: .././logprint/log_misc.c:1169 #, c-format -msgid "" -"Warning: the data subvolume sector size %u is less than the sector size \n" -"reported by the device (%u).\n" -msgstr "" -"Uwaga: rozmiar sektora podwolumenu danych %u jest mniejszy od rozmiaru\n" -"sektora zgłaszanego przez urządzenie (%u).\n" +msgid "h_size: %d\n" +msgstr "h_size: %d\n" -#: .././mkfs/xfs_mkfs.c:2017 +#: .././logprint/log_misc.c:1181 #, c-format -msgid "" -"Warning: the log subvolume sector size %u is less than the sector size\n" -"reported by the device (%u).\n" -msgstr "" -"Uwaga: rozmiar sektora podwolumenu logu %u jest mniejszy od rozmiaru\n" -"sektora zgłaszanego przez urządzenie (%u).\n" +msgid "extended-header: cycle: %d\n" +msgstr "nagłówek-rozszerzony: cykl: %d\n" + +#: .././logprint/log_misc.c:1197 +#, c-format +msgid "* ERROR: found data after zeroed blocks block=%-21lld *\n" +msgstr "* BŁĄD: znaleziono dane za wyzerowanymi blokami blok=%-21lld *\n" + +#: .././logprint/log_misc.c:1208 +#, c-format +msgid "* ERROR: header cycle=%-11d block=%-21lld *\n" +msgstr "* BŁĄD: nagłówek cykl=%-11d blok=%-21lld *\n" -#: .././mkfs/xfs_mkfs.c:2023 +#: .././logprint/log_misc.c:1219 +#, c-format +msgid "* ERROR: data block=%-21lld *\n" +msgstr "* BŁĄD: blok danych=%-21lld *\n" + +#: .././logprint/log_misc.c:1230 #, c-format msgid "" -"Warning: the realtime subvolume sector size %u is less than the sector size\n" -"reported by the device (%u).\n" +"* ERROR: for header block=%lld\n" +"* not enough hdrs for data length, required num = %d, hdr num = %d\n" msgstr "" -"Uwaga: rozmiar sektora podwolumenu realtime %u jest mniejszy od rozmiaru\n" -"sektora zgłaszanego przez urządzenie (%u).\n" +"* BŁĄD: dla bloku nagłówka %lld\n" +"* za mało nagłówków dla długości danych, wymaganych = %d, liczba = %d\n" -#: .././mkfs/xfs_mkfs.c:2037 +#: .././logprint/log_misc.c:1236 +msgid "Not enough headers for data length." +msgstr "Za mało nagłówków dla długości danych." + +#: .././logprint/log_misc.c:1246 #, c-format -msgid "size %s specified for log subvolume is too large, maximum is %lld blocks\n" -msgstr "rozmiar %s podany dla podwolumenu logu jest zbyt duży, maksimum to %lld bloków\n" +msgid "%s: xlog_print: malloc failed for ext hdrs\n" +msgstr "%s: xlog_print: malloc dla rozszerzonych nagłówków nie powiódł się\n" -#: .././mkfs/xfs_mkfs.c:2044 +#: .././logprint/log_misc.c:1292 .././logprint/log_misc.c:1368 +#: .././logprint/log_misc.c:1439 .././logprint/log_misc.c:1476 #, c-format -msgid "size specified for non-existent log subvolume\n" -msgstr "podano rozmiar dla nie istniejącego podwolumenu logu\n" +msgid "%s: physical end of log\n" +msgstr "%s: fizyczny koniec logu\n" -#: .././mkfs/xfs_mkfs.c:2047 +#: .././logprint/log_misc.c:1298 .././logprint/log_misc.c:1373 +#: .././logprint/log_misc.c:1491 #, c-format -msgid "size %lld too large for internal log\n" -msgstr "rozmiar %lld jest zbyt duży dla logu wewnętrznego\n" +msgid "BLKNO: %lld\n" +msgstr "BLKNO: %lld\n" -#: .././mkfs/xfs_mkfs.c:2074 +#: .././logprint/log_misc.c:1356 #, c-format -msgid "size %s specified for rt subvolume is too large, maximum is %lld blocks\n" -msgstr "rozmiar %s podany dla podwolumenu rt jest zbyt duży, maksimum to %lld bloków\n" +msgid "%s: problem finding oldest LR\n" +msgstr "%s: problem ze znalezieniem najstarszego rekordu logu\n" -#: .././mkfs/xfs_mkfs.c:2082 +#: .././logprint/log_misc.c:1382 #, c-format -msgid "size specified for non-existent rt subvolume\n" -msgstr "podano rozmiar dla nie istniejącego podwolumenu rt\n" +msgid "%s: after %d zeroed blocks\n" +msgstr "%s: po %d wyzerowanych blokach\n" -#: .././mkfs/xfs_mkfs.c:2099 +#: .././logprint/log_misc.c:1451 +msgid "illegal value" +msgstr "niedozwolona wartość" + +#: .././logprint/log_misc.c:1457 #, c-format -msgid "agsize (%lld) not a multiple of fs blk size (%d)\n" -msgstr "agsize (%lld) nie jest wielokrotnością rozmiaru bloku systemu plików (%d)\n" +msgid "%s: skipped %d cleared blocks in range: %lld - %lld\n" +msgstr "%s: pominięto %d wyzerowanych bloków w przedziale: %lld - %lld\n" -#: .././mkfs/xfs_mkfs.c:2116 +#: .././logprint/log_misc.c:1462 #, c-format -msgid "%s: Specified data stripe unit %d is not the same as the volume stripe unit %d\n" -msgstr "%s: Podana jednostka pasa danych %d nie jest taka sama jak jednostka pasa wolumenu %d\n" +msgid "%s: totally cleared log\n" +msgstr "%s: całkowicie wyczyszczony log\n" -#: .././mkfs/xfs_mkfs.c:2123 +#: .././logprint/log_misc.c:1467 #, c-format -msgid "%s: Specified data stripe width %d is not the same as the volume stripe width %d\n" -msgstr "%s: Podana szerokość pasa danych %d nie jest taka sama jak szerokość pasa wolumenu %d\n" +msgid "%s: skipped %d zeroed blocks in range: %lld - %lld\n" +msgstr "%s: pominięto %d wyzerowanych bloków w przedziale %lld - %lld\n" -#: .././mkfs/xfs_mkfs.c:2171 +#: .././logprint/log_misc.c:1472 #, c-format -msgid "agsize rounded to %lld, swidth = %d\n" -msgstr "agsize zaokrąglone do %lld, swidth = %d\n" +msgid "%s: totally zeroed log\n" +msgstr "%s: całkowicie wyzerowany log\n" + +#: .././logprint/log_misc.c:1488 +msgid "xlog_find_head: bad read" +msgstr "xlog_find_head: błędny odczyt" -#: .././mkfs/xfs_mkfs.c:2178 +#: .././logprint/log_misc.c:1540 #, c-format -msgid "Allocation group size (%lld) is not a multiple of the stripe unit (%d)\n" -msgstr "Rozmiar grupy alokacji (%lld) nie jest wielokrotnością jednostki pasa (%d)\n" +msgid "%s: logical end of log\n" +msgstr "%s: logiczny koniec logu\n" -#: .././mkfs/xfs_mkfs.c:2200 +#: .././logprint/log_misc.c:1636 #, c-format -msgid "" -"Warning: AG size is a multiple of stripe width. This can cause performance\n" -"problems by aligning all AGs on the same disk. To avoid this, run mkfs with\n" -"an AG size that is one stripe unit smaller, for example %llu.\n" -msgstr "" -"Uwaga: rozmiar AG jest wielokrotnością szerokości pasa. Może to spowodować\n" -"problemy z wydajnością poprzez wyrównanie wszystkich AG na tym samym dysku.\n" -"Aby temu zapobiec, należy uruchomić mkfs z rozmiarem AG o jedną jednostkę\n" -"pasa mniejszym, na przykład %llu.\n" +msgid "%s: bad size of efi format: %u; expected %u or %u; nextents = %u\n" +msgstr "%s: błędny rozmiar formatu efi: %u; oczekiwano %u lub %u; nextents = %u\n" -#: .././mkfs/xfs_mkfs.c:2225 +#: .././logprint/log_print_all.c:94 #, c-format -msgid "%s: Stripe unit(%d) or stripe width(%d) is not a multiple of the block size(%d)\n" -msgstr "%s: Jednostka pasa (%d) lub szerokość pasa (%d) nie jest wielokrotnością rozmiaru bloku (%d)\n" +msgid "BUF: #regs:%d start blkno:0x%llx len:%d bmap size:%d flags:0x%x\n" +msgstr "BUF: #regs:%d blok pocz.:0x%llx dług.:%d rozm.bmapy:%d flagi:0x%x\n" -#: .././mkfs/xfs_mkfs.c:2257 +#: .././logprint/log_print_all.c:104 #, c-format -msgid "log stripe unit (%d) must be a multiple of the block size (%d)\n" -msgstr "jednostka pasa logu (%d) musi być wielokrotnością rozmiaru bloku (%d)\n" +msgid "\tSUPER Block Buffer:\n" +msgstr "\tBufor SUPER bloku:\n" -#: .././mkfs/xfs_mkfs.c:2270 +#: .././logprint/log_print_all.c:107 #, c-format -msgid "log stripe unit (%d bytes) is too large (maximum is 256KiB)\n" -msgstr "jednostka pasa logu (%d bajtów) jest zbyt duża (maksimum to 256KiB)\n" +msgid " icount:%llu ifree:%llu " +msgstr " icount:%llu ifree:%llu " -#: .././mkfs/xfs_mkfs.c:2273 +#: .././logprint/log_print_all.c:112 #, c-format -msgid "log stripe unit adjusted to 32KiB\n" -msgstr "jednostka pasa logu zmodyfikowana na 32KiB\n" +msgid "fdblks:%llu frext:%llu\n" +msgstr "fdblks:%llu frext:%llu\n" -#: .././mkfs/xfs_mkfs.c:2298 +#: .././logprint/log_print_all.c:117 #, c-format -msgid "internal log size %lld too large, must fit in allocation group\n" -msgstr "rozmiar wewnętrznego logu %lld zbyt duży, musi się zmieścić w grupie alokacji\n" +msgid "\t\tsunit:%u swidth:%u\n" +msgstr "\t\tsunit:%u swidth:%u\n" -#: .././mkfs/xfs_mkfs.c:2305 +#: .././logprint/log_print_all.c:123 #, c-format -msgid "log ag number %d too large, must be less than %lld\n" -msgstr "liczba ag logu %d zbyt duża, musi być mniejsza niż %lld\n" +msgid "\tAGI Buffer: (XAGI)\n" +msgstr "\tBufor AGI: (XAGI)\n" -#: .././mkfs/xfs_mkfs.c:2335 +#: .././logprint/log_print_all.c:126 #, c-format -msgid "" -"meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n" -" =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" -"data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" -" =%-22s sunit=%-6u swidth=%u blks\n" -"naming =version %-14u bsize=%-6u ascii-ci=%d\n" -"log =%-22s bsize=%-6d blocks=%lld, version=%d\n" -" =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n" -"realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n" -msgstr "" -"metadane=%-22s isize=%-6d agcount=%lld, agsize=%lld bloków\n" -" =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" -"dane =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" -" =%-22s sunit=%-6u swidth=%u bloków\n" -"nazwy =wersja %-14u bsize=%-6u ascii-ci=%d\n" -"log =%-22s bsize=%-6d blocks=%lld, wersja=%d\n" -" =%-22s sectsz=%-5u sunit=%d bloków, lazy-count=%d\n" -"realtime=%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n" +msgid "\t\tver:%d " +msgstr "\t\twersja:%d " -#: .././mkfs/xfs_mkfs.c:2451 +#: .././logprint/log_print_all.c:128 #, c-format -msgid "%s: Growing the data section failed\n" -msgstr "%s: Powiększenie sekcji danych nie powiodło się\n" +msgid "seq#:%d len:%d cnt:%d root:%d\n" +msgstr "seq#:%d len:%d cnt:%d root:%d\n" -#: .././mkfs/xfs_mkfs.c:2481 +#: .././logprint/log_print_all.c:133 #, c-format -msgid "%s: filesystem failed to initialize\n" -msgstr "%s: nie udało się zainicjować systemu plików\n" +msgid "\t\tlevel:%d free#:0x%x newino:0x%x\n" +msgstr "\t\tlevel:%d free#:0x%x newino:0x%x\n" -#: .././mkfs/xfs_mkfs.c:2693 +#: .././logprint/log_print_all.c:157 #, c-format -msgid "%s: root inode created in AG %u, not AG 0\n" -msgstr "%s: główny i-węzeł utworzony w AG %u, nie AG 0\n" +msgid "\tAGF Buffer: (XAGF)\n" +msgstr "\tBufor AGI: (XAGF)\n" -#: .././mkfs/xfs_mkfs.c:2760 +#: .././logprint/log_print_all.c:160 #, c-format -msgid "Cannot specify both -%c %s and -%c %s\n" -msgstr "Nie można podać jednocześnie -%c %s i %c %s\n" +msgid "\t\tver:%d seq#:%d len:%d \n" +msgstr "\t\tver:%d seq#:%d len:%d \n" -#: .././mkfs/xfs_mkfs.c:2771 +#: .././logprint/log_print_all.c:164 #, c-format -msgid "Illegal value %s for -%s option\n" -msgstr "Niedozwolona wartość %s dla opcji -%s\n" +msgid "\t\troot BNO:%d CNT:%d\n" +msgstr "\t\troot BNO:%d CNT:%d\n" -#: .././mkfs/xfs_mkfs.c:2788 +#: .././logprint/log_print_all.c:167 #, c-format -msgid "-%c %s option requires a value\n" -msgstr "Opcja -%c %s wymaga wartości\n" +msgid "\t\tlevel BNO:%d CNT:%d\n" +msgstr "\t\tlevel BNO:%d CNT:%d\n" -#: .././mkfs/xfs_mkfs.c:2849 +#: .././logprint/log_print_all.c:170 #, c-format -msgid "blocksize not available yet.\n" -msgstr "rozmiar bloku jeszcze nie dostępny.\n" +msgid "\t\t1st:%d last:%d cnt:%d freeblks:%d longest:%d\n" +msgstr "\t\t1st:%d last:%d cnt:%d freeblks:%d longest:%d\n" -#: .././mkfs/xfs_mkfs.c:2875 +#: .././logprint/log_print_all.c:179 #, c-format -msgid "" -"Usage: %s\n" -"/* blocksize */\t\t[-b log=n|size=num]\n" -"/* data subvol */\t[-d agcount=n,agsize=n,file,name=xxx,size=num,\n" -"\t\t\t (sunit=value,swidth=value|su=num,sw=num),\n" -"\t\t\t sectlog=n|sectsize=num\n" -"/* inode size */\t[-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,\n" -"\t\t\t projid32bit=0|1]\n" -"/* log subvol */\t[-l agnum=n,internal,size=num,logdev=xxx,version=n\n" -"\t\t\t sunit=value|su=num,sectlog=n|sectsize=num,\n" -"\t\t\t lazy-count=0|1]\n" -"/* label */\t\t[-L label (maximum 12 characters)]\n" -"/* naming */\t\t[-n log=n|size=num,version=2|ci]\n" -"/* prototype file */\t[-p fname]\n" -"/* quiet */\t\t[-q]\n" -"/* realtime subvol */\t[-r extsize=num,size=num,rtdev=xxx]\n" -"/* sectorsize */\t[-s log=n|size=num]\n" -"/* version */\t\t[-V]\n" -"\t\t\tdevicename\n" -" is required unless -d name=xxx is given.\n" -" is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),\n" -" xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).\n" -" is xxx (512 byte blocks).\n" -msgstr "" -"Składnia: %s\n" -"/* rozmiar bloku */ [-b log=n|size=liczba]\n" -"/* podwolumen danych */ [-d agcount=n,agsize=n,file,name=xxx,size=liczba,\n" -" (sunit=wartość,swidth=wartość|su=liczba,sw=liczba),\n" -" sectlog=n|sectsize=liczba]\n" -"/* rozmiar i-węzła */ [-i log=n|perblock=n|size=liczba,maxpct=n,attr=0|1|2,\n" -" projid32bit=0|1]\n" -"/* podwolumen logu */ [-l agnum=n,internal,size=liczba,logdev=xxx,version=n\n" -" sunit=wartość|su=liczba,sectlog=n|sectsize=liczba,\n" -" lazy-count=0|1]\n" -"/* etykieta */ [-L etykieta (maksymalnie 12 znaków)]\n" -"/* nazwy */ [-n log=n|size=liczba,wersja=2|ci]\n" -"/* plik prototypu */ [-p nazwa_pliku]\n" -"/* cisza */ [-q]\n" -"/* podwolumen rt */ [-r extsize=liczba,size=liczba,rtdev=xxx]\n" -"/* rozmiar sektora */ [-s log=n|size=liczba]\n" -"/* wersja */ [-V]\n" -" nazwa_urządzenia\n" -" jest wymagana, chyba że podano -d name=xxx.\n" -" to xxx (bajtów), xxxs (sektorów), xxxb (bloków systemu plików),\n" -" xxxk (xxx KiB), xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB),\n" -" xxxp (xxx PiB).\n" -" to xxx (512-bajtowych bloków).\n" +msgid "\tDQUOT Buffer:\n" +msgstr "\tBufor DQUOT:\n" -#: .././logprint/log_copy.c:44 .././logprint/log_dump.c:43 +#: .././logprint/log_print_all.c:182 #, c-format -msgid "%s: read error (%lld): %s\n" -msgstr "%s: błąd odczytu (%lld): %s\n" +msgid "\t\tUIDs 0x%lx-0x%lx\n" +msgstr "\t\tUIDs 0x%lx-0x%lx\n" -#: .././logprint/log_copy.c:49 .././logprint/log_dump.c:48 +#: .././logprint/log_print_all.c:187 #, c-format -msgid "%s: physical end of log at %lld\n" -msgstr "%s: fizyczny koniec logu na %lld\n" +msgid "\tBUF DATA\n" +msgstr "\tDANE BUF\n" -#: .././logprint/log_copy.c:53 +#: .././logprint/log_print_all.c:209 #, c-format -msgid "%s: short read? (%lld)\n" -msgstr "%s: skrócony odczyt? (%lld)\n" +msgid "\tQUOTAOFF: #regs:%d type:%s\n" +msgstr "\tQUOTAOFF: #regs:%d type:%s\n" -#: .././logprint/log_copy.c:60 +#: .././logprint/log_print_all.c:224 #, c-format -msgid "%s: write error (%lld): %s\n" -msgstr "%s: błąd zapisu (%lld): %s\n" +msgid "\tDQUOT: #regs:%d blkno:%lld boffset:%u id: %d\n" +msgstr "\tDQUOT: #regs:%d blkno:%lld boffset:%u id: %d\n" -#: .././logprint/log_copy.c:65 +#: .././logprint/log_print_all.c:228 #, c-format -msgid "%s: short write? (%lld)\n" -msgstr "%s: skrócony zapis? (%lld)\n" +msgid "\t\tmagic 0x%x\tversion 0x%x\tID 0x%x (%d)\t\n" +msgstr "\t\tmagic 0x%x\twersja 0x%x\tID 0x%x (%d)\t\n" -#: .././logprint/log_dump.c:56 +#: .././logprint/log_print_all.c:233 #, c-format -msgid "%6lld HEADER Cycle %d tail %d:%06d len %6d ops %d\n" -msgstr "%6lld NAGŁÓWEK Cykl %d koniec %d:%06d len %6d ops %d\n" +msgid "\t\tblk_hard 0x%x\tblk_soft 0x%x\tino_hard 0x%x\tino_soft 0x%x\n" +msgstr "\t\tblk_hard 0x%x\tblk_soft 0x%x\tino_hard 0x%x\tino_soft 0x%x\n" -#: .././logprint/log_dump.c:67 +#: .././logprint/log_print_all.c:239 #, c-format -msgid "[%05lld - %05lld] Cycle 0x%08x New Cycle 0x%08x\n" -msgstr "[%05lld - %05lld] Cykl 0x%08x Nowy cykl 0x%08x\n" +msgid "\t\tbcount 0x%x (%d) icount 0x%x (%d)\n" +msgstr "\t\tbcount 0x%x (%d) icount 0x%x (%d)\n" -#: .././logprint/logprint.c:42 +#: .././logprint/log_print_all.c:244 #, c-format -msgid "" -"Usage: %s [options...] \n" -"\n" -"Options:\n" -" -c\t try to continue if error found in log\n" -" -C copy the log from the filesystem to filename\n" -" -d\t dump the log in log-record format\n" -" -f\t specified device is actually a file\n" -" -l filename of external log\n" -" -n\t don't try and interpret log data\n" -" -o\t print buffer data in hex\n" -" -s block # to start printing\n" -" -v print \"overwrite\" data\n" -" -t\t print out transactional view\n" -"\t-b in transactional view, extract buffer info\n" -"\t-i in transactional view, extract inode info\n" -"\t-q in transactional view, extract quota info\n" +msgid "\t\tbtimer 0x%x itimer 0x%x \n" +msgstr "\t\tbtimer 0x%x itimer 0x%x \n" + +#: .././logprint/log_print_all.c:253 +#, c-format +msgid "\tCORE inode:\n" +msgstr "\tGŁÓWNY i-węzeł:\n" + +#: .././logprint/log_print_all.c:256 +#, c-format +msgid "\t\tmagic:%c%c mode:0x%x ver:%d format:%d onlink:%d\n" +msgstr "\t\tmagic:%c%c mode:0x%x ver:%d format:%d onlin:%d\n" + +#: .././logprint/log_print_all.c:260 +#, c-format +msgid "\t\tuid:%d gid:%d nlink:%d projid:%u\n" +msgstr "\t\tuid:%d gid:%d nlink:%d projid:%u\n" + +#: .././logprint/log_print_all.c:262 +#, c-format +msgid "\t\tatime:%d mtime:%d ctime:%d\n" +msgstr "\t\tatime:%d mtime:%d ctime:%d\n" + +#: .././logprint/log_print_all.c:264 +#, c-format +msgid "\t\tflushiter:%d\n" +msgstr "\t\tflushiter:%d\n" + +#: .././logprint/log_print_all.c:265 +#, c-format +msgid "\t\tsize:0x%llx nblks:0x%llx exsize:%d nextents:%d anextents:%d\n" +msgstr "\t\tsize:0x%llx nblks:0x%llx exsize:%d nextents:%d anextents:%d\n" + +#: .././logprint/log_print_all.c:269 +#, c-format +msgid "\t\tforkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x gen:%d\n" +msgstr "\t\tforkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x gen:%d\n" + +#: .././logprint/log_print_all.c:289 +#, c-format +msgid "\tINODE: #regs:%d ino:0x%llx flags:0x%x dsize:%d\n" +msgstr "\tINODE: #regs:%d ino:0x%llx flags:0x%x dsize:%d\n" + +#: .././logprint/log_print_all.c:305 +#, c-format +msgid "\t\tDATA FORK EXTENTS inode data:\n" +msgstr "\t\tDane EKSTENTÓW GAŁĘZI DANYCH i-węzła:\n" + +#: .././logprint/log_print_all.c:312 +#, c-format +msgid "\t\tDATA FORK BTREE inode data:\n" +msgstr "\t\tDane B-DRZEWA GAŁĘZI DANYCH i-węzła:\n" + +#: .././logprint/log_print_all.c:319 +#, c-format +msgid "\t\tDATA FORK LOCAL inode data:\n" +msgstr "\t\tDane LOKALNE GAŁĘZI DANYCH i-węzła:\n" + +#: .././logprint/log_print_all.c:326 +#, c-format +msgid "\t\tDEV inode: no extra region\n" +msgstr "\t\tI-węzeł DEV: brak dodatkowego regionu\n" + +#: .././logprint/log_print_all.c:330 +#, c-format +msgid "\t\tUUID inode: no extra region\n" +msgstr "\t\tI-węzeł UUID: brak dodatkowego regionu\n" + +#: .././logprint/log_print_all.c:345 +#, c-format +msgid "\t\tATTR FORK EXTENTS inode data:\n" +msgstr "\t\tDane EKSTENTÓW GAŁĘZI ATRYBUTÓW i-węzła:\n" + +#: .././logprint/log_print_all.c:353 +#, c-format +msgid "\t\tATTR FORK BTREE inode data:\n" +msgstr "\t\tDane B-DRZEWA GAŁĘZI ATRYBUTÓW i-węzła:\n" + +#: .././logprint/log_print_all.c:361 +#, c-format +msgid "\t\tATTR FORK LOCAL inode data:\n" +msgstr "\t\tDane LOKALNE GAŁĘZI ATRYBUTÓW i-węzła:\n" + +#: .././logprint/log_print_all.c:386 +#, c-format +msgid "\tEFD: #regs: %d num_extents: %d id: 0x%llx\n" +msgstr "\tEFD: #regs: %d num_extents: %d id: 0x%llx\n" + +#: .././logprint/log_print_all.c:410 +#, c-format +msgid "%s: xlog_recover_print_efi: malloc failed\n" +msgstr "%s: xlog_recover_print_efi: malloc nie powiodło się\n" + +#: .././logprint/log_print_all.c:418 +#, c-format +msgid "\tEFI: #regs:%d num_extents:%d id:0x%llx\n" +msgstr "\tEFI: #regs:%d num_extents:%d id:0x%llx\n" + +#: .././logprint/log_print_all.c:442 +#, c-format +msgid "" +"\tICR: #ag: %d agbno: 0x%x len: %d\n" +"\t cnt: %d isize: %d gen: 0x%x\n" +msgstr "" +"\tICR: #ag: %d agbno: 0x%x len: %d\n" +"\t cnt: %d isize: %d gen: 0x%x\n" + +#: .././logprint/log_print_all.c:476 +#, c-format +msgid "xlog_recover_print_logitem: illegal type\n" +msgstr "xlog_recover_print_logitem: niedozwolony typ\n" + +#: .././logprint/log_print_all.c:510 +#, c-format +msgid "%s: illegal type" +msgstr "%s: niedozwolony typ" + +#: .././logprint/log_print_all.c:518 +#, c-format +msgid ": cnt:%d total:%d " +msgstr ": cnt:%d total:%d " + +#: .././logprint/log_print_all.c:520 +#, c-format +msgid "a:0x%lx len:%d " +msgstr "a:0x%lx len:%d " + +#: .././logprint/log_print_trans.c:25 +#, c-format +msgid "TRANS: tid:0x%x type:%s #items:%d trans:0x%x q:0x%lx\n" +msgstr "TRANS: tid:0x%x typ:%s #elem:%d trans:0x%x q:0x%lx\n" + +#: .././logprint/log_print_trans.c:51 +#, c-format +msgid "%s: failed to find head and tail, error: %d\n" +msgstr "%s: nie udało się odnaleźć początku ani końca, błąd: %d\n" + +#: .././logprint/log_print_trans.c:56 +#, c-format +msgid " log tail: %lld head: %lld state: %s\n" +msgstr " koniec logu: %lld początek: %lld stan: %s\n" + +#: .././logprint/log_print_trans.c:62 +#, c-format +msgid " override tail: %d\n" +msgstr " koniec override: %d\n" + +#: .././logprint/log_print_trans.c:82 +#, c-format +msgid "" +"Superblock has unknown incompatible log features (0x%x) enabled.\n" +"Output may be incomplete or inaccurate. It is recommended that you\n" +"upgrade your xfsprogs installation to match the filesystem features.\n" +msgstr "" +"Superblok ma włączone nieznane, niezgodne opcje logu (0x%x).\n" +"Wyjście może być niekompletne lub niedokładne. Zalecana jest\n" +"aktualizacja zainstalowanej wersji xfsprogs, aby zgadzała się z opcjami\n" +"systemu plików.\n" + +#: .././logprint/log_print_trans.c:90 +#, c-format +msgid "%s: failed in xfs_do_recovery_pass, error: %d\n" +msgstr "%s: xfs_do_recovery_pass nie powiodło się, błąd: %d\n" + +#: .././logprint/logprint.c:42 +#, c-format +msgid "" +"Usage: %s [options...] \n" +"\n" +"Options:\n" +" -c\t try to continue if error found in log\n" +" -C copy the log from the filesystem to filename\n" +" -d\t dump the log in log-record format\n" +" -e\t exit when an error is found in the log\n" +" -f\t specified device is actually a file\n" +" -l filename of external log\n" +" -n\t don't try and interpret log data\n" +" -o\t print buffer data in hex\n" +" -s block # to start printing\n" +" -v print \"overwrite\" data\n" +" -t\t print out transactional view\n" +"\t-b in transactional view, extract buffer info\n" +"\t-i in transactional view, extract inode info\n" +"\t-q in transactional view, extract quota info\n" " -D print only data; no decoding\n" " -V print version information\n" msgstr "" @@ -6630,6 +6924,7 @@ " -c próba kontynuacji w przypadku błędu w logu\n" " -C skopiowanie logu z systemu plików do pliku o podanej nazwie\n" " -d zrzut logu w formacie jego rekordów\n" +" -e zakończenie po napotkaniu błędu w logu\n" " -f podane urządzenie jest plikiem\n" " -l nazwa pliku z logiem zewnętrznym\n" " -n bez prób interpretacji danych logu\n" @@ -6643,17 +6938,17 @@ " -D wypisywanie tylko danych, bez dekodowania\n" " -V wypisanie informacji o wersji\n" -#: .././logprint/logprint.c:75 +#: .././logprint/logprint.c:76 #, c-format msgid " Can't open device %s: %s\n" msgstr " Nie można otworzyć urządzenia %s: %s\n" -#: .././logprint/logprint.c:81 +#: .././logprint/logprint.c:82 #, c-format msgid " read of XFS superblock failed\n" msgstr " odczyt superbloku XFS-a nie powiódł się\n" -#: .././logprint/logprint.c:97 +#: .././logprint/logprint.c:102 #, c-format msgid "" " external log device not specified\n" @@ -6662,32 +6957,32 @@ " Nie podano urządzenia zewnętrznego loga\n" "\n" -#: .././logprint/logprint.c:112 +#: .././logprint/logprint.c:118 #, c-format msgid "Can't open file %s: %s\n" msgstr "Nie można otworzyć pliku %s: %s\n" -#: .././logprint/logprint.c:212 +#: .././logprint/logprint.c:219 #, c-format msgid "xfs_logprint:\n" msgstr "xfs_logprint:\n" -#: .././logprint/logprint.c:220 +#: .././logprint/logprint.c:228 #, c-format msgid " data device: 0x%llx\n" msgstr " urządzenie danych: 0x%llx\n" -#: .././logprint/logprint.c:223 +#: .././logprint/logprint.c:231 #, c-format msgid " log file: \"%s\" " msgstr " plik logu: \"%s\" " -#: .././logprint/logprint.c:225 +#: .././logprint/logprint.c:233 #, c-format msgid " log device: 0x%llx " msgstr " urządzenie logu: 0x%llx " -#: .././logprint/logprint.c:228 +#: .././logprint/logprint.c:236 #, c-format msgid "" "daddr: %lld length: %lld\n" @@ -6696,6508 +6991,6148 @@ "daddr: %lld długość: %lld\n" "\n" -#: .././logprint/log_misc.c:132 +#: .././mkfs/proto.c:60 #, c-format -msgid "Oper (%d): tid: %x len: %d clientid: %s " -msgstr "Operacja (%d): tid: %x len: %d clientid: %s " +msgid "%s: failed to open %s: %s\n" +msgstr "%s: nie udało się otworzyć %s: %s\n" -#: .././logprint/log_misc.c:137 +#: .././mkfs/proto.c:67 .././mkfs/proto.c:300 #, c-format -msgid "flags: " -msgstr "flagi: " +msgid "%s: read failed on %s: %s\n" +msgstr "%s: odczyt nie powiódł się dla %s: %s\n" -#: .././logprint/log_misc.c:231 +#: .././mkfs/proto.c:72 #, c-format -msgid " Not enough data to decode further\n" -msgstr " Za mało danych do dalszego dekodowania\n" +msgid "%s: proto file %s premature EOF\n" +msgstr "%s: plik prototypu %s skończył się przedwcześnie\n" -#: .././logprint/log_misc.c:235 -#, c-format -msgid " type: %s tid: %x num_items: %d\n" -msgstr " typ: %s tid: %x num_items: %d\n" +#: .././mkfs/proto.c:116 +msgid "cannot reserve space" +msgstr "nie można zarezerwować miejsca" -#: .././logprint/log_misc.c:277 +#: .././mkfs/proto.c:171 #, c-format -msgid "#regs: %d start blkno: %lld (0x%llx) len: %d bmap size: %d flags: 0x%x\n" -msgstr "#regs: %d start blkno: %lld (0x%llx) len: %d bmap size: %d flags: 0x%x\n" +msgid "%s: premature EOF in prototype file\n" +msgstr "%s: przedwczesny EOF w pliku prototypu\n" -#: .././logprint/log_misc.c:283 -#, c-format -msgid "#regs: %d Not printing rest of data\n" -msgstr "#regs: %d Bez wypisywania reszty danych\n" +#: .././mkfs/proto.c:190 +msgid "error reserving space for a file" +msgstr "błąd podczas rezerwowania miejsca na plik" -#: .././logprint/log_misc.c:300 -#, c-format -msgid "SUPER BLOCK Buffer: " -msgstr "Bufor SUPER BLOKU: " +#: .././mkfs/proto.c:258 +msgid "error allocating space for a file" +msgstr "błąd podczas przydzielania miejsca na plik" -#: .././logprint/log_misc.c:302 .././logprint/log_misc.c:366 -#: .././logprint/log_misc.c:392 +#: .././mkfs/proto.c:262 #, c-format -msgid "Out of space\n" -msgstr "Brak miejsca na dysku\n" +msgid "%s: cannot allocate space for file\n" +msgstr "%s: nie można przydzielić miejsca na plik\n" -#: .././logprint/log_misc.c:310 -#, c-format -msgid "icount: %llu ifree: %llu " -msgstr "icount: %llu ifree: %llu " +#: .././mkfs/proto.c:327 +msgid "directory createname error" +msgstr "błąd tworzenia nazwy katalogu" -#: .././logprint/log_misc.c:315 -#, c-format -msgid "fdblks: %llu frext: %llu\n" -msgstr "fdblks: %llu frext: %llu\n" +#: .././mkfs/proto.c:341 +msgid "directory create error" +msgstr "błąd tworzenia katalogu" -#: .././logprint/log_misc.c:322 +#: .././mkfs/proto.c:407 .././mkfs/proto.c:419 .././mkfs/proto.c:430 +#: .././mkfs/proto.c:437 #, c-format -msgid "AGI Buffer: XAGI " -msgstr "Bufor AGI: XAGI " +msgid "%s: bad format string %s\n" +msgstr "%s: błędny łańcuch formatujący %s\n" -#: .././logprint/log_misc.c:325 -#, c-format -msgid "out of space\n" -msgstr "brak miejsca na dysku\n" +#: .././mkfs/proto.c:459 .././mkfs/proto.c:499 .././mkfs/proto.c:514 +#: .././mkfs/proto.c:526 .././mkfs/proto.c:538 .././mkfs/proto.c:549 +msgid "Inode allocation failed" +msgstr "Przydzielanie i-węzła nie powiodło się" -#: .././logprint/log_misc.c:328 -#, c-format -msgid "ver: %d " -msgstr "wersja: %d " +#: .././mkfs/proto.c:476 +msgid "Inode pre-allocation failed" +msgstr "Wczesne przydzielanie i-węzła nie powiodło się" -#: .././logprint/log_misc.c:330 -#, c-format -msgid "seq#: %d len: %d cnt: %d root: %d\n" -msgstr "seq#: %d len: %d cnt: %d root: %d\n" +#: .././mkfs/proto.c:486 +msgid "Pre-allocated file creation failed" +msgstr "Tworzenie wcześnie przydzielonego pliku nie powiodło się" -#: .././logprint/log_misc.c:335 -#, c-format -msgid "level: %d free#: 0x%x newino: 0x%x\n" -msgstr "level: %d free#: 0x%x newino: 0x%x\n" +#: .././mkfs/proto.c:568 +msgid "Directory creation failed" +msgstr "Tworzenie katalogu nie powiodło się" -#: .././logprint/log_misc.c:345 -#, c-format -msgid "AGI unlinked data skipped " -msgstr "Pominięto niedowiązane dane AGI " +#: .././mkfs/proto.c:589 +msgid "Unknown format" +msgstr "Nieznany format" -#: .././logprint/log_misc.c:346 -#, c-format -msgid "(CONTINUE set, no space)\n" -msgstr "(KONTYNUACJA, brak miejsca)\n" +#: .././mkfs/proto.c:594 +msgid "Error encountered creating file from prototype file" +msgstr "Wystąpił błąd podczas tworzenia pliku z pliku prototypu" -#: .././logprint/log_misc.c:352 -#, c-format -msgid "bucket[%d - %d]: " -msgstr "kubełek[%d - %d]: " +#: .././mkfs/proto.c:648 +msgid "Realtime bitmap inode allocation failed" +msgstr "Przydzielanie i-węzła bitmapy realtime nie powiodło się" -#: .././logprint/log_misc.c:364 -#, c-format -msgid "AGF Buffer: XAGF " -msgstr "Bufor AGF: XAGF " +#: .././mkfs/proto.c:665 +msgid "Realtime summary inode allocation failed" +msgstr "Tworzenie i-węzła opisu realtime nie powiodło się" -#: .././logprint/log_misc.c:369 -#, c-format -msgid "ver: %d seq#: %d len: %d \n" -msgstr "ver: %d seq#: %d len: %d \n" +#: .././mkfs/proto.c:692 +msgid "Allocation of the realtime bitmap failed" +msgstr "Przydzielenie bitmapy realtime nie powiodło się" -#: .././logprint/log_misc.c:373 -#, c-format -msgid "root BNO: %d CNT: %d\n" -msgstr "root BNO: %d CNT: %d\n" +#: .././mkfs/proto.c:705 +msgid "Completion of the realtime bitmap failed" +msgstr "Uzupełnienie bitmapy realtime nie powiodło się" -#: .././logprint/log_misc.c:376 -#, c-format -msgid "level BNO: %d CNT: %d\n" -msgstr "level BNO: %d CNT: %d\n" +#: .././mkfs/proto.c:728 +msgid "Allocation of the realtime summary failed" +msgstr "Przydzielenie opisu realtime nie powiodło się" -#: .././logprint/log_misc.c:379 -#, c-format -msgid "1st: %d last: %d cnt: %d freeblks: %d longest: %d\n" -msgstr "1st: %d last: %d cnt: %d freeblks: %d longest: %d\n" +#: .././mkfs/proto.c:740 +msgid "Completion of the realtime summary failed" +msgstr "Uzupełnienie opisu realtime nie powiodło się" -#: .././logprint/log_misc.c:389 -#, c-format -msgid "DQUOT Buffer: DQ " -msgstr "Bufor DQUOT: DQ " +#: .././mkfs/proto.c:759 +msgid "Error initializing the realtime space" +msgstr "Błąd podczas inicjalizacji przestrzeni realtime" -#: .././logprint/log_misc.c:396 -#, c-format -msgid "ver: %d flags: 0x%x id: %d \n" -msgstr "ver: %d flags: 0x%x id: %d \n" +#: .././mkfs/proto.c:764 +msgid "Error completing the realtime space" +msgstr "Błąd podczas uzupełniania przestrzeni realtime" -#: .././logprint/log_misc.c:399 +#: .././mkfs/xfs_mkfs.c:230 #, c-format -msgid "blk limits hard: %llu soft: %llu\n" -msgstr "blk limits hard: %llu soft: %llu\n" +msgid "data su/sw must not be used in conjunction with data sunit/swidth\n" +msgstr "su/sw danych nie można użyć w połączeniu z sunit/swidth danych\n" -#: .././logprint/log_misc.c:404 +#: .././mkfs/xfs_mkfs.c:237 #, c-format -msgid "blk count: %llu warns: %d timer: %d\n" -msgstr "blk count: %llu warns: %d timer: %d\n" +msgid "both data sunit and data swidth options must be specified\n" +msgstr "trzeba podać obie opcje sunit i swidth dla danych\n" -#: .././logprint/log_misc.c:408 +#: .././mkfs/xfs_mkfs.c:246 #, c-format -msgid "ino limits hard: %llu soft: %llu\n" -msgstr "ino limits hard: %llu soft: %llu\n" +msgid "data sunit/swidth must not be used in conjunction with data su/sw\n" +msgstr "sunit/swidth danych nie można użyć w połączeniu z su/sw danych\n" -#: .././logprint/log_misc.c:413 +#: .././mkfs/xfs_mkfs.c:253 #, c-format -msgid "ino count: %llu warns: %d timer: %d\n" -msgstr "ino count: %llu warns: %d timer: %d\n" +msgid "both data su and data sw options must be specified\n" +msgstr "trzeba podać obie opcje su i sw dla danych\n" -#: .././logprint/log_misc.c:419 +#: .././mkfs/xfs_mkfs.c:260 #, c-format -msgid "BUF DATA\n" -msgstr "DANE BUFORA\n" +msgid "data su must be a multiple of the sector size (%d)\n" +msgstr "su danych musi być wielokrotnością rozmiaru sektora (%d)\n" -#: .././logprint/log_misc.c:461 +#: .././mkfs/xfs_mkfs.c:271 #, c-format -msgid "EFD: #regs: %d num_extents: %d id: 0x%llx\n" -msgstr "EFD: #regs: %d num_extents: %d id: 0x%llx\n" +msgid "data stripe width (%d) must be a multiple of the data stripe unit (%d)\n" +msgstr "szerokość pasa danych (%d) musi być wielokrotnością jednostki pasa danych (%d)\n" -#: .././logprint/log_misc.c:468 +#: .././mkfs/xfs_mkfs.c:281 #, c-format -msgid "EFD: Not enough data to decode further\n" -msgstr "EFD: Za mało danych do dalszego dekodowania\n" +msgid "log su should not be used in conjunction with log sunit\n" +msgstr "su logu nie powinno być używane w połączeniu z sunit logu\n" -#: .././logprint/log_misc.c:488 .././logprint/log_misc.c:497 +#: .././mkfs/xfs_mkfs.c:290 #, c-format -msgid "%s: xlog_print_trans_efi: malloc failed\n" -msgstr "%s: xlog_print_trans_efi: malloc nie powiodło się\n" +msgid "log sunit should not be used in conjunction with log su\n" +msgstr "sunit logu nie powinno być używane w połączeniu z su logu\n" -#: .././logprint/log_misc.c:505 +#: .././mkfs/xfs_mkfs.c:360 .././mkfs/xfs_mkfs.c:503 #, c-format -msgid "EFI: #regs: %d num_extents: %d id: 0x%llx\n" -msgstr "EFI: #regs: %d num_extents: %d id: 0x%llx\n" +msgid "%s: %s appears to contain an existing filesystem (%s).\n" +msgstr "%s: %s zdaje się zawierać istniejący system plików (%s).\n" -#: .././logprint/log_misc.c:532 +#: .././mkfs/xfs_mkfs.c:364 .././mkfs/xfs_mkfs.c:509 #, c-format -msgid "QOFF: #regs: %d flags: 0x%x\n" -msgstr "QOFF: #regs: %d flags: 0x%x\n" +msgid "%s: %s appears to contain a partition table (%s).\n" +msgstr "%s: %s zdaje się zawierać tablicę partycji (%s).\n" -#: .././logprint/log_misc.c:535 +#: .././mkfs/xfs_mkfs.c:368 #, c-format -msgid "QOFF: Not enough data to decode further\n" -msgstr "QOFF: Za mało danych do dalszego dekodowania\n" +msgid "%s: %s appears to contain something weird according to blkid\n" +msgstr "%s: %s zdaje się zawierać coś dziwnego wg blkid\n" -#: .././logprint/log_misc.c:544 +#: .././mkfs/xfs_mkfs.c:378 #, c-format -msgid "INODE CORE\n" -msgstr "RDZEŃ I-WĘZŁA\n" +msgid "%s: probe of %s failed, cannot detect existing filesystem.\n" +msgstr "%s: test %s nie powiódł się, nie można wykryć istniejącego systemu plików.\n" -#: .././logprint/log_misc.c:545 +#: .././mkfs/xfs_mkfs.c:431 #, c-format -msgid "magic 0x%hx mode 0%ho version %d format %d\n" -msgstr "magic 0x%hx mode 0%ho version %d format %d\n" +msgid "warning: device is not properly aligned %s\n" +msgstr "uwaga: urządzenie nie jest właściwie wyrównane: %s\n" -#: .././logprint/log_misc.c:548 +#: .././mkfs/xfs_mkfs.c:436 #, c-format -msgid "nlink %hd uid %d gid %d\n" -msgstr "nlink %hd uid %d gid %d\n" +msgid "Use -f to force usage of a misaligned device\n" +msgstr "Można użyć -f do wymuszenia użycia źle wyrównanego urządzenia\n" -#: .././logprint/log_misc.c:550 +#: .././mkfs/xfs_mkfs.c:450 #, c-format -msgid "atime 0x%x mtime 0x%x ctime 0x%x\n" -msgstr "atime 0x%x mtime 0x%x ctime 0x%x\n" +msgid "warning: unable to probe device toplology for device %s\n" +msgstr "uwaga: nie udało się odczytać topologii urządzenia %s\n" -#: .././logprint/log_misc.c:552 +#: .././mkfs/xfs_mkfs.c:578 #, c-format -msgid "size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n" -msgstr "size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n" +msgid "log size %lld is not a multiple of the log stripe unit %d\n" +msgstr "rozmiar logu %lld nie jest wielokrotnością jednostki pasa logu %d\n" -#: .././logprint/log_misc.c:555 +#: .././mkfs/xfs_mkfs.c:606 #, c-format -msgid "naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n" -msgstr "naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n" +msgid "Due to stripe alignment, the internal log size (%lld) is too large.\n" +msgstr "Ze względu na wyrównanie do rozmiaru pasa rozmiar wewnętrznego logu (%lld) jest zbyt duży.\n" -#: .././logprint/log_misc.c:558 +#: .././mkfs/xfs_mkfs.c:608 #, c-format -msgid "flags 0x%x gen 0x%x\n" -msgstr "flags 0x%x gen 0x%x\n" +msgid "Must fit within an allocation group.\n" +msgstr "Musi zmieścić się wewnątrz grupy alokacji.\n" -#: .././logprint/log_misc.c:574 +#: .././mkfs/xfs_mkfs.c:619 #, c-format -msgid "SHORTFORM DIRECTORY size %d\n" -msgstr "Rozmiar KATALOGU W POSTACI KRÓTKIEJ %d\n" +msgid "log size %lld blocks too small, minimum size is %d blocks\n" +msgstr "rozmiar logu %lld bloków jest zbyt mały, minimalny rozmiar to %d bloków\n" -#: .././logprint/log_misc.c:580 +#: .././mkfs/xfs_mkfs.c:625 #, c-format -msgid "SHORTFORM DIRECTORY size %d count %d\n" -msgstr "KATALOG W POSTACI KRÓTKIEJ: rozmiar %d liczba %d\n" +msgid "log size %lld blocks too large, maximum size is %lld blocks\n" +msgstr "rozmiar logu %lld bloków jest zbyt duży, maksymalny rozmiar to %lld bloków\n" -#: .././logprint/log_misc.c:583 +#: .././mkfs/xfs_mkfs.c:631 #, c-format -msgid ".. ino 0x%llx\n" -msgstr ".. ino 0x%llx\n" +msgid "log size %lld bytes too large, maximum size is %lld bytes\n" +msgstr "rozmiar logu %lld bajtów jest zbyt duży, maksymalny rozmiar to %lld bajtów\n" -#: .././logprint/log_misc.c:591 +#: .././mkfs/xfs_mkfs.c:739 #, c-format -msgid "%s ino 0x%llx namelen %d\n" -msgstr "%s ino 0x%llx namelen %d\n" +msgid "agsize (%lld blocks) too small, need at least %lld blocks\n" +msgstr "agsize (%lld bloków) zbyt małe, potrzeba co najmniej %lld bloków\n" -#: .././logprint/log_misc.c:623 +#: .././mkfs/xfs_mkfs.c:747 #, c-format -msgid "INODE: " -msgstr "I-WĘZEŁ: " +msgid "agsize (%lld blocks) too big, maximum is %lld blocks\n" +msgstr "agsize (%lld bloków) zbyt duże, maksimum to %lld bloków\n" -#: .././logprint/log_misc.c:624 +#: .././mkfs/xfs_mkfs.c:755 #, c-format -msgid "#regs: %d ino: 0x%llx flags: 0x%x dsize: %d\n" -msgstr "#regs: %d ino: 0x%llx flags: 0x%x dsize: %d\n" +msgid "agsize (%lld blocks) too big, data area is %lld blocks\n" +msgstr "agsize (%lld bloków) zbyt duże, obszar danych to %lld bloków\n" -#: .././logprint/log_misc.c:627 +#: .././mkfs/xfs_mkfs.c:762 #, c-format -msgid " blkno: %lld len: %d boff: %d\n" -msgstr " blkno: %lld len: %d boff: %d\n" +msgid "too many allocation groups for size = %lld\n" +msgstr "zbyt dużo grup alokacji dla rozmiaru = %lld\n" -#: .././logprint/log_misc.c:632 +#: .././mkfs/xfs_mkfs.c:764 #, c-format -msgid "INODE: #regs: %d Not printing rest of data\n" -msgstr "I-WĘZEŁ: #regs: %d Bez wypisywania reszty danych\n" +msgid "need at most %lld allocation groups\n" +msgstr "potrzeba najwyżej %lld grup alokacji\n" -#: .././logprint/log_misc.c:665 +#: .././mkfs/xfs_mkfs.c:772 #, c-format -msgid "EXTENTS inode data\n" -msgstr "EKSTENTY danych i-węzła\n" +msgid "too few allocation groups for size = %lld\n" +msgstr "zbyt mało grup alokacji dla rozmiaru = %lld\n" -#: .././logprint/log_misc.c:676 +#: .././mkfs/xfs_mkfs.c:774 #, c-format -msgid "BTREE inode data\n" -msgstr "B-DRZEWO danych i-węzła\n" +msgid "need at least %lld allocation groups\n" +msgstr "potrzeba co najmniej %lld grup alokacji\n" -#: .././logprint/log_misc.c:687 +#: .././mkfs/xfs_mkfs.c:787 #, c-format -msgid "LOCAL inode data\n" -msgstr "LOKALNE dane i-węzła\n" +msgid "last AG size %lld blocks too small, minimum size is %lld blocks\n" +msgstr "rozmiar ostatniej AG %lld bloków zbyt mały, minimalny rozmiar to %lld bloków\n" -#: .././logprint/log_misc.c:701 +#: .././mkfs/xfs_mkfs.c:798 #, c-format -msgid "EXTENTS inode attr\n" -msgstr "EKSTENTY atrybutów i-węzła\n" +msgid "%lld allocation groups is too many, maximum is %lld\n" +msgstr "%lld grup alokacji to zbyt dużo, maksimum to %lld\n" -#: .././logprint/log_misc.c:712 +#: .././mkfs/xfs_mkfs.c:822 #, c-format -msgid "BTREE inode attr\n" -msgstr "B-DRZEWO atrybutów i-węzła\n" +msgid "error reading existing superblock -- failed to memalign buffer\n" +msgstr "błąd podczas odczytu istniejącego superbloku - nie udało się wykonać memalign dla bufora\n" -#: .././logprint/log_misc.c:723 +#: .././mkfs/xfs_mkfs.c:828 #, c-format -msgid "LOCAL inode attr\n" -msgstr "LOKALNE atrybuty i-węzła\n" +msgid "existing superblock read failed: %s\n" +msgstr "odczyt istniejącego superbloku nie powiódł się: %s\n" -#: .././logprint/log_misc.c:735 +#: .././mkfs/xfs_mkfs.c:1133 #, c-format -msgid "DEV inode: no extra region\n" -msgstr "I-węzeł DEV: brak dodatkowego regionu\n" +msgid "%s: Specify data sunit in 512-byte blocks, no unit suffix\n" +msgstr "%s: sunit danych należy podać w 512-bajtowych blokach, bez jednostki\n" -#: .././logprint/log_misc.c:740 +#: .././mkfs/xfs_mkfs.c:1149 #, c-format -msgid "UUID inode: no extra region\n" -msgstr "I-węzeł UUID: brak dodatkowego regionu\n" - -#: .././logprint/log_misc.c:748 -msgid "xlog_print_trans_inode: illegal inode type" -msgstr "xlog_print_trans_inode: niedozwolony typ i-węzła" +msgid "%s: Specify data swidth in 512-byte blocks, no unit suffix\n" +msgstr "%s: swidth danych należy podać w 512-bajtowych blokach, bez jednostki\n" -#: .././logprint/log_misc.c:776 +#: .././mkfs/xfs_mkfs.c:1176 #, c-format -msgid "#regs: %d id: 0x%x" -msgstr "#regs: %d id: 0x%x" +msgid "%s: Specify data sw as multiple of su, no unit suffix\n" +msgstr "%s: sw danych należy podać jako wielokrotność su, bez jednostki\n" -#: .././logprint/log_misc.c:777 +#: .././mkfs/xfs_mkfs.c:1405 #, c-format -msgid " blkno: %lld len: %d boff: %d\n" -msgstr " blkno: %lld len: %d boff: %d\n" +msgid "Specify log sunit in 512-byte blocks, no size suffix\n" +msgstr "sunit należy podać w 512-bajtowych blokach, bez jednostki\n" -#: .././logprint/log_misc.c:781 +#: .././mkfs/xfs_mkfs.c:1508 .././mkfs/xfs_mkfs.c:1585 #, c-format -msgid "DQUOT: #regs: %d Not printing rest of data\n" -msgstr "DQUOT: #regs: %d Bez wypisywania reszty danych\n" +msgid "cannot specify both crc and ftype\n" +msgstr "nie można podać jednocześnie crc i ftype\n" -#: .././logprint/log_misc.c:800 +#: .././mkfs/xfs_mkfs.c:1710 #, c-format -msgid "DQUOT: magic 0x%hx flags 0%ho\n" -msgstr "DQUOT: magic 0x%hx flags 0%ho\n" +msgid "extra arguments\n" +msgstr "nadmiarowe argumenty\n" -#: .././logprint/log_misc.c:828 +#: .././mkfs/xfs_mkfs.c:1716 #, c-format -msgid "%s: lseek64 to %lld failed: %s\n" -msgstr "%s: lseek64 na %lld nie powiodło się: %s\n" +msgid "cannot specify both %s and -d name=%s\n" +msgstr "nie można podać jednocześnie %s i -d name=%s\n" -#: .././logprint/log_misc.c:871 +#: .././mkfs/xfs_mkfs.c:1733 #, c-format -msgid "%s: xlog_print_record: malloc failed\n" -msgstr "%s: xlog_print_record: malloc nie powiodło się\n" +msgid "illegal block size %d\n" +msgstr "niedozwolony rozmiar bloku %d\n" -#: .././logprint/log_misc.c:880 +#: .././mkfs/xfs_mkfs.c:1768 #, c-format -msgid "%s: xlog_print_record: read error\n" -msgstr "%s: xlog_print_record: błąd odczytu\n" +msgid "specified blocksize %d is less than device physical sector size %d\n" +msgstr "podany rozmiar bloku %d jest mniejszy niż rozmiar fizycznego sektora urządzenia (%d)\n" -#: .././logprint/log_misc.c:967 +#: .././mkfs/xfs_mkfs.c:1771 #, c-format -msgid "Left over region from split log item\n" -msgstr "Region pozostały z podziału elementu logu\n" +msgid "switching to logical sector size %d\n" +msgstr "przełączono na rozmiar sektora logicznego %d\n" -#: .././logprint/log_misc.c:1011 +#: .././mkfs/xfs_mkfs.c:1789 #, c-format -msgid "Unmount filesystem\n" -msgstr "Niezamontowany system plików\n" +msgid "illegal sector size %d\n" +msgstr "niedozwolony rozmiar sektora %d\n" -#: .././logprint/log_misc.c:1016 +#: .././mkfs/xfs_mkfs.c:1792 #, c-format -msgid "%s: unknown log operation type (%x)\n" -msgstr "%s: nieznany typ operacji w logu (%x)\n" +msgid "block size %d cannot be smaller than logical sector size %d\n" +msgstr "rozmiar bloku %d nie może być mniejszy niż rozmiar sektora logicznego %d\n" -#: .././logprint/log_misc.c:1051 +#: .././mkfs/xfs_mkfs.c:1797 #, c-format -msgid "Header 0x%x wanted 0x%x\n" -msgstr "Nagłówek 0x%x, pożądany 0x%x\n" +msgid "illegal sector size %d; hw sector is %d\n" +msgstr "niedozwolony rozmiar sektora %d; sektor sprzętowy ma %d\n" -#: .././logprint/log_misc.c:1065 +#: .././mkfs/xfs_mkfs.c:1803 #, c-format -msgid "cycle: %d\tversion: %d\t" -msgstr "cykl: %d\twersja: %d\t" +msgid "illegal log sector size %d\n" +msgstr "niedozwolony rozmiar sektora logu %d\n" -#: .././logprint/log_misc.c:1071 +#: .././mkfs/xfs_mkfs.c:1819 .././mkfs/xfs_mkfs.c:1924 #, c-format -msgid "length of Log Record: %d\tprev offset: %d\t\tnum ops: %d\n" -msgstr "długość rekordu logu: %d\tpoprz.offset: %d\t\tl.oper.: %d\n" +msgid "Minimum inode size for CRCs is %d bytes\n" +msgstr "Minimalny rozmiar i-węzła dla CRC to %d bajtów\n" -#: .././logprint/log_misc.c:1077 .././logprint/log_misc.c:1119 +#: .././mkfs/xfs_mkfs.c:1827 #, c-format -msgid "cycle num overwrites: " -msgstr "liczba nadpisań cyklu: " +msgid "Inodes always aligned for CRC enabled filesytems\n" +msgstr "I-węzły są zawsze wyrównane dla systemów plików z CRC\n" -#: .././logprint/log_misc.c:1086 +#: .././mkfs/xfs_mkfs.c:1834 #, c-format -msgid "uuid: %s format: " -msgstr "uuid: %s format: " +msgid "Lazy superblock counted always enabled for CRC enabled filesytems\n" +msgstr "Leniwe liczenie syperbloków jest zawsze włączone dla systemów plików z CRC\n" -#: .././logprint/log_misc.c:1089 +#: .././mkfs/xfs_mkfs.c:1841 #, c-format -msgid "unknown\n" -msgstr "nieznany\n" +msgid "V2 logs always enabled for CRC enabled filesytems\n" +msgstr "Logi V2 są zawsze włączone dla systemów plików z CRC\n" -#: .././logprint/log_misc.c:1092 +#: .././mkfs/xfs_mkfs.c:1848 #, c-format -msgid "little endian linux\n" -msgstr "Linux little endian\n" +msgid "V2 attribute format always enabled on CRC enabled filesytems\n" +msgstr "Format atrybutów V2 jest zawsze włączony dla systemów plików z CRC\n" -#: .././logprint/log_misc.c:1095 +#: .././mkfs/xfs_mkfs.c:1856 #, c-format -msgid "big endian linux\n" -msgstr "Linux big endian\n" +msgid "32 bit Project IDs always enabled on CRC enabled filesytems\n" +msgstr "32-bitowe ID projektów są zawsze włączone dla systemów plików z CRC\n" -#: .././logprint/log_misc.c:1098 +#: .././mkfs/xfs_mkfs.c:1867 #, c-format -msgid "big endian irix\n" -msgstr "IRIX big endian\n" +msgid "warning: finobt not supported without CRC support, disabled.\n" +msgstr "uwaga: finobt nie jest obsługiwane bez obsługi CRC, wyłączono.\n" -#: .././logprint/log_misc.c:1104 +#: .././mkfs/xfs_mkfs.c:1874 #, c-format -msgid "h_size: %d\n" -msgstr "h_size: %d\n" +msgid "illegal directory block size %d\n" +msgstr "niedozwolony rozmiar bloku katalogu %d\n" -#: .././logprint/log_misc.c:1116 +#: .././mkfs/xfs_mkfs.c:1888 #, c-format -msgid "extended-header: cycle: %d\n" -msgstr "nagłówek-rozszerzony: cykl: %d\n" +msgid "both -d agcount= and agsize= specified, use one or the other\n" +msgstr "podano jednocześnie -d agcount= i agsize=, można użyć tylko jednej z tych opcji\n" -#: .././logprint/log_misc.c:1132 +#: .././mkfs/xfs_mkfs.c:1894 #, c-format -msgid "* ERROR: found data after zeroed blocks block=%-21lld *\n" -msgstr "* BŁĄD: znaleziono dane za wyzerowanymi blokami blok=%-21lld *\n" +msgid "if -d file then -d name and -d size are required\n" +msgstr "jeśli podano -d file, to -d name i -d size są wymagane\n" -#: .././logprint/log_misc.c:1143 +#: .././mkfs/xfs_mkfs.c:1903 #, c-format -msgid "* ERROR: header cycle=%-11d block=%-21lld *\n" -msgstr "* BŁĄD: nagłówek cykl=%-11d blok=%-21lld *\n" +msgid "illegal data length %lld, not a multiple of %d\n" +msgstr "niedozwolona długość danych %lld, nie jest wielokrotnością %d\n" -#: .././logprint/log_misc.c:1154 +#: .././mkfs/xfs_mkfs.c:1909 #, c-format -msgid "* ERROR: data block=%-21lld *\n" -msgstr "* BŁĄD: blok danych=%-21lld *\n" +msgid "warning: data length %lld not a multiple of %d, truncated to %lld\n" +msgstr "uwaga: długość danych %lld nie jest wielokrotnością %d, ucięto do %lld\n" -#: .././logprint/log_misc.c:1165 +#: .././mkfs/xfs_mkfs.c:1931 #, c-format -msgid "" -"* ERROR: for header block=%lld\n" -"* not enough hdrs for data length, required num = %d, hdr num = %d\n" -msgstr "" -"* BŁĄD: dla bloku nagłówka %lld\n" -"* za mało nagłówków dla długości danych, wymaganych = %d, liczba = %d\n" - -#: .././logprint/log_misc.c:1171 -msgid "Not enough headers for data length." -msgstr "Za mało nagłówków dla długości danych." +msgid "if -l file then -l name and -l size are required\n" +msgstr "jeśli podano -l file to -l name i -l size są wymagane\n" -#: .././logprint/log_misc.c:1181 +#: .././mkfs/xfs_mkfs.c:1940 #, c-format -msgid "%s: xlog_print: malloc failed for ext hdrs\n" -msgstr "%s: xlog_print: malloc dla rozszerzonych nagłówków nie powiódł się\n" +msgid "illegal log length %lld, not a multiple of %d\n" +msgstr "niedozwolona długość logu %lld, nie jest wielokrotnością %d\n" -#: .././logprint/log_misc.c:1227 .././logprint/log_misc.c:1302 -#: .././logprint/log_misc.c:1368 .././logprint/log_misc.c:1405 +#: .././mkfs/xfs_mkfs.c:1947 #, c-format -msgid "%s: physical end of log\n" -msgstr "%s: fizyczny koniec logu\n" +msgid "warning: log length %lld not a multiple of %d, truncated to %lld\n" +msgstr "uwaga: długość logu %lld nie jest wielokrotnością %d, ucięto do %lld\n" -#: .././logprint/log_misc.c:1233 .././logprint/log_misc.c:1307 -#: .././logprint/log_misc.c:1420 +#: .././mkfs/xfs_mkfs.c:1953 #, c-format -msgid "BLKNO: %lld\n" -msgstr "BLKNO: %lld\n" +msgid "if -r file then -r name and -r size are required\n" +msgstr "jeśli podano -r file, to -r name i -r size są wymagane\n" -#: .././logprint/log_misc.c:1290 +#: .././mkfs/xfs_mkfs.c:1962 #, c-format -msgid "%s: problem finding oldest LR\n" -msgstr "%s: problem ze znalezieniem najstarszego rekordu logu\n" +msgid "illegal rt length %lld, not a multiple of %d\n" +msgstr "niedozwolona długość rt %lld, nie jest wielokrotnością %d\n" -#: .././logprint/log_misc.c:1316 +#: .././mkfs/xfs_mkfs.c:1969 #, c-format -msgid "%s: after %d zeroed blocks\n" -msgstr "%s: po %d wyzerowanych blokach\n" - -#: .././logprint/log_misc.c:1380 -msgid "illegal value" -msgstr "niedozwolona wartość" +msgid "warning: rt length %lld not a multiple of %d, truncated to %lld\n" +msgstr "uwaga: długość rt %lld nie jest wielokrotnością %d, ucięto do %lld\n" -#: .././logprint/log_misc.c:1386 +#: .././mkfs/xfs_mkfs.c:1982 #, c-format -msgid "%s: skipped %d cleared blocks in range: %lld - %lld\n" -msgstr "%s: pominięto %d wyzerowanych bloków w przedziale: %lld - %lld\n" +msgid "illegal rt extent size %lld, not a multiple of %d\n" +msgstr "niedozwolony rozmiar ekstentu rt %lld, nie jest wielokrotnością %d\n" -#: .././logprint/log_misc.c:1391 +#: .././mkfs/xfs_mkfs.c:1988 #, c-format -msgid "%s: totally cleared log\n" -msgstr "%s: całkowicie wyczyszczony log\n" +msgid "rt extent size %s too large, maximum %d\n" +msgstr "rozmiar ekstentu rt %s zbyt duży, maksimum to %d\n" -#: .././logprint/log_misc.c:1396 +#: .././mkfs/xfs_mkfs.c:1994 #, c-format -msgid "%s: skipped %d zeroed blocks in range: %lld - %lld\n" -msgstr "%s: pominięto %d wyzerowanych bloków w przedziale %lld - %lld\n" +msgid "rt extent size %s too small, minimum %d\n" +msgstr "rozmiar ekstentu rt %s zbyt mały, minimum to %d\n" -#: .././logprint/log_misc.c:1401 +#: .././mkfs/xfs_mkfs.c:2037 #, c-format -msgid "%s: totally zeroed log\n" -msgstr "%s: całkowicie wyzerowany log\n" - -#: .././logprint/log_misc.c:1417 -msgid "xlog_find_head: bad read" -msgstr "xlog_find_head: błędny odczyt" +msgid "illegal inode size %d\n" +msgstr "niedozwolony rozmiar i-węzła %d\n" -#: .././logprint/log_misc.c:1473 +#: .././mkfs/xfs_mkfs.c:2042 #, c-format -msgid "%s: logical end of log\n" -msgstr "%s: logiczny koniec logu\n" +msgid "allowable inode size with %d byte blocks is %d\n" +msgstr "dozwolony rozmiar i-węzła przy blokach %d-bajtowych to %d\n" -#: .././logprint/log_misc.c:1565 +#: .././mkfs/xfs_mkfs.c:2046 #, c-format -msgid "%s: bad size of efi format: %u; expected %u or %u; nextents = %u\n" -msgstr "%s: błędny rozmiar formatu efi: %u; oczekiwano %u lub %u; nextents = %u\n" +msgid "allowable inode size with %d byte blocks is between %d and %d\n" +msgstr "dozwolone rozmiary i-węzła przy blokach %d-bajtowych są od %d do %d\n" -#: .././logprint/log_print_trans.c:25 +#: .././mkfs/xfs_mkfs.c:2054 #, c-format -msgid "TRANS: tid:0x%x type:%s #items:%d trans:0x%x q:0x%lx\n" -msgstr "TRANS: tid:0x%x typ:%s #elem:%d trans:0x%x q:0x%lx\n" +msgid "log stripe unit specified, using v2 logs\n" +msgstr "podano jednostkę pasa logu, użyto logów v2\n" -#: .././logprint/log_print_trans.c:51 +#: .././mkfs/xfs_mkfs.c:2069 #, c-format -msgid "%s: failed to find head and tail, error: %d\n" -msgstr "%s: nie udało się odnaleźć początku ani końca, błąd: %d\n" +msgid "no device name given in argument list\n" +msgstr "nie podano nazwy urządzenia w liście argumentów\n" -#: .././logprint/log_print_trans.c:56 +#: .././mkfs/xfs_mkfs.c:2094 #, c-format -msgid " log tail: %lld head: %lld state: %s\n" -msgstr " koniec logu: %lld początek: %lld stan: %s\n" +msgid "%s: Use the -f option to force overwrite.\n" +msgstr "%s: Można użyć opcji -f do wymuszenia nadpisania.\n" -#: .././logprint/log_print_trans.c:62 -#, c-format -msgid " override tail: %d\n" -msgstr " koniec override: %d\n" +#: .././mkfs/xfs_mkfs.c:2113 +msgid "internal log" +msgstr "log wewnętrzny" -#: .././logprint/log_print_trans.c:72 -#, c-format -msgid "%s: failed in xfs_do_recovery_pass, error: %d\n" -msgstr "%s: xfs_do_recovery_pass nie powiodło się, błąd: %d\n" +#: .././mkfs/xfs_mkfs.c:2115 +msgid "volume log" +msgstr "log na wolumenie" -#: .././logprint/log_print_all.c:98 +#: .././mkfs/xfs_mkfs.c:2117 #, c-format -msgid "BUF: #regs:%d start blkno:0x%llx len:%d bmap size:%d flags:0x%x\n" -msgstr "BUF: #regs:%d blok pocz.:0x%llx dług.:%d rozm.bmapy:%d flagi:0x%x\n" +msgid "no log subvolume or internal log\n" +msgstr "brak podwolumenu logu ani logu wewnętrznego\n" -#: .././logprint/log_print_all.c:108 -#, c-format -msgid "\tSUPER Block Buffer:\n" -msgstr "\tBufor SUPER bloku:\n" +#: .././mkfs/xfs_mkfs.c:2124 +msgid "volume rt" +msgstr "wolumen rt" -#: .././logprint/log_print_all.c:111 +#: .././mkfs/xfs_mkfs.c:2129 #, c-format -msgid " icount:%llu ifree:%llu " -msgstr " icount:%llu ifree:%llu " +msgid "size %s specified for data subvolume is too large, maximum is %lld blocks\n" +msgstr "rozmiar %s podany dla podwolumenu danych jest zbyt duży, maksimum to %lld bloków\n" -#: .././logprint/log_print_all.c:116 +#: .././mkfs/xfs_mkfs.c:2136 #, c-format -msgid "fdblks:%llu frext:%llu\n" -msgstr "fdblks:%llu frext:%llu\n" +msgid "can't get size of data subvolume\n" +msgstr "nie można pobrać rozmiaru podwolumenu danych\n" -#: .././logprint/log_print_all.c:121 +#: .././mkfs/xfs_mkfs.c:2141 #, c-format -msgid "\t\tsunit:%u swidth:%u\n" -msgstr "\t\tsunit:%u swidth:%u\n" +msgid "size %lld of data subvolume is too small, minimum %d blocks\n" +msgstr "rozmiar %lld dla podwolumenu danych jest zbyt mały, minimum to %d bloków\n" -#: .././logprint/log_print_all.c:126 +#: .././mkfs/xfs_mkfs.c:2148 #, c-format -msgid "\tAGI Buffer: (XAGI)\n" -msgstr "\tBufor AGI: (XAGI)\n" +msgid "can't have both external and internal logs\n" +msgstr "nie można mieć jednocześnie zewnętrznego i wewnętrznego logu\n" -#: .././logprint/log_print_all.c:129 +#: .././mkfs/xfs_mkfs.c:2152 #, c-format -msgid "\t\tver:%d " -msgstr "\t\twersja:%d " +msgid "data and log sector sizes must be equal for internal logs\n" +msgstr "rozmiary sektora danych i logu muszą być równe dla logów wewnętrznych\n" -#: .././logprint/log_print_all.c:131 +#: .././mkfs/xfs_mkfs.c:2158 #, c-format -msgid "seq#:%d len:%d cnt:%d root:%d\n" -msgstr "seq#:%d len:%d cnt:%d root:%d\n" +msgid "" +"Warning: the data subvolume sector size %u is less than the sector size \n" +"reported by the device (%u).\n" +msgstr "" +"Uwaga: rozmiar sektora podwolumenu danych %u jest mniejszy od rozmiaru\n" +"sektora zgłaszanego przez urządzenie (%u).\n" -#: .././logprint/log_print_all.c:136 +#: .././mkfs/xfs_mkfs.c:2164 #, c-format -msgid "\t\tlevel:%d free#:0x%x newino:0x%x\n" -msgstr "\t\tlevel:%d free#:0x%x newino:0x%x\n" +msgid "" +"Warning: the log subvolume sector size %u is less than the sector size\n" +"reported by the device (%u).\n" +msgstr "" +"Uwaga: rozmiar sektora podwolumenu logu %u jest mniejszy od rozmiaru\n" +"sektora zgłaszanego przez urządzenie (%u).\n" -#: .././logprint/log_print_all.c:142 +#: .././mkfs/xfs_mkfs.c:2170 #, c-format -msgid "\tAGF Buffer: (XAGF)\n" -msgstr "\tBufor AGI: (XAGF)\n" +msgid "" +"Warning: the realtime subvolume sector size %u is less than the sector size\n" +"reported by the device (%u).\n" +msgstr "" +"Uwaga: rozmiar sektora podwolumenu realtime %u jest mniejszy od rozmiaru\n" +"sektora zgłaszanego przez urządzenie (%u).\n" -#: .././logprint/log_print_all.c:145 +#: .././mkfs/xfs_mkfs.c:2177 #, c-format -msgid "\t\tver:%d seq#:%d len:%d \n" -msgstr "\t\tver:%d seq#:%d len:%d \n" +msgid "size %s specified for rt subvolume is too large, maximum is %lld blocks\n" +msgstr "rozmiar %s podany dla podwolumenu rt jest zbyt duży, maksimum to %lld bloków\n" -#: .././logprint/log_print_all.c:149 +#: .././mkfs/xfs_mkfs.c:2185 #, c-format -msgid "\t\troot BNO:%d CNT:%d\n" -msgstr "\t\troot BNO:%d CNT:%d\n" +msgid "size specified for non-existent rt subvolume\n" +msgstr "podano rozmiar dla nie istniejącego podwolumenu rt\n" -#: .././logprint/log_print_all.c:152 +#: .././mkfs/xfs_mkfs.c:2200 #, c-format -msgid "\t\tlevel BNO:%d CNT:%d\n" -msgstr "\t\tlevel BNO:%d CNT:%d\n" +msgid "%s: Specified data stripe unit %d is not the same as the volume stripe unit %d\n" +msgstr "%s: Podana jednostka pasa danych %d nie jest taka sama jak jednostka pasa wolumenu %d\n" -#: .././logprint/log_print_all.c:155 +#: .././mkfs/xfs_mkfs.c:2207 #, c-format -msgid "\t\t1st:%d last:%d cnt:%d freeblks:%d longest:%d\n" -msgstr "\t\t1st:%d last:%d cnt:%d freeblks:%d longest:%d\n" +msgid "%s: Specified data stripe width %d is not the same as the volume stripe width %d\n" +msgstr "%s: Podana szerokość pasa danych %d nie jest taka sama jak szerokość pasa wolumenu %d\n" -#: .././logprint/log_print_all.c:164 +#: .././mkfs/xfs_mkfs.c:2225 #, c-format -msgid "\tDQUOT Buffer:\n" -msgstr "\tBufor DQUOT:\n" +msgid "agsize (%lld) not a multiple of fs blk size (%d)\n" +msgstr "agsize (%lld) nie jest wielokrotnością rozmiaru bloku systemu plików (%d)\n" -#: .././logprint/log_print_all.c:167 +#: .././mkfs/xfs_mkfs.c:2275 #, c-format -msgid "\t\tUIDs 0x%lx-0x%lx\n" -msgstr "\t\tUIDs 0x%lx-0x%lx\n" +msgid "agsize rounded to %lld, swidth = %d\n" +msgstr "agsize zaokrąglone do %lld, swidth = %d\n" -#: .././logprint/log_print_all.c:172 +#: .././mkfs/xfs_mkfs.c:2307 #, c-format -msgid "\tBUF DATA\n" -msgstr "\tDANE BUF\n" +msgid "" +"Warning: AG size is a multiple of stripe width. This can cause performance\n" +"problems by aligning all AGs on the same disk. To avoid this, run mkfs with\n" +"an AG size that is one stripe unit smaller, for example %llu.\n" +msgstr "" +"Uwaga: rozmiar AG jest wielokrotnością szerokości pasa. Może to spowodować\n" +"problemy z wydajnością poprzez wyrównanie wszystkich AG na tym samym dysku.\n" +"Aby temu zapobiec, należy uruchomić mkfs z rozmiarem AG o jedną jednostkę\n" +"pasa mniejszym, na przykład %llu.\n" -#: .././logprint/log_print_all.c:194 +#: .././mkfs/xfs_mkfs.c:2332 #, c-format -msgid "\tQUOTAOFF: #regs:%d type:%s\n" -msgstr "\tQUOTAOFF: #regs:%d type:%s\n" +msgid "%s: Stripe unit(%d) or stripe width(%d) is not a multiple of the block size(%d)\n" +msgstr "%s: Jednostka pasa (%d) lub szerokość pasa (%d) nie jest wielokrotnością rozmiaru bloku (%d)\n" -#: .././logprint/log_print_all.c:209 +#: .././mkfs/xfs_mkfs.c:2364 #, c-format -msgid "\tDQUOT: #regs:%d blkno:%lld boffset:%u id: %d\n" -msgstr "\tDQUOT: #regs:%d blkno:%lld boffset:%u id: %d\n" +msgid "log stripe unit (%d) must be a multiple of the block size (%d)\n" +msgstr "jednostka pasa logu (%d) musi być wielokrotnością rozmiaru bloku (%d)\n" -#: .././logprint/log_print_all.c:213 +#: .././mkfs/xfs_mkfs.c:2377 #, c-format -msgid "\t\tmagic 0x%x\tversion 0x%x\tID 0x%x (%d)\t\n" -msgstr "\t\tmagic 0x%x\twersja 0x%x\tID 0x%x (%d)\t\n" +msgid "log stripe unit (%d bytes) is too large (maximum is 256KiB)\n" +msgstr "jednostka pasa logu (%d bajtów) jest zbyt duża (maksimum to 256KiB)\n" -#: .././logprint/log_print_all.c:218 +#: .././mkfs/xfs_mkfs.c:2380 #, c-format -msgid "\t\tblk_hard 0x%x\tblk_soft 0x%x\tino_hard 0x%x\tino_soft 0x%x\n" -msgstr "\t\tblk_hard 0x%x\tblk_soft 0x%x\tino_hard 0x%x\tino_soft 0x%x\n" +msgid "log stripe unit adjusted to 32KiB\n" +msgstr "jednostka pasa logu zmodyfikowana na 32KiB\n" -#: .././logprint/log_print_all.c:224 +#: .././mkfs/xfs_mkfs.c:2392 #, c-format -msgid "\t\tbcount 0x%x (%d) icount 0x%x (%d)\n" -msgstr "\t\tbcount 0x%x (%d) icount 0x%x (%d)\n" +msgid "size %s specified for log subvolume is too large, maximum is %lld blocks\n" +msgstr "rozmiar %s podany dla podwolumenu logu jest zbyt duży, maksimum to %lld bloków\n" -#: .././logprint/log_print_all.c:229 +#: .././mkfs/xfs_mkfs.c:2399 #, c-format -msgid "\t\tbtimer 0x%x itimer 0x%x \n" -msgstr "\t\tbtimer 0x%x itimer 0x%x \n" +msgid "size specified for non-existent log subvolume\n" +msgstr "podano rozmiar dla nie istniejącego podwolumenu logu\n" -#: .././logprint/log_print_all.c:238 +#: .././mkfs/xfs_mkfs.c:2402 #, c-format -msgid "\tCORE inode:\n" -msgstr "\tGŁÓWNY i-węzeł:\n" +msgid "size %lld too large for internal log\n" +msgstr "rozmiar %lld jest zbyt duży dla logu wewnętrznego\n" -#: .././logprint/log_print_all.c:241 +#: .././mkfs/xfs_mkfs.c:2495 #, c-format -msgid "\t\tmagic:%c%c mode:0x%x ver:%d format:%d onlink:%d\n" -msgstr "\t\tmagic:%c%c mode:0x%x ver:%d format:%d onlin:%d\n" +msgid "internal log size %lld too large, must fit in allocation group\n" +msgstr "rozmiar wewnętrznego logu %lld zbyt duży, musi się zmieścić w grupie alokacji\n" -#: .././logprint/log_print_all.c:245 +#: .././mkfs/xfs_mkfs.c:2503 #, c-format -msgid "\t\tuid:%d gid:%d nlink:%d projid:%u\n" -msgstr "\t\tuid:%d gid:%d nlink:%d projid:%u\n" +msgid "log ag number %d too large, must be less than %lld\n" +msgstr "liczba ag logu %d zbyt duża, musi być mniejsza niż %lld\n" -#: .././logprint/log_print_all.c:247 +#: .././mkfs/xfs_mkfs.c:2541 #, c-format -msgid "\t\tatime:%d mtime:%d ctime:%d\n" -msgstr "\t\tatime:%d mtime:%d ctime:%d\n" +msgid "" +"meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n" +" =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" +" =%-22s crc=%-8u finobt=%u\n" +"data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" +" =%-22s sunit=%-6u swidth=%u blks\n" +"naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n" +"log =%-22s bsize=%-6d blocks=%lld, version=%d\n" +" =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n" +"realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n" +msgstr "" +"metadane=%-22s isize=%-6d agcount=%lld, agsize=%lld bloków\n" +" =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" +" =%-22s crc=%-8u finobt=%u\n" +"dane =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" +" =%-22s sunit=%-6u swidth=%u bloków\n" +"nazwy =wersja %-14u bsize=%-6u ascii-ci=%d ftype=%d\n" +"log =%-22s bsize=%-6d blocks=%lld, wersja=%d\n" +" =%-22s sectsz=%-5u sunit=%d bloków, lazy-count=%d\n" +"realtime=%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n" -#: .././logprint/log_print_all.c:249 +#: .././mkfs/xfs_mkfs.c:2650 #, c-format -msgid "\t\tflushiter:%d\n" -msgstr "\t\tflushiter:%d\n" +msgid "%s: Growing the data section failed\n" +msgstr "%s: Powiększenie sekcji danych nie powiodło się\n" -#: .././logprint/log_print_all.c:250 +#: .././mkfs/xfs_mkfs.c:2679 #, c-format -msgid "\t\tsize:0x%llx nblks:0x%llx exsize:%d nextents:%d anextents:%d\n" -msgstr "\t\tsize:0x%llx nblks:0x%llx exsize:%d nextents:%d anextents:%d\n" +msgid "%s: filesystem failed to initialize\n" +msgstr "%s: nie udało się zainicjować systemu plików\n" -#: .././logprint/log_print_all.c:254 +#: .././mkfs/xfs_mkfs.c:2979 #, c-format -msgid "\t\tforkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x gen:%d\n" -msgstr "\t\tforkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x gen:%d\n" +msgid "%s: root inode created in AG %u, not AG 0\n" +msgstr "%s: główny i-węzeł utworzony w AG %u, nie AG 0\n" -#: .././logprint/log_print_all.c:274 +#: .././mkfs/xfs_mkfs.c:3045 #, c-format -msgid "\tINODE: #regs:%d ino:0x%llx flags:0x%x dsize:%d\n" -msgstr "\tINODE: #regs:%d ino:0x%llx flags:0x%x dsize:%d\n" +msgid "Cannot specify both -%c %s and -%c %s\n" +msgstr "Nie można podać jednocześnie -%c %s i %c %s\n" -#: .././logprint/log_print_all.c:289 +#: .././mkfs/xfs_mkfs.c:3056 #, c-format -msgid "\t\tDATA FORK EXTENTS inode data:\n" -msgstr "\t\tDane EKSTENTÓW GAŁĘZI DANYCH i-węzła:\n" +msgid "Illegal value %s for -%s option\n" +msgstr "Niedozwolona wartość %s dla opcji -%s\n" -#: .././logprint/log_print_all.c:296 +#: .././mkfs/xfs_mkfs.c:3073 #, c-format -msgid "\t\tDATA FORK BTREE inode data:\n" -msgstr "\t\tDane B-DRZEWA GAŁĘZI DANYCH i-węzła:\n" +msgid "-%c %s option requires a value\n" +msgstr "Opcja -%c %s wymaga wartości\n" -#: .././logprint/log_print_all.c:303 +#: .././mkfs/xfs_mkfs.c:3086 .././repair/xfs_repair.c:164 #, c-format -msgid "\t\tDATA FORK LOCAL inode data:\n" -msgstr "\t\tDane LOKALNE GAŁĘZI DANYCH i-węzła:\n" +msgid "option respecified\n" +msgstr "ponownie podana opcja\n" -#: .././logprint/log_print_all.c:310 +#: .././mkfs/xfs_mkfs.c:3095 .././repair/xfs_repair.c:171 #, c-format -msgid "\t\tDEV inode: no extra region\n" -msgstr "\t\tI-węzeł DEV: brak dodatkowego regionu\n" +msgid "unknown option -%c %s\n" +msgstr "nieznana opcja -%c %s\n" -#: .././logprint/log_print_all.c:314 +#: .././mkfs/xfs_mkfs.c:3134 #, c-format -msgid "\t\tUUID inode: no extra region\n" -msgstr "\t\tI-węzeł UUID: brak dodatkowego regionu\n" +msgid "blocksize not available yet.\n" +msgstr "rozmiar bloku jeszcze nie dostępny.\n" -#: .././logprint/log_print_all.c:329 +#: .././mkfs/xfs_mkfs.c:3160 #, c-format -msgid "\t\tATTR FORK EXTENTS inode data:\n" -msgstr "\t\tDane EKSTENTÓW GAŁĘZI ATRYBUTÓW i-węzła:\n" +msgid "" +"Usage: %s\n" +"/* blocksize */\t\t[-b log=n|size=num]\n" +"/* metadata */\t\t[-m crc=0|1,finobt=0|1]\n" +"/* data subvol */\t[-d agcount=n,agsize=n,file,name=xxx,size=num,\n" +"\t\t\t (sunit=value,swidth=value|su=num,sw=num|noalign),\n" +"\t\t\t sectlog=n|sectsize=num\n" +"/* force overwrite */\t[-f]\n" +"/* inode size */\t[-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,\n" +"\t\t\t projid32bit=0|1]\n" +"/* no discard */\t[-K]\n" +"/* log subvol */\t[-l agnum=n,internal,size=num,logdev=xxx,version=n\n" +"\t\t\t sunit=value|su=num,sectlog=n|sectsize=num,\n" +"\t\t\t lazy-count=0|1]\n" +"/* label */\t\t[-L label (maximum 12 characters)]\n" +"/* naming */\t\t[-n log=n|size=num,version=2|ci,ftype=0|1]\n" +"/* no-op info only */\t[-N]\n" +"/* prototype file */\t[-p fname]\n" +"/* quiet */\t\t[-q]\n" +"/* realtime subvol */\t[-r extsize=num,size=num,rtdev=xxx]\n" +"/* sectorsize */\t[-s log=n|size=num]\n" +"/* version */\t\t[-V]\n" +"\t\t\tdevicename\n" +" is required unless -d name=xxx is given.\n" +" is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),\n" +" xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).\n" +" is xxx (512 byte blocks).\n" +msgstr "" +"Składnia: %s\n" +"/* rozmiar bloku */ [-b log=n|size=liczba]\n" +"/* metadane */ [-m crc=0|1,finobt=0|1]\n" +"/* podwolumen danych */ [-d agcount=n,agsize=n,file,name=xxx,size=liczba,\n" +" (sunit=wartość,swidth=wartość|su=ile,sw=ile|noalign),\n" +" sectlog=n|sectsize=ile]\n" +"/* wym. nadpisania */ [-f]\n" +"/* rozmiar i-węzła */ [-i log=n|perblock=n|size=ile,maxpct=n,attr=0|1|2,\n" +" projid32bit=0|1]\n" +"/* bez porzucenia */ [-K]\n" +"/* podwolumen logu */ [-l agnum=n,internal,size=ile,logdev=xxx,version=n\n" +" sunit=wartość|su=ile,sectlog=n|sectsize=ile,\n" +" lazy-count=0|1]\n" +"/* etykieta */ [-L etykieta (maksymalnie 12 znaków)]\n" +"/* nazwy */ [-n log=n|size=ile,wersja=2|ci,ftype=0|1]\n" +"/* tylko info no-op */ [-N]\n" +"/* plik prototypu */ [-p nazwa_pliku]\n" +"/* cisza */ [-q]\n" +"/* podwolumen rt */ [-r extsize=ile,size=ile,rtdev=xxx]\n" +"/* rozmiar sektora */ [-s log=n|size=ile]\n" +"/* wersja */ [-V]\n" +" nazwa_urządzenia\n" +" jest wymagana, chyba że podano -d name=xxx.\n" +" to xxx (bajtów), xxxs (sektorów), xxxb (bloków systemu plików),\n" +" xxxk (xxx KiB), xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB),\n" +" xxxp (xxx PiB).\n" +" to xxx (512-bajtowych bloków).\n" -#: .././logprint/log_print_all.c:337 +#: .././quota/edit.c:36 #, c-format -msgid "\t\tATTR FORK BTREE inode data:\n" -msgstr "\t\tDane B-DRZEWA GAŁĘZI ATRYBUTÓW i-węzła:\n" +msgid "" +"\n" +" modify quota limits for the specified user\n" +"\n" +" Example:\n" +" 'limit bsoft=100m bhard=110m tanya\n" +"\n" +" Changes the soft and/or hard block limits, inode limits and/or realtime\n" +" block limits that are currently being used for the specified user, group,\n" +" or project. The filesystem identified by the current path is modified.\n" +" -d -- set the default values, used the first time a file is created\n" +" -g -- modify group quota limits\n" +" -p -- modify project quota limits\n" +" -u -- modify user quota limits\n" +" The block limit values can be specified with a units suffix - accepted\n" +" units are: k (kilobytes), m (megabytes), g (gigabytes), and t (terabytes).\n" +" The user/group/project can be specified either by name or by number.\n" +"\n" +msgstr "" +"\n" +" zmiana limitów quot dla podanego użytkownika\n" +"\n" +"Przykład:\n" +" 'limit bsoft=100m bhard=110m tanya'\n" +"\n" +" limit zmienia miękki i/lub twardy limit bloków, limity i-węzłów i/lub limity\n" +" bloków realtime aktualnie używane dla podanego użytkownika, grupy lub projektu.\n" +" System plików określony bieżącą ścieżką jest modyfikowany.\n" +" -d - ustawienie wartości domyślnych, użytych pierwszy raz przy tworzeniu pliku\n" +" -g - zmiana limitów quot grupy\n" +" -p - zmiana limitów quot projektu\n" +" -u - zmiana limitów quot użytkownika\n" +" Wartości limitów bloków mogą być podane z końcówką jednostki - przyjmowane\n" +" jednostki to: k (kilobajty), m (megabajty), g (gigabajty) i t (terabajty).\n" +" Użytkownik/grupa/projekt może być podany za pomocą nazwy lub numeru.\n" +"\n" -#: .././logprint/log_print_all.c:345 +#: .././quota/edit.c:59 #, c-format -msgid "\t\tATTR FORK LOCAL inode data:\n" -msgstr "\t\tDane LOKALNE GAŁĘZI ATRYBUTÓW i-węzła:\n" +msgid "" +"\n" +" modify quota enforcement timeout for the current filesystem\n" +"\n" +" Example:\n" +" 'timer -i 3days'\n" +" (soft inode limit timer is changed to 3 days)\n" +"\n" +" Changes the timeout value associated with the block limits, inode limits\n" +" and/or realtime block limits for all users, groups, or projects on the\n" +" current filesystem.\n" +" As soon as a user consumes the amount of space or number of inodes set as\n" +" the soft limit, a timer is started. If the timer expires and the user is\n" +" still over the soft limit, the soft limit is enforced as the hard limit.\n" +" The default timeout is 7 days.\n" +" -d -- set the default values, used the first time a file is created\n" +" -g -- modify group quota timer\n" +" -p -- modify project quota timer\n" +" -u -- modify user quota timer\n" +" -b -- modify the blocks-used timer\n" +" -i -- modify the inodes-used timer\n" +" -r -- modify the blocks-used timer for the (optional) realtime subvolume\n" +" The timeout value is specified as a number of seconds, by default.\n" +" However, a suffix may be used to alternatively specify minutes (m),\n" +" hours (h), days (d), or weeks (w) - either the full word or the first\n" +" letter of the word can be used.\n" +"\n" +msgstr "" +"\n" +" zmiana czasu wymuszenia limitów dla bieżącego systemu plików\n" +"\n" +" Przykład:\n" +" 'timer -i 3days'\n" +" (zmiana czasu wymuszenia miękkiego limitu i-węzłów na 3 dni)\n" +"\n" +" timer zmienia wartość ograniczenia czasu związanego z limitami bloków,\n" +" limitami i-węzłów i/lub limitami bloków realtime dla wszystkich użytkowników,\n" +" grup lub projektów na bieżącym systemie plików.\n" +" Po tym jak użytkownik wykorzysta ilość miejsca lub liczbę i-węzłów ustawioną\n" +" jako miękki limit, zaczyna działać zegar. Kiedy czas minie, a użytkownik nadal\n" +" przekracza miękki limit, miękki limit staje się twardym.\n" +" Domyślne ograniczenie czasowe to 7 dni.\n" +" -d - ustawienie wartości domyślnych, użytych pierwszy raz przy tworzeniu pliku\n" +" -g - zmiana czasu dla limitów quot grup\n" +" -p - zmiana czasu dla limitów quot projektów\n" +" -u - zmiana czasu dla limitów quot użytkowników\n" +" -b - zmiana czasu dla użytych bloków\n" +" -i - zmiana czasu dla użytych i-węzłów\n" +" -r - zmiana czasu dla użytych bloków na (opcjonalnym) podwolumenie realtime\n" +" Wartość ograniczenia czasu jest podawana domyślnie jako liczba sekund.\n" +" Jednak można dodać końcówkę, aby podać czas w minutach (m), godzinach (h),\n" +" dniach (d) lub tygodniach (w) - można użyć pełnego słowa lub pierwsze litery.\n" +"\n" -#: .././logprint/log_print_all.c:370 +#: .././quota/edit.c:91 #, c-format -msgid "\tEFD: #regs: %d num_extents: %d id: 0x%llx\n" -msgstr "\tEFD: #regs: %d num_extents: %d id: 0x%llx\n" +msgid "" +"\n" +" modify the number of quota warnings sent to the specified user\n" +"\n" +" Example:\n" +" 'warn 2 jimmy'\n" +" (tell the quota system that two warnings have been sent to user jimmy)\n" +"\n" +" Changes the warning count associated with the block limits, inode limits\n" +" and/or realtime block limits for the specified user, group, or project.\n" +" When a user has been warned the maximum number of times allowed, the soft\n" +" limit is enforced as the hard limit. It is intended as an alternative to\n" +" the timeout system, where the system administrator updates a count of the\n" +" number of warnings issued to people, and they are penalised if the warnings\n" +" are ignored.\n" +" -d -- set maximum warning count, which triggers soft limit enforcement\n" +" -g -- set group quota warning count\n" +" -p -- set project quota warning count\n" +" -u -- set user quota warning count\n" +" -b -- set the blocks-used warning count\n" +" -i -- set the inodes-used warning count\n" +" -r -- set the blocks-used warn count for the (optional) realtime subvolume\n" +" The user/group/project can be specified either by name or by number.\n" +"\n" +msgstr "" +"\n" +" zmiana liczby ostrzeżeń quot wysyłanych do podanego użytkownika\n" +"\n" +" Przykład:\n" +" 'warn 2 jimmy'\n" +" (przekazanie systemowi quota, że wysłano 2 ostrzeżenia do użytkownika jimmy)\n" +"\n" +" warn zmienia liczbę ostrzeżeń związanych z limitami bloków, limitami i-węzłów\n" +" i/lub limitami bloków realtime dla podanego użytkownika, grupy lub projektu.\n" +" Kiedy użytkownik został ostrzeżony maksymalną dozwoloną liczbę razy, miękki\n" +" limit staje się twardym. Jest to pomyślane jako alternatywa dla systemu\n" +" ograniczeń czasowych, gdzie administrator uaktualnia licznik ostrzeżeń\n" +" wysłanych do ludzi i karze użytkowników ignorujących ostrzeżenia.\n" +" -d - ustawienie maksymalnej liczby ostrzeżeń, po której wymuszane są limity\n" +" -g - ustawienie liczby ostrzeżeń dla grupy\n" +" -p - ustawienie liczby ostrzeżeń dla projektu\n" +" -u - ustawienie liczby ostrzeżeń dla grupy\n" +" -b - ustawienie liczby ostrzeżeń dla użytych bloków\n" +" -i - ustawienie liczby ostrzeżeń dla użytych i-węzłów\n" +" -r - ustawienie liczby ostrzeżeń dla użytych bloków na podwolumenie realtime\n" +" Użytkownik/grupa/projekt może być podany za pomocą nazwy lub numeru.\n" +"\n" -#: .././logprint/log_print_all.c:394 +#: .././quota/edit.c:145 #, c-format -msgid "%s: xlog_recover_print_efi: malloc failed\n" -msgstr "%s: xlog_recover_print_efi: malloc nie powiodło się\n" +msgid "%s: cannot set limits: %s\n" +msgstr "%s: nie można ustawić limitów: %s\n" -#: .././logprint/log_print_all.c:402 +#: .././quota/edit.c:166 .././quota/edit.c:569 #, c-format -msgid "\tEFI: #regs:%d num_extents:%d id:0x%llx\n" -msgstr "\tEFI: #regs:%d num_extents:%d id:0x%llx\n" +msgid "%s: invalid user name: %s\n" +msgstr "%s: nieprawidłowa nazwa użytkownika: %s\n" -#: .././logprint/log_print_all.c:442 +#: .././quota/edit.c:189 .././quota/edit.c:586 #, c-format -msgid "xlog_recover_print_logitem: illegal type\n" -msgstr "xlog_recover_print_logitem: niedozwolony typ\n" +msgid "%s: invalid group name: %s\n" +msgstr "%s: nieprawidłowa nazwa grupy: %s\n" -#: .././logprint/log_print_all.c:473 +#: .././quota/edit.c:212 .././quota/edit.c:603 #, c-format -msgid "%s: illegal type" -msgstr "%s: niedozwolony typ" +msgid "%s: invalid project name: %s\n" +msgstr "%s: nieprawidłowa nazwa projektu: %s\n" -#: .././logprint/log_print_all.c:481 +#: .././quota/edit.c:237 #, c-format -msgid ": cnt:%d total:%d " -msgstr ": cnt:%d total:%d " +msgid "%s: Error: could not parse size %s.\n" +msgstr "%s: Błąd: nie udało się przeanalizować rozmiaru %s.\n" -#: .././logprint/log_print_all.c:483 +#: .././quota/edit.c:243 #, c-format -msgid "a:0x%lx len:%d " -msgstr "a:0x%lx len:%d " +msgid "%s: Warning: `%s' in quota blocks is 0 (unlimited).\n" +msgstr "%s: Uwaga: `%s' w blokach limitów wynosi 0 (bez ograniczeń).\n" -#: .././libxlog/util.c:37 +#: .././quota/edit.c:332 #, c-format -msgid "" -"* ERROR: mismatched uuid in log\n" -"* SB : %s\n" -"* log: %s\n" -msgstr "" -"* BŁĄD: niepasujący uuid w logu\n" -" SB : %s\n" -" log: %s\n" +msgid "%s: unrecognised argument %s\n" +msgstr "%s: nierozpoznany argument %s\n" -#: .././libxlog/util.c:50 +#: .././quota/edit.c:339 #, c-format -msgid "" -"\n" -"LOG REC AT LSN cycle %d block %d (0x%x, 0x%x)\n" -msgstr "" -"\n" -"LOG REC AT LSN cykl %d blok %d (0x%x, 0x%x)\n" +msgid "%s: cannot find any valid arguments\n" +msgstr "%s: nie można znaleźć żadnych poprawnych argumentów\n" -#: .././libxlog/util.c:58 +#: .././quota/edit.c:447 #, c-format -msgid "* ERROR: bad magic number in log header: 0x%x\n" -msgstr "* BŁĄD: błędna liczba magiczna w nagłówku logu: 0x%x\n" +msgid "%s: fopen on %s failed: %s\n" +msgstr "%s: fopen na %s nie powiodło się: %s\n" -#: .././libxlog/util.c:67 +#: .././quota/edit.c:479 #, c-format -msgid "* ERROR: log format incompatible (log=%d, ours=%d)\n" -msgstr "* BŁĄD: niekompatybilny format logu (log=%d, nasz=%d)\n" - -#: .././libxlog/util.c:77 .././libxlog/util.c:89 -msgid "Bad log" -msgstr "Błędny log" +msgid "%s: cannot set timer: %s\n" +msgstr "%s: nie można ustawić czasu: %s\n" -#: .././libxfs/freebsd.c:49 +#: .././quota/edit.c:553 #, c-format -msgid "%s: %s possibly contains a mounted filesystem\n" -msgstr "%s: %s może zawierać podmontowany system plików\n" - -#: .././libxfs/freebsd.c:60 .././libxfs/linux.c:67 -#, c-format -msgid "%s: %s contains a mounted filesystem\n" -msgstr "%s: %s zawiera podmontowany system plików\n" - -#: .././libxfs/freebsd.c:75 .././libxfs/linux.c:85 -#, c-format -msgid "%s: %s contains a possibly writable, mounted filesystem\n" -msgstr "%s: %s zawiera podmontowany, być może zapisywalny system plików\n" - -#: .././libxfs/freebsd.c:89 .././libxfs/linux.c:99 -#, c-format -msgid "%s: %s contains a mounted and writable filesystem\n" -msgstr "%s: %s zawiera podmontowany, zapisywalny system plików\n" - -#: .././libxfs/freebsd.c:116 .././libxfs/darwin.c:76 .././libxfs/irix.c:58 -#: .././libxfs/linux.c:138 -#, c-format -msgid "%s: cannot stat the device file \"%s\": %s\n" -msgstr "%s: nie można wykonać stat na pliku urządzenia \"%s\": %s\n" - -#: .././libxfs/freebsd.c:129 -#, c-format -msgid "%s: Not a device or file: \"%s\"\n" -msgstr "%s: Nie jest urządzeniem ani plikiem: \"%s\"\n" - -#: .././libxfs/freebsd.c:135 -#, c-format -msgid "%s: DIOCGMEDIASIZE failed on \"%s\": %s\n" -msgstr "%s: DIOCGMEDIASIE nie powiodło się dla \"%s\": %s\n" - -#: .././libxfs/freebsd.c:141 -#, c-format -msgid "%s: DIOCGSECTORSIZE failed on \"%s\": %s\n" -msgstr "%s: DIOCGSECTORSIZE nie powiodło się dla \"%s\": %s\n" - -#: .././libxfs/freebsd.c:196 .././libxfs/darwin.c:139 .././libxfs/irix.c:106 -#: .././libxfs/linux.c:216 -#, c-format -msgid "%s: can't determine memory size\n" -msgstr "%s: nie można określić rozmiaru pamięci\n" - -#: .././libxfs/util.c:707 -#, c-format -msgid "%s: cannot reserve space: %s\n" -msgstr "%s: nie można zarezerwować przestrzeni: %s\n" - -#: .././libxfs/darwin.c:41 -#, c-format -msgid "%s: error opening the device special file \"%s\": %s\n" -msgstr "%s: błąd podczas otwierania pliku specjalnego urządzenia \"%s\": %s\n" - -#: .././libxfs/darwin.c:48 -#, c-format -msgid "%s: can't tell if \"%s\" is writable: %s\n" -msgstr "%s: nie można stwierdzić czy \"%s\" jest zapisywalny: %s\n" - -#: .././libxfs/darwin.c:86 -#, c-format -msgid "%s: can't determine device size: %s\n" -msgstr "%s: nie można określić rozmiaru urządzenia: %s\n" - -#: .././libxfs/kmem.c:15 -#, c-format -msgid "%s: zone init failed (%s, %d bytes): %s\n" -msgstr "%s: inicjalizacja strefy nie powiodła się (%s, %d bajtów): %s\n" - -#: .././libxfs/kmem.c:32 -#, c-format -msgid "%s: zone alloc failed (%s, %d bytes): %s\n" -msgstr "%s: przydzielenie strefy nie powiodło się (%s, %d bajtów): %s\n" - -#: .././libxfs/kmem.c:56 -#, c-format -msgid "%s: malloc failed (%d bytes): %s\n" -msgstr "%s: malloc nie powiodło się (%d bajtów): %s\n" - -#: .././libxfs/kmem.c:77 -#, c-format -msgid "%s: realloc failed (%d bytes): %s\n" -msgstr "%s: realloc nie powiodło się (%d bajtów): %s\n" +msgid "%s: cannot set warnings: %s\n" +msgstr "%s: nie można ustawić ostrzeżeń: %s\n" -#: .././libxfs/linux.c:114 -#, c-format -msgid "%s: %s - cannot set blocksize %d on block device %s: %s\n" -msgstr "%s: %s - nie można ustawić rozmiaru bloku %d dla urządzenia blokowego %s: %s\n" +#: .././quota/edit.c:689 +msgid "[-gpu] bsoft|bhard|isoft|ihard|rtbsoft|rtbhard=N -d|id|name" +msgstr "[-gpu] bsoft|bhard|isoft|ihard|rtbsoft|rtbhard=N -d|id|nazwa" -#: .././libxfs/linux.c:161 -#, c-format -msgid "%s: can't determine device size\n" -msgstr "%s: nie można określić rozmiaru urządzenia\n" +#: .././quota/edit.c:690 +msgid "modify quota limits" +msgstr "zmiana limitów quot" -#: .././libxfs/linux.c:169 -#, c-format -msgid "%s: warning - cannot get sector size from block device %s: %s\n" -msgstr "%s: uwaga - nie można pobrać rozmiaru sektora urządzenia blokowego %s: %s\n" +#: .././quota/edit.c:697 .././quota/report.c:33 .././quota/report.c:647 +msgid "[-gpu] [-f file]" +msgstr "[-gpu] [-f plik]" -#: .././libxfs/init.c:80 .././libxfs/init.c:179 -#, c-format -msgid "%s: %s: device %lld is not open\n" -msgstr "%s: %s: urządzenie %lld nie jest otwarte\n" +#: .././quota/edit.c:698 +msgid "restore quota limits from a backup file" +msgstr "odtworzenie limitów quot z pliku kopii zapasowej" -#: .././libxfs/init.c:116 -#, c-format -msgid "%s: cannot stat %s: %s\n" -msgstr "%s: nie można wykonać stat na %s: %s\n" +#: .././quota/edit.c:704 .././quota/edit.c:712 +msgid "[-bir] [-gpu] value -d|id|name" +msgstr "[-bir] [-gpu] wartość -d|id|nazwa" -#: .././libxfs/init.c:141 -#, c-format -msgid "%s: device %lld is already open\n" -msgstr "%s: urządzenie %lld jest już otwarte\n" +#: .././quota/edit.c:705 +msgid "get/set quota enforcement timeouts" +msgstr "pobranie/ustawienie czasu wymuszenia quot" -#: .././libxfs/init.c:154 -#, c-format -msgid "%s: %s: too many open devices\n" -msgstr "%s: %s: zbyt dużo otwartych urządzeń\n" +#: .././quota/edit.c:713 +msgid "get/set enforcement warning counter" +msgstr "pobranie/ustawienie licznika ostrzeżeń" -#: .././libxfs/init.c:197 +#: .././quota/free.c:29 #, c-format -msgid "%s: can't find a character device matching %s\n" -msgstr "%s: nie można odnaleźć urządzenia znakowego odpowiadającego %s\n" +msgid "" +"\n" +" reports the number of free disk blocks and inodes\n" +"\n" +" This command reports the number of total, used, and available disk blocks.\n" +" It can optionally report the same set of numbers for inodes and realtime\n" +" disk blocks, and will report on all known XFS filesystem mount points and\n" +" project quota paths by default (see 'print' command for a list).\n" +" -b -- report the block count values\n" +" -i -- report the inode count values\n" +" -r -- report the realtime block count values\n" +" -h -- report in a human-readable format\n" +" -N -- suppress the header from the output\n" +"\n" +msgstr "" +"\n" +" informacje o liczbie wolnych bloków i i-węzłów dysku\n" +"\n" +" To polecenie informuje o liczbie wszystkich, używanych i dostępnych bloków\n" +" dysku. Opcjonalnie informuje o tym samym zestawie liczb dla i-węzłów i bloków\n" +" realtime oraz domyślnie zgłasza wszystkie znane punkty montowania systemu\n" +" plików XFS i ścieżki quot projektów (patrz lista w poleceniu 'print').\n" +" -b - informacje o liczbach bloków\n" +" -i - informacje o liczbach i-węzłów\n" +" -r - informacje o liczbach bloków realtime\n" +" -h - informacje w postaci czytelnej dla człowieka\n" +" -N - pominięcie nagłówka z wyjścia\n" +"\n" -#: .././libxfs/init.c:203 +#: .././quota/free.c:154 #, c-format -msgid "%s: can't find a block device matching %s\n" -msgstr "%s: nie można odnaleźć urządzenia blokowego odpowiadającego %s\n" +msgid "%s: project quota flag not set on %s\n" +msgstr "%s: flaga quot projektu nie ustawiona dla %s\n" -#: .././libxfs/init.c:320 +#: .././quota/free.c:163 #, c-format -msgid "%s: can't get size for data subvolume\n" -msgstr "%s: nie można pobrać rozmiaru podwolumenu danych\n" +msgid "%s: project ID %u (%s) doesn't match ID %u (%s)\n" +msgstr "%s: ID projektu %u (%s) nie zgadza się z ID %u (%s)\n" -#: .././libxfs/init.c:325 +#: .././quota/free.c:230 #, c-format -msgid "%s: can't get size for log subvolume\n" -msgstr "%s: nie można pobrać rozmiaru podwolumenu logu\n" +msgid "Filesystem " +msgstr "System plików " -#: .././libxfs/init.c:330 +#: .././quota/free.c:230 #, c-format -msgid "%s: can't get size for realtime subvolume\n" -msgstr "%s: nie można pobrać rozmiaru podwolumenu realtime\n" +msgid "Filesystem " +msgstr "System plików " -#: .././libxfs/init.c:430 +#: .././quota/free.c:233 #, c-format -msgid "%s: cannot read realtime bitmap inode (%d)\n" -msgstr "%s: nie można odczytać i-węzła bitmapy realtime (%d)\n" +msgid " Size Used Avail Use%%" +msgstr " Rozmiar Użyto Dost. %%uż." -#: .././libxfs/init.c:440 +#: .././quota/free.c:234 #, c-format -msgid "%s: cannot read realtime summary inode (%d)\n" -msgstr "%s: nie można odczytać i-węzła opisu realtime (%d)\n" +msgid " 1K-blocks Used Available Use%%" +msgstr " Bloki 1K Użyto Dostępnych %%uż." -#: .././libxfs/init.c:464 +#: .././quota/free.c:237 #, c-format -msgid "%s: filesystem has a realtime subvolume\n" -msgstr "%s: system plików ma podwolumen realtime\n" +msgid " Inodes Used Free Use%%" +msgstr " I-węzły Użyto Wolne %%uż." -#: .././libxfs/init.c:486 +#: .././quota/free.c:238 #, c-format -msgid "%s: realtime init - %llu != %llu\n" -msgstr "%s: inicjalizacja realtime - %llu != %llu\n" +msgid " Inodes IUsed IFree IUse%%" +msgstr " I-węzły UżytoI WolneI %%użI" -#: .././libxfs/init.c:494 +#: .././quota/free.c:239 #, c-format -msgid "%s: realtime size check failed\n" -msgstr "%s: sprawdzenie rozmiaru realtime nie powiodło się\n" +msgid " Pathname\n" +msgstr " Ścieżka\n" -#: .././libxfs/init.c:699 -#, c-format -msgid "%s: size check failed\n" -msgstr "%s: sprawdzenie rozmiaru nie powiodło się\n" +#: .././quota/free.c:371 +msgid "[-bir] [-hn] [-f file]" +msgstr "[-bir] [hn] [-f plik]" -#: .././libxfs/init.c:708 -#, c-format -msgid "%s: WARNING - filesystem uses v1 dirs,limited functionality provided.\n" -msgstr "%s: UWAGA - system plików używa katalogów v1, funkcjonalność jest ograniczona.\n" +#: .././quota/free.c:372 +msgid "show free and used counts for blocks and inodes" +msgstr "pokazanie liczby wolnych i zajętych bloków i i-węzłów" -#: .././libxfs/init.c:728 +#: .././quota/init.c:48 #, c-format -msgid "%s: data size check failed\n" -msgstr "%s: sprawdzenie rozmiaru danych nie powiodło się\n" +msgid "Usage: %s [-V] [-x] [-p prog] [-c cmd]... [-d project]... [path]\n" +msgstr "Składnia: %s [-V] [-x] [-p program] [-c polecenie]... [-d projekt]... [ścieżka]\n" -#: .././libxfs/init.c:741 +#: .././quota/path.c:39 #, c-format -msgid "%s: log size checks failed\n" -msgstr "%s: sprawdzenie rozmiaru logu nie powiodło się\n" +msgid "%sFilesystem Pathname\n" +msgstr "%sSystem plików Ścieżka\n" -#: .././libxfs/init.c:752 -#, c-format -msgid "%s: realtime device init failed\n" -msgstr "%s: inicjalizacja urządzenia realtime nie powiodła się\n" +#: .././quota/path.c:40 +msgid " " +msgstr " " -#: .././libxfs/init.c:759 +#: .././quota/path.c:43 #, c-format -msgid "%s: perag init failed\n" -msgstr "%s: nie udało się zainicjować perag\n" +msgid "%c%03d%c " +msgstr "%c%03d%c " -#: .././libxfs/init.c:771 +#: .././quota/path.c:45 #, c-format -msgid "%s: cannot read root inode (%d)\n" -msgstr "%s: nie można odczytać i-węzła głównego (%d)\n" +msgid "%-19s %s" +msgstr "%-19s %s" -#: .././libxfs/init.c:791 +#: .././quota/path.c:48 #, c-format -msgid "%s: cannot init perag data (%d)\n" -msgstr "%s: nie można zainicjować tabeli perag (%d)\n" +msgid " (project %u" +msgstr " (projekt %u" -#: .././libxfs/rdwr.c:40 +#: .././quota/path.c:50 #, c-format -msgid "%s: %s can't memalign %d bytes: %s\n" -msgstr "%s: %s nie można wykonać memalign dla %d bajtów: %s\n" +msgid ", %s" +msgstr ", %s" -#: .././libxfs/rdwr.c:50 +#: .././quota/path.c:103 #, c-format -msgid "%s: %s seek to offset %llu failed: %s\n" -msgstr "%s: %s zmiana offsetu na %llu nie powiodła się: %s\n" +msgid "No paths are available\n" +msgstr "Brak ścieżek\n" -#: .././libxfs/rdwr.c:60 -#, c-format -msgid "%s: %s write failed: %s\n" -msgstr "%s: %s zapis nie powiódł się: %s\n" +#: .././quota/path.c:131 +msgid "set current path, or show the list of paths" +msgstr "ustawienie bieżącej ścieżki lub pokazanie listy ścieżek" -#: .././libxfs/rdwr.c:64 -#, c-format -msgid "%s: %s not progressing?\n" -msgstr "%s: %s nie postępuje?\n" +#: .././quota/path.c:139 +msgid "list known mount points and projects" +msgstr "wypisanie znanych punktów montowań i projektów" -#: .././libxfs/rdwr.c:336 +#: .././quota/project.c:45 #, c-format -msgid "%s: %s can't memalign %u bytes: %s\n" -msgstr "%s: %s nie można wykonać memalign dla %u bajtów: %s\n" +msgid "" +"\n" +" list projects or setup a project tree for tree quota management\n" +"\n" +" Example:\n" +" 'project -c logfiles'\n" +" (match project 'logfiles' to a directory, and setup the directory tree)\n" +"\n" +" Without arguments, report all projects found in the /etc/projects file.\n" +" The project quota mechanism in XFS can be used to implement a form of\n" +" directory tree quota, where a specified directory and all of the files\n" +" and subdirectories below it (i.e. a tree) can be restricted to using a\n" +" subset of the available space in the filesystem.\n" +"\n" +" A managed tree must be setup initially using the -c option with a project.\n" +" The specified project name or identifier is matched to one or more trees\n" +" defined in /etc/projects, and these trees are then recursively descended\n" +" to mark the affected inodes as being part of that tree - which sets inode\n" +" flags and the project identifier on every file.\n" +" Once this has been done, new files created in the tree will automatically\n" +" be accounted to the tree based on their project identifier. An attempt to\n" +" create a hard link to a file in the tree will only succeed if the project\n" +" identifier matches the project identifier for the tree. The xfs_io utility\n" +" can be used to set the project ID for an arbitrary file, but this can only\n" +" be done by a privileged user.\n" +"\n" +" A previously setup tree can be cleared from project quota control through\n" +" use of the -C option, which will recursively descend the tree, clearing\n" +" the affected inodes from project quota control.\n" +"\n" +" The -c option can be used to check whether a tree is setup, it reports\n" +" nothing if the tree is correct, otherwise it reports the paths of inodes\n" +" which do not have the project ID of the rest of the tree, or if the inode\n" +" flag is not set.\n" +"\n" +" The -p option can be used to manually specify project path without\n" +" need to create /etc/projects file. This option can be used multiple times\n" +" to specify multiple paths. When using this option only one projid/name can\n" +" be specified at command line. Note that /etc/projects is also used if exists.\n" +"\n" +" The -d option allows to descend at most levels of directories\n" +" below the command line arguments. -d 0 means only apply the actions\n" +" to the top level of the projects. -d -1 means no recursion limit (default).\n" +"\n" +" The /etc/projid and /etc/projects file formats are simple, and described\n" +" on the xfs_quota man page.\n" +"\n" +msgstr "" +"\n" +" wypisanie projektów lub ustanowienie drzewa projektu do zarządzania limitami\n" +"\n" +" Przykład:\n" +" 'project -c logfiles'\n" +" (dopasowanie projektu 'logfiles' do katalogu i ustanowienie drzewa katalogów)\n" +"\n" +" Bez argumentów project wypisuje wszystkie projekty znalezione w pliku\n" +" /etc/projects. Mechanizm quota dla projektów w XFS-ie może być używany do\n" +" zaimplementowania formy limitów dla drzewa katalogów, gdzie podany katalog\n" +" i wszystkie pliki i podkatalogi poniżej niego (czyli drzewo) mogą być\n" +" ograniczone do używania podzbioru miejsca dostępnego w systemie plików.\n" +"\n" +" Zarządzane drzewo musi być ustanowione początkowo przy użyciu opcji project -c.\n" +" Podana nazwa lub identyfikator projektu jest dopasowywany do jednego lub\n" +" większej liczby drzew zdefiniowanych w /etc/projects, a następnie te drzewa są\n" +" rekurencyjnie przechodzone w celu oznaczenia i-węzłów jako będących częścią\n" +" tego drzewa - co ustawia flagi i-węzłów i identyfikator projektu dla każdego\n" +" pliku.\n" +" Po zrobieniu tego nowe pliki tworzone w drzewie będą automatycznie liczone jako\n" +" część drzewa o ich identyfikatorze projektu. Próba utworzenia dowiązania\n" +" zwykłego do pliku w drzewie powiedzie się tylko jeśli identyfikator projektu\n" +" pasuje do identyfikatora projektu drzewa. Można użyć narzędzia xfs_io do\n" +" ustawienia ID projektu dla dowolnego pliku, ale może tego dokonać tylko\n" +" uprzywilejowany użytkownik.\n" +"\n" +" Poprzednio ustanowione drzewa można usunąć z kontroli limitów projektu poprzez\n" +" użycie opcji -C, która rekurencyjnie przejdzie drzewo, usuwając i-węzły spod\n" +" kontroli limitów projektu.\n" +"\n" +" Opcji -c można użyć do sprawdzenia czy drzewo zostało ustanowione - nie\n" +" informuje o niczym jeśli drzewo jest poprawne, a w przeciwnym wypadku zgłasza\n" +" ścieżki i-węzłów nie mające ID projektu takiego jak reszta drzewa lub nie\n" +" mające ustawionej flagi.\n" +"\n" +" Opcja -p <ścieżka> umożliwia podanie ścieżki projektu w linii poleceń\n" +" bez potrzeby tworzenia pliku /etc/projects. Ta opcja może być używana\n" +" wielokrotnie w celu przekazanie wielu ścieżek projektu. Tylko jeden\n" +" identyfikator projektu może być podawy w linii poleceń w momencie\n" +" używania opcji -p. Jeśli plik /etc/projects istnieje to także jest używany\n" +" oprócz ścieżek w linii poleceń.\n" +"\n" +" Opcja -d pozwala na ograniczanie zagłębiania się w podkatalogach\n" +" projektu do granicy . -d 0 oznacza najwyższy poziom. -d 1 oznacza\n" +" brak limitu zagłębiania (domyślny).\n" +"\n" +" Format plików /etc/projid i /etc/projects jest prosty i opisany na stronie\n" +" manuala xfs_quota.\n" +"\n" -#: .././libxfs/rdwr.c:425 +#: .././quota/project.c:108 .././quota/project.c:153 .././quota/project.c:200 #, c-format -msgid "Warning: recursive buffer locking at block % detected\n" -msgstr "Uwaga: wykryto rekurencyjną blokadę bufora na bloku %\n" +msgid "%s: cannot stat file %s\n" +msgstr "%s: nie można wykonać stat na pliku %s\n" -#: .././libxfs/rdwr.c:519 +#: .././quota/project.c:112 .././quota/project.c:157 .././quota/project.c:204 #, c-format -msgid "%s: read failed: %s\n" -msgstr "%s: odczyt nie powiódł się: %s\n" +msgid "%s: skipping special file %s\n" +msgstr "%s: pominięto plik specjalny %s\n" -#: .././libxfs/rdwr.c:525 +#: .././quota/project.c:126 #, c-format -msgid "%s: error - read only %d of %d bytes\n" -msgstr "%s: błąd - odczytano tylko %d z %d bajtów\n" +msgid "%s - project identifier is not set (inode=%u, tree=%u)\n" +msgstr "%s - identyfikator projektu nie ustawiony (i-węzeł=%u, drzewo=%u)\n" -#: .././libxfs/rdwr.c:568 +#: .././quota/project.c:130 #, c-format -msgid "%s: pwrite64 failed: %s\n" -msgstr "%s: pwrite64 nie powiodło się: %s\n" +msgid "%s - project inheritance flag is not set\n" +msgstr "%s - flaga dziedziczenia projektu nie ustawiona\n" -#: .././libxfs/rdwr.c:574 +#: .././quota/project.c:178 #, c-format -msgid "%s: error - wrote only %d of %d bytes\n" -msgstr "%s: błąd - zapisano tylko %d z %d bajtów\n" +msgid "%s: cannot clear project on %s: %s\n" +msgstr "%s: nie można usunąć projektu z %s: %s\n" -#: .././libxfs/trans.c:33 +#: .././quota/project.c:225 #, c-format -msgid "%s: xact calloc failed (%d bytes): %s\n" -msgstr "%s: xact calloc nie powiodło się (%d bajtów): %s\n" +msgid "%s: cannot set project on %s: %s\n" +msgstr "%s: nie można ustawić projektu na %s: %s\n" -#: .././libxfs/trans.c:602 +#: .././quota/project.c:240 #, c-format -msgid "%s: warning - itobp failed (%d)\n" -msgstr "%s: uwaga - itobp nie powiodło się (%d)\n" +msgid "Checking project %s (path %s)...\n" +msgstr "Sprawdzanie projektu %s (ścieżka %s)...\n" -#: .././libxfs/trans.c:610 +#: .././quota/project.c:244 #, c-format -msgid "%s: warning - iflush_int failed (%d)\n" -msgstr "%s: uwaga - iflush_int nie powiodło się (%d)\n" +msgid "Setting up project %s (path %s)...\n" +msgstr "Ustanawianie projektu %s (ścieżka %s)...\n" -#: .././libxfs/trans.c:682 .././libxfs/trans.c:741 +#: .././quota/project.c:248 #, c-format -msgid "%s: unrecognised log item type\n" -msgstr "%s: nierozpoznany typ elementu logu\n" +msgid "Clearing project %s (path %s)...\n" +msgstr "Usuwanie projektu %s (ścieżka %s)...\n" -#: .././libxcmd/command.c:85 +#: .././quota/project.c:271 #, c-format -msgid "bad argument count %d to %s, expected at least %d arguments\n" -msgstr "błędna liczba argumentów %d dla %s, oczekiwano co najmniej %d argumentów\n" +msgid "Processed %d (%s and cmdline) paths for project %s with recursion depth %s (%d).\n" +msgstr "" +"Przetworzono %d (z %s oraz z linii poleceń) ścieżek dla projektu %s\n" +"z ograniczeniem %s (%d)\n" -#: .././libxcmd/command.c:89 -#, c-format -msgid "bad argument count %d to %s, expected %d arguments\n" -msgstr "błędna liczba argumentów %d dla %s, oczekiwano %d argumentów\n" +#: .././quota/project.c:274 +msgid "infinite" +msgstr "nieaktywnym" -#: .././libxcmd/command.c:93 +#: .././quota/project.c:274 +msgid "limited" +msgstr "aktywnym" + +#: .././quota/project.c:319 #, c-format -msgid "bad argument count %d to %s, expected between %d and %d arguments\n" -msgstr "błędna liczba argumentów %d dla %s, oczekiwano od %d do %d argumentów\n" +msgid "projects file \"%s\" doesn't exist\n" +msgstr "plik projektów \"%s\" nie istnieje\n" -#: .././libxcmd/command.c:155 +#: .././quota/project.c:326 #, c-format -msgid "cannot strdup command '%s': %s\n" -msgstr "nie można wykonać strdup na poleceniu '%s': %s\n" +msgid "%s: only one projid/name can be specified when using -p , %d found.\n" +msgstr "%s: tylko jeden id projektu/nazwa może być podana kiedy opcja -p <ścieżka> jest w użyciu. Znaleziono %d.\n" -#: .././libxcmd/command.c:171 .././libxcmd/command.c:189 +#: .././quota/project.c:336 #, c-format -msgid "command \"%s\" not found\n" -msgstr "nie znaleziono polecenia \"%s\"\n" +msgid "%s - no such project in %s or invalid project number\n" +msgstr "%s - nie ma takiego projektu w %s lub błędny numer projektu\n" -#: .././libxcmd/help.c:33 .././db/help.c:40 +#: .././quota/project.c:353 +msgid "[-c|-s|-C|-d |-p ] project ..." +msgstr "[-c|-s|-C| -d |-p <ścieżka>] projekt ..." + +#: .././quota/project.c:356 +msgid "check, setup or clear project quota trees" +msgstr "sprawdzenie, ustanowienie lub usunięcie drzew projektów" + +#: .././quota/quot.c:55 #, c-format msgid "" "\n" -"Use 'help commandname' for extended help.\n" +" display a summary of filesystem ownership\n" +"\n" +" -a -- summarise for all local XFS filesystem mount points\n" +" -c -- display three columns giving file size in kilobytes, number of files\n" +" of that size, and cumulative total of kilobytes in that size or\n" +" smaller file. The last row is used as an overflow bucket and is the\n" +" total of all files greater than 500 kilobytes.\n" +" -v -- display three columns containing the number of kilobytes not\n" +" accessed in the last 30, 60, and 90 days.\n" +" -g -- display group summary\n" +" -p -- display project summary\n" +" -u -- display user summary\n" +" -b -- display number of blocks used\n" +" -i -- display number of inodes used\n" +" -r -- display number of realtime blocks used\n" +" -n -- skip identifier-to-name translations, just report IDs\n" +" -N -- suppress the initial header\n" +" -f -- send output to a file\n" +" The (optional) user/group/project can be specified either by name or by\n" +" number (i.e. uid/gid/projid).\n" +"\n" msgstr "" "\n" -"Rozszerzony opis można uzyskać przez 'help nazwa_polecenia'.\n" +" wyświetlenie podsumowania własności systemu plików\n" +"\n" +" -a - podsumowanie dla wszystkich punktów montowania systemów plików XFS\n" +" -c - wyświetlenie trzech kolumn z rozmiarem plików w kilobajtach, liczbą\n" +" plików tego rozmiaru i sumą kilobajtów w plikach o tym lub mniejszym\n" +" rozmiarze. Ostatni wiersz podsumowuje pliki większe niż 500 kilobajtów.\n" +" -v - wyświetlenie trzech kolumn zawierających liczbę kilobajtów, do których\n" +" nie było odwołań przez ostatnie 30, 60 i 90 dni.\n" +" -g - wyświetlenie podsumowania dla grup\n" +" -p - wyświetlenie podsumowania dla projektów\n" +" -u - wyświetlenie podsumowania dla użytkowników\n" +" -b - wyświetlenie liczby wykorzystanych bloków\n" +" -i - wyświetlenie liczby wykorzystanych i-węzłów\n" +" -r - wyświetlenie liczby wykorzystanych blików realtime\n" +" -n - pominięcie tłumaczenia identyfikatorów na nazwy, wypisywanie ID\n" +" -N - pominięcie początkowego nagłówka\n" +" -f - zapisanie wyjścia do pliku\n" +" (opcjonalny) użytkownik/grupa/projekt może być podany za pomocą nazwy lub\n" +" numeru (tzn. uid/gid/projid).\n" -#: .././libxcmd/help.c:49 .././db/command.c:82 .././db/help.c:56 +#: .././quota/quot.c:220 #, c-format -msgid "command %s not found\n" -msgstr "nie znaleziono polecenia %s\n" - -#: .././libxcmd/help.c:92 .././db/help.c:30 .././db/io.c:48 -msgid "[command]" -msgstr "[polecenie]" - -#: .././libxcmd/help.c:93 .././db/help.c:31 -msgid "help for one or all commands" -msgstr "opis dla jednego lub wszystkich poleceń" +msgid "%s (%s) %s:\n" +msgstr "%s (%s) %s:\n" -#: .././libxcmd/paths.c:263 +#: .././quota/quot.c:296 #, c-format -msgid "%s: unable to extract mount options for \"%s\"\n" -msgstr "%s: nie udało się wydobyć opcji montowania dla \"%s\"\n" +msgid "%s (%s):\n" +msgstr "%s (%s):\n" -#: .././libxcmd/paths.c:324 +#: .././quota/quot.c:301 .././quota/quot.c:305 #, c-format -msgid "%s: getmntinfo() failed: %s\n" -msgstr "%s: getmntinfo() nie powiodło się: %s\n" +msgid "%d\t%llu\t%llu\n" +msgstr "%d\t%llu\t%llu\n" -#: .././libxcmd/paths.c:385 -#, c-format -msgid "%s: cannot setup path for mount %s: %s\n" -msgstr "%s: nie można ustawić ścieżki dla montowania %s: %s\n" +#: .././quota/quot.c:419 +msgid "[-bir] [-gpu] [-acv] [-f file]" +msgstr "[-bir] [-gpu] [-acv] [-f plik]" -#: .././libxcmd/paths.c:407 -#, c-format -msgid "%s: cannot find mount point for path `%s': %s\n" -msgstr "%s: nie można znaleźć punktu montowania dla ścieżki `%s': %s\n" +#: .././quota/quot.c:420 +msgid "summarize filesystem ownership" +msgstr "podsumowanie własności systemu plików" -#: .././libxcmd/paths.c:435 +#: .././quota/quota.c:32 #, c-format -msgid "%s: cannot setup path for project %s: %s\n" -msgstr "%s: nie można ustawić ścieżki dla projektu %s: %s\n" +msgid "" +"\n" +" display usage and quota information\n" +"\n" +" -g -- display group quota information\n" +" -p -- display project quota information\n" +" -u -- display user quota information\n" +" -b -- display number of blocks used\n" +" -i -- display number of inodes used\n" +" -r -- display number of realtime blocks used\n" +" -h -- report in a human-readable format\n" +" -n -- skip identifier-to-name translations, just report IDs\n" +" -N -- suppress the initial header\n" +" -v -- increase verbosity in reporting (also dumps zero values)\n" +" -f -- send output to a file\n" +" The (optional) user/group/project can be specified either by name or by\n" +" number (i.e. uid/gid/projid).\n" +"\n" +msgstr "" +"\n" +" wyświetlenie informacji o wykorzystaniu miejsca i limitach\n" +"\n" +" -g - wyświetlenie informacji o limitach grup\n" +" -p - wyświetlenie informacji o limitach projektów\n" +" -u - wyświetlenie informacji o limitach użytkowników\n" +" -b - wyświetlenie liczby wykorzystanych bloków\n" +" -i - wyświetlenie liczby wykorzystanych i-węzłów\n" +" -r - wyświetlenie liczby wykorzystanych bloków realtime\n" +" -h - użycie formatu czytelnego dla człowieka\n" +" -n - pominięcie tłumaczenia identyfikatorów na nazwy, wypisywanie ID\n" +" -N - pominięcie początkowego nagłówka\n" +" -v - zwiększenie szczegółowości (wypisywanie także wartości zerowych)\n" +" -f - zapisanie wyjścia do pliku\n" +" (opcjonalny) użytkownik/grupa/projekt może być podany za pomocą nazwy lub\n" +" numeru (tzn. uid/gid/projid).\n" -#: .././libxcmd/paths.c:476 +#: .././quota/quota.c:85 #, c-format -msgid "%s: cannot initialise path table: %s\n" -msgstr "%s: nie można zainicjować tabeli ścieżek: %s\n" +msgid "" +"Disk quotas for %s %s (%u)\n" +"Filesystem%s" +msgstr "" +"Limity dyskowe (quota) dla %s %s (%u)\n" +"System plików%s" -#: .././libxcmd/paths.c:496 +#: .././quota/quota.c:90 #, c-format -msgid "%s: cannot setup path for project dir %s: %s\n" -msgstr "%s: nie można ustawić ścieżki dla katalogu projektu %s: %s\n" - -#: .././libxcmd/quit.c:42 -msgid "exit the program" -msgstr "wyjście z programu" +msgid " Blocks Quota Limit Warn/Time " +msgstr " Bloki Quota Limit Czas ostrz. " -#: .././libdisk/drivers.c:35 +#: .././quota/quota.c:91 #, c-format -msgid "Cannot stat %s: %s\n" -msgstr "Nie można wykonać stat na %s: %s\n" +msgid " Blocks Quota Limit Warn/Time " +msgstr " Bloki Quota Limit Czas ostrz. " -#: .././libdisk/lvm.c:60 +#: .././quota/quota.c:94 #, c-format -msgid "Warning - LVM device, but no lvdisplay(8) found\n" -msgstr "Uwaga - urządzenie LVM, ale nie znaleziono lvdisplay(8)\n" +msgid " Files Quota Limit Warn/Time " +msgstr " Pliki Quota Limit Czas ostrz. " -#: .././libdisk/lvm.c:70 .././libdisk/dm.c:73 +#: .././quota/quota.c:95 #, c-format -msgid "Could not open pipe\n" -msgstr "Nie udało się otworzyć potoku\n" +msgid " Files Quota Limit Warn/Time " +msgstr " Pliki Quota Limit Czas ostrz. " -#: .././libdisk/lvm.c:85 .././libdisk/dm.c:88 +#: .././quota/quota.c:98 #, c-format -msgid "Failed to execute %s\n" -msgstr "Nie udało się wywołać %s\n" +msgid "Realtime Quota Limit Warn/Time " +msgstr "Realtime Quota Limit Czas ostrz. " -#: .././libdisk/lvm.c:89 +#: .././quota/quota.c:99 #, c-format -msgid "Failed forking lvdisplay process\n" -msgstr "Nie udało się odgałęzić procesu lvdisplay\n" +msgid " Realtime Quota Limit Warn/Time " +msgstr " Realtime Quota Limit Czas ostrz. " -#: .././libdisk/md.c:61 +#: .././quota/quota.c:235 #, c-format -msgid "Error getting MD array device from %s\n" -msgstr "Błąd podczas pobierania urządzenia macierzy MD z %s\n" +msgid "%s: cannot find user %s\n" +msgstr "%s: nie można odnaleźć użytkownika %s\n" -#: .././libdisk/md.c:68 +#: .././quota/quota.c:285 #, c-format -msgid "Couldn't malloc device string\n" -msgstr "Nie można przydzielić łańcucha nazwy urządzenia\n" +msgid "%s: cannot find group %s\n" +msgstr "%s: nie można odnaleźć grupy %s\n" -#: .././libdisk/md.c:84 +#: .././quota/quota.c:346 #, c-format -msgid "Error getting MD array info from %s\n" -msgstr "Błąd podczas pobierania informacji o macierzy MD z %s\n" +msgid "%s: must specify a project name/ID\n" +msgstr "%s: należy podać nazwę/ID projektu\n" -#: .././libdisk/dm.c:57 +#: .././quota/quota.c:359 #, c-format -msgid "Warning - device mapper device, but no dmsetup(8) found\n" -msgstr "Uwaga - urządzenie device mappera, ale nie znaleziono dmsetup(8)\n" +msgid "%s: cannot find project %s\n" +msgstr "%s: nie można odnaleźć projektu %s\n" -#: .././libdisk/dm.c:92 -#, c-format -msgid "Failed forking dmsetup process\n" -msgstr "Nie udało się odgałęzić procesu dmsetup\n" +#: .././quota/quota.c:464 +msgid "[-bir] [-gpu] [-hnNv] [-f file] [id|name]..." +msgstr "[-bir] [-gpu] [-hnNv] [-f plik] [id|nazwa]..." -#: .././io/inject.c:109 +#: .././quota/quota.c:465 +msgid "show usage and limits" +msgstr "pokazanie wykorzystania i limitów" + +#: .././quota/report.c:34 .././quota/report.c:648 +msgid "dump quota information for backup utilities" +msgstr "zrzucenie informacji o limitach (quota) dla narzędzi backupowych" + +#: .././quota/report.c:36 #, c-format msgid "" "\n" -" inject errors into the filesystem of the currently open file\n" +" create a backup file which contains quota limits information\n" +" -g -- dump out group quota limits\n" +" -p -- dump out project quota limits\n" +" -u -- dump out user quota limits (default)\n" +" -f -- write the dump out to the specified file\n" "\n" -" Example:\n" -" 'inject readagf' - cause errors on allocation group freespace reads\n" +msgstr "" "\n" -" Causes the kernel to generate and react to errors within XFS, provided\n" -" the XFS kernel code has been built with debugging features enabled.\n" -" With no arguments, displays the list of error injection tags.\n" +" utworzenie pliku kopii zapasowej zawierającego informacje o limitach (quota)\n" +" -g - zrzucenie limitów dla grup\n" +" -p - zrzucenie limitów dla projektów\n" +" -u - zrzucenie limitów dla użytkowników (domyślne)\n" +" -f - zapisanie zrzutu do podanego pliku\n" +"\n" + +#: .././quota/report.c:48 +msgid "[-bir] [-gpu] [-ahntLNU] [-f file]" +msgstr "[-bir] [-gpu] [-ahntLNU] [-f plik]" + +#: .././quota/report.c:49 .././quota/report.c:658 +msgid "report filesystem quota information" +msgstr "raportowanie informacji o limitach (quota) w systemie plików" + +#: .././quota/report.c:51 +#, c-format +msgid "" +"\n" +" report used space and inodes, and quota limits, for a filesystem\n" +" Example:\n" +" 'report -igh'\n" +" (reports inode usage for all groups, in an easy-to-read format)\n" +" This command is the equivalent of the traditional repquota command, which\n" +" prints a summary of the disk usage and quotas for the current filesystem,\n" +" or all filesystems.\n" +" -a -- report for all mounted filesystems with quota enabled\n" +" -h -- report in a human-readable format\n" +" -n -- skip identifier-to-name translations, just report IDs\n" +" -N -- suppress the header from the output\n" +" -t -- terse output format, hides rows which are all zero\n" +" -L -- lower ID bound to report on\n" +" -U -- upper ID bound to report on\n" +" -g -- report group usage and quota information\n" +" -p -- report project usage and quota information\n" +" -u -- report user usage and quota information\n" +" -b -- report blocks-used information only\n" +" -i -- report inodes-used information only\n" +" -r -- report realtime-blocks-used information only\n" "\n" msgstr "" "\n" -" wprowadzenie błędów do systemu plików aktualnie otwartego pliku\n" +" informacje o wykorzystanym miejscu i i-węzłach oraz limitach quota dla systemu\n" +" plików\n" "\n" " Przykład:\n" -" 'inject readagf' - spowodowanie błędów przy odczytach wolnego miejsca grup\n" -" alokacji\n" +" 'report -igh'\n" +" (raport o wykorzystaniu i-węzłów dla wszystkich grup w czytelnym formacie)\n" "\n" -" inject powoduje, że jądro generuje i reaguje na błędy wewnątrz XFS-a,\n" -" pod warunkiem, że kod XFS-a w jądrze został zbudowany z włączonymi opcjami\n" -" diagnostycznymi. Bez argumentów wyświetla listę znaczników wprowadzania\n" -" błędów.\n" +" To polecenie jest odpowiednikiem tradycyjnego polecenia repquota, wypisującego\n" +" podsumowanie wykorzystania dysku i limitów dla bieżącego systemu plików lub\n" +" wszystkich systemów plików.\n" +" -a - informacje o wszystkich zamontowanych systemach plików z limitami\n" +" -h - informacje w formacie czytelnym dla człowieka\n" +" -n - pominięcie tłumaczenia identyfikatorów na nazwy, wypisywanie ID\n" +" -N - pominięcie początkowego nagłówka\n" +" -t - zwięzły format, ukrycie wierszy zerowych\n" +" -L - dolna granica ID dla wypisywanych informacji\n" +" -U - górna granica ID dla wypisywanych informacji\n" +" -g - informacje o wykorzystanym miejscu i limitach dla grup\n" +" -p - informacje o wykorzystanym miejscu i limitach dla projektów\n" +" -u - informacje o wykorzystanym miejscu i limitach dla użytkowników\n" +" -b - tylko informacje o wykorzystanych blokach\n" +" -i - tylko informacje o wykorzystanych i-węzłach\n" +" -r - tylko informacje o wykorzystanych blokach realtime\n" "\n" -#: .././io/inject.c:135 +#: .././quota/report.c:228 #, c-format -msgid "no such tag -- %s\n" -msgstr "nie ma takiego znacznika - %s\n" - -#: .././io/inject.c:156 -msgid "[tag ...]" -msgstr "[znacznik ...]" - -#: .././io/inject.c:157 -msgid "inject errors into a filesystem" -msgstr "wprowadzanie błędów do systemu plików" +msgid "%s quota on %s (%s)\n" +msgstr "limit %s na %s (%s)\n" -#: .././io/getrusage.c:118 -msgid "report process resource usage" -msgstr "informacje o wykorzystaniu zasobów przez proces" +#: .././quota/report.c:253 .././quota/report.c:261 +#, c-format +msgid " Used Soft Hard Warn/Grace " +msgstr " Użyto Miękki Twardy Ostrzeżenie " -#: .././io/freeze.c:37 +#: .././quota/report.c:254 .././quota/report.c:262 #, c-format -msgid "%s: cannot freeze filesystem at %s: %s\n" -msgstr "%s: nie można zamrozić systemu plików na %s: %s\n" +msgid " Used Soft Hard Warn/Grace " +msgstr " Użyto Miękki Twardy Ostrzeżenie " -#: .././io/freeze.c:54 +#: .././quota/report.c:257 #, c-format -msgid "%s: cannot unfreeze filesystem mounted at %s: %s\n" -msgstr "%s: nie można odmrozić systemu plików podmontowanego pod %s: %s\n" +msgid " Used Soft Hard Warn/Grace " +msgstr " Użyto Miękki Twardy Ostrzeżenie" -#: .././io/freeze.c:70 -msgid "freeze filesystem of current file" -msgstr "zamrożenie systemu plików na bieżącym pliku" +#: .././quota/report.c:258 +#, c-format +msgid " Used Soft Hard Warn/ Grace " +msgstr " Użyto Miękki Twardy Ostrzeżenie " -#: .././io/freeze.c:77 -msgid "unfreeze filesystem of current file" -msgstr "odmrożenie systemu plików na bieżącym pliku" +#: .././quota/report.c:657 +msgid "[-bir] [-gpu] [-ahnt] [-f file]" +msgstr "[-bir] [-gpu] [-ahnt] [-f plik]" -#: .././io/fiemap.c:32 +#: .././quota/state.c:33 #, c-format msgid "" "\n" -" prints the block mapping for a file's data or attribute forks\n" +" turn filesystem quota off, both accounting and enforcement\n" +"\n" " Example:\n" -" 'fiemap -v' - tabular format verbose map\n" +" 'off -uv' (switch off user quota on the current filesystem)\n" +" This command is the equivalent of the traditional quotaoff command,\n" +" which disables quota completely on a mounted filesystem.\n" +" Note that there is no 'on' command - for XFS filesystems (with the\n" +" exception of the root filesystem on IRIX) quota can only be enabled\n" +" at mount time, through the use of one of the quota mount options.\n" "\n" -" fiemap prints the map of disk blocks used by the current file.\n" -" The map lists each extent used by the file, as well as regions in the\n" -" file that do not have any corresponding blocks (holes).\n" -" By default, each line of the listing takes the following form:\n" -" extent: [startoffset..endoffset]: startblock..endblock\n" -" Holes are marked by replacing the startblock..endblock with 'hole'.\n" -" All the file offsets and disk blocks are in units of 512-byte blocks.\n" -" -a -- prints the attribute fork map instead of the data fork.\n" -" -l -- also displays the length of each extent in 512-byte blocks.\n" -" -n -- query n extents.\n" -" -v -- Verbose information\n" +" The state command is useful for displaying the current state. Using\n" +" the -v (verbose) option with the 'off' command will display the quota\n" +" state for the affected filesystem once the operation is complete.\n" +" The affected quota type is -g (groups), -p (projects) or -u (users)\n" +" and defaults to user quota (multiple types can be specified).\n" "\n" msgstr "" "\n" -" wypisanie mapowania bloków dla danych lub atrybutów pliku\n" +" wyłączenie podsystemu quota (zarówno rozliczania jak i wymuszania)\n" +"\n" " Przykład:\n" -" 'fiemap -v' - szczegółowa mapa w formacie tabeli\n" +" 'off -uv' (wyłączenie limitów użytkownika w bieżącym systemie plików)\n" "\n" -" fiemap wypisuje mapę bloków dysku używanych przez bieżący plik.\n" -" Mapa opisuje każdy ekstent użyty przez plik, a także regiony w pliku\n" -" nie mające przypisanych bloków (dziury).\n" -" Domyślnie każda linia listingu przyjmuje następującą postać:\n" -" ekstent: [offsetpocz..offsetkońc]: blokpocz..blokkońc\n" -" Dziury są oznaczane przez zastąpienie blokpocz..blokkońc przez 'dziura'.\n" -" Wszystkie offsety w plikach i bloki dysku są w jednostkach 512-bajtowych.\n" -" -a - wypisanie mapy gałęzi atrybutów zamiast gałęzi danych.\n" -" -l - wyświetlenie także długości każdego fragmentu w 512-bajtowych blokach.\n" -" -n - odpytanie n ekstentów.\n" -" -v - szczegółowe informacje\n" +" To polecenie jest odpowiednikiem tradycyjnego polecenia quotaoff,\n" +" wyłączającego całkowicie limity na podmontowanym systemie plików.\n" +" Należy zauważyć, że nie ma polecenia 'on' - dla systemów plików XFS\n" +" (z wyjątkiem głównego systemu plików pod systemem IRIX) limity można\n" +" włączyć wyłącznie na etapie montowania, poprzez użycie jednej z opcji\n" +" quota programu mount.\n" +"\n" +" Polecenie state jest przydatne do wyświetlania aktualnego stanu. Użycie\n" +" opcji -v (szczegółowość) dla polecenia 'off' wyświetli stan quoty dla\n" +" danego systemu plików po zakończeniu operacji.\n" +" Rodzaj limitu którego dotyczy polecenie można wybrać opcją -g (grupy),\n" +" -p (projekty) lub -u (użytkownicy); domyślnie polecenie dotyczy limitów\n" +" użytkowników (można podać wiele rodzajów).\n" "\n" -#: .././io/fiemap.c:97 .././io/fiemap.c:317 .././io/fiemap.c:321 -#: .././io/bmap.c:251 .././io/bmap.c:379 -#, c-format -msgid "hole" -msgstr "dziura" - -#: .././io/fiemap.c:139 .././io/fiemap.c:153 .././io/fiemap.c:323 -#, c-format -msgid " %llu blocks\n" -msgstr " %llu bloków\n" - -#: .././io/fiemap.c:210 .././io/bmap.c:149 +#: .././quota/state.c:56 #, c-format -msgid "%s: malloc of %d bytes failed.\n" -msgstr "%s: przydzielenie %d bajtów nie powiodło się.\n" - -#: .././io/fiemap.c:243 .././io/bmap.c:339 -msgid "EXT" -msgstr "EXT" - -#: .././io/fiemap.c:244 .././io/bmap.c:340 -msgid "FILE-OFFSET" -msgstr "OFFSET-W-PLIKU" - -#: .././io/fiemap.c:245 .././io/bmap.c:341 -msgid "BLOCK-RANGE" -msgstr "ZAKRES-BLOKÓW" - -#: .././io/fiemap.c:246 .././io/bmap.c:344 -msgid "TOTAL" -msgstr "RAZEM" - -#: .././io/fiemap.c:247 -msgid "FLAGS" -msgstr "FLAGI" - -#: .././io/fiemap.c:343 -msgid "[-alv] [-n nx]" -msgstr "[-alv] [-n nx]" - -#: .././io/fiemap.c:344 -msgid "print block mapping for a file" -msgstr "wypisanie mapowania bloków dla pliku" +msgid "" +"\n" +" query the state of quota on the current filesystem\n" +"\n" +" This is a verbose status command, reporting whether or not accounting\n" +" and/or enforcement are enabled for a filesystem, which inodes are in\n" +" use as the quota state inodes, and how many extents and blocks are\n" +" presently being used to hold that information.\n" +" The quota type is specified via -g (groups), -p (projects) or -u (users)\n" +" and defaults to user quota (multiple types can be specified).\n" +"\n" +msgstr "" +"\n" +" odczytanie stanu podsystemu quota w bieżącym systemie plików\n" +"\n" +" Jest to polecenie szczegółowo informujące o stanie, opisujące czy włączone\n" +" jest rozliczanie i/lub wymuszanie limitów w systemie plików, które i-węzły\n" +" są wykorzystywane jako i-węzły stanu quot oraz ile ekstentów i bloków jest\n" +" aktualnie używana do przechowywania tych informacji.\n" +" Rodzaj limitów podaje się opcją -g (grupy), -p (projekty) lub -u (użytkownicy);\n" +" domyślnie polecenie dotyczy limitów użytkowników (można podać wiele rodzajów).\n" +"\n" -#: .././io/imap.c:53 +#: .././quota/state.c:72 #, c-format -msgid "ino %10llu count %2d mask %016llx\n" -msgstr "i-węzeł %10llu liczba %2d maska %016llx\n" - -#: .././io/imap.c:71 -msgid "[nentries]" -msgstr "[liczba_wpisów]" - -#: .././io/imap.c:73 -msgid "inode map for filesystem of current file" -msgstr "map i-węzłów dla systemu plików bieżącego pliku" +msgid "" +"\n" +" enable quota enforcement on a filesystem\n" +"\n" +" If a filesystem is mounted and has quota accounting enabled, but not\n" +" quota enforcement, enforcement can be enabled with this command.\n" +" With the -v (verbose) option, the status of the filesystem will be\n" +" reported after the operation is complete.\n" +" The affected quota type is -g (groups), -p (projects) or -u (users)\n" +" and defaults to user quota (multiple types can be specified).\n" +"\n" +msgstr "" +"\n" +" włączenie wymuszania limitów w systemie plików\n" +"\n" +" Jeśli system plików jest podmontowany i ma włączone rozliczanie limitów,\n" +" ale nie ma wymuszania limitów, można włączyć wymuszanie tym poleceniem.\n" +" Z opcją -v (szczegółowość) po zakończeniu operacji zostanie zraportowany\n" +" stan systemu plików.\n" +" Rodzaj limitów podaje się opcją -g (grupy), -p (projekty) lub -u (użytkownicy);\n" +" domyślnie polecenie dotyczy limitów użytkowników (można podać wiele rodzajów).\n" +"\n" -#: .././io/madvise.c:32 +#: .././quota/state.c:88 #, c-format msgid "" "\n" -" advise the page cache about access patterns expected for a mapping\n" +" disable quota enforcement on a filesystem\n" "\n" -" Modifies page cache behavior when operating on the current mapping.\n" -" The range arguments are required by some advise commands ([*] below).\n" -" With no arguments, the POSIX_MADV_NORMAL advice is implied.\n" -" -d -- don't need these pages (POSIX_MADV_DONTNEED) [*]\n" -" -r -- expect random page references (POSIX_MADV_RANDOM)\n" -" -s -- expect sequential page references (POSIX_MADV_SEQUENTIAL)\n" -" -w -- will need these pages (POSIX_MADV_WILLNEED) [*]\n" -" Notes:\n" -" NORMAL sets the default readahead setting on the file.\n" -" RANDOM sets the readahead setting on the file to zero.\n" -" SEQUENTIAL sets double the default readahead setting on the file.\n" -" WILLNEED forces the maximum readahead.\n" +" If a filesystem is mounted and is currently enforcing quota, this\n" +" provides a mechanism to switch off the enforcement, but continue to\n" +" perform used space (and used inodes) accounting.\n" +" The affected quota type is -g (groups), -p (projects) or -u (users).\n" "\n" msgstr "" "\n" -" doradzenie buforowi stron w sprawie oczekiwanych schematów dostępu do odwzorowań\n" +" wyłączenie wymuszania limitów w systemie plików\n" "\n" -" madvise modyfikuje zachowanie bufora stron przy operacjach na bieżącym\n" -" odwzorowaniu. Niektóre polecenia madvise ([*] poniżej) wymagają podania zakresu.\n" -" Bez argumentów zakłada się doradzenie POSIX_MADV_NORMAL.\n" -" -d - podane strony nie są wymagane (POSIX_MADV_DONTNEED) [*]\n" -" -r - należy oczekiwać losowych odwołań do stron (POSIX_MADV_RANDOM)\n" -" -s - należy oczekiwać sekwencyjnych odwołań do stron (POSIX_MADV_SEQUENTIAL)\n" -" -w - podane strony będą potrzebne (POSIX_MADV_WILLNEED) [*]\n" -" Uwagi:\n" -" NORMAL ustawia domyślną wartość czytania z wyprzedzeniem dla pliku.\n" -" RANDOM ustawia czytanie z wyprzedzeniem dla pliku na zero.\n" -" SEQUENTIAL ustawia podwójną domyślną wartość czytania z wyprzedzeniem.\n" -" WILLNEED wymusza maksymalne czytanie z wyprzedzeniem.\n" +" Jeśli system plików jest podmontowany i aktualnie wymusza przestrzeganie\n" +" limitów, tym poleceniem można wyłączyć wymuszanie, ale nadal pozostawić\n" +" rozliczanie wykorzystanego miejsca (oraz i-węzłów).\n" +" Rodzaj limitów podaje się opcją -g (grupy), -p (projekty) lub -u (użytkownicy).\n" "\n" -#: .././io/madvise.c:87 .././io/mincore.c:48 .././io/mmap.c:206 -#: .././io/mmap.c:301 .././io/mmap.c:387 .././io/mmap.c:546 -#: .././io/prealloc.c:55 .././io/pwrite.c:284 .././io/sendfile.c:126 -#: .././io/fadvise.c:92 +#: .././quota/state.c:102 #, c-format -msgid "non-numeric offset argument -- %s\n" -msgstr "nieliczbowy argument będący offsetem - %s\n" +msgid "" +"\n" +" remove any space being used by the quota subsystem\n" +"\n" +" Once quota has been switched 'off' on a filesystem, the space that\n" +" was allocated to holding quota metadata can be freed via this command.\n" +" The affected quota type is -g (groups), -p (projects) or -u (users)\n" +" and defaults to user quota (multiple types can be specified).\n" +"\n" +msgstr "" +"\n" +" zwolnienie miejsca zajmowanego przez podsystem quota\n" +"\n" +" Po wyłączeniu limitów dla systemu plików można tym poleceniem zwolnić miejsce\n" +" przydzielone na przechowywanie metadanych quot.\n" +" Rodzaj limitów podaje się opcją -g (grupy), -p (projekty) lub -u (użytkownicy);\n" +" domyślnie polecenie dotyczy limitów użytkowników (można podać wiele rodzajów).\n" +"\n" -#: .././io/madvise.c:94 .././io/mincore.c:54 .././io/mmap.c:212 -#: .././io/mmap.c:308 .././io/mmap.c:394 .././io/mmap.c:553 -#: .././io/pread.c:330 .././io/pread.c:338 .././io/prealloc.c:60 -#: .././io/pwrite.c:290 .././io/sendfile.c:133 .././io/fadvise.c:99 +#: .././quota/state.c:121 #, c-format -msgid "non-numeric length argument -- %s\n" -msgstr "nieliczbowy argument będący długością - %s\n" +msgid "%s quota state on %s (%s)\n" +msgstr "stan limitów %s na %s (%s)\n" -#: .././io/madvise.c:98 .././io/mincore.c:58 +#: .././quota/state.c:123 #, c-format -msgid "length argument too large -- %lld\n" -msgstr "zbyt duży argument będący długością - %lld\n" +msgid " Accounting: %s\n" +msgstr " Rozliczanie: %s\n" -#: .././io/madvise.c:127 -msgid "[-drsw] [off len]" -msgstr "[-drsw] [offset długość]" +#: .././quota/state.c:123 .././quota/state.c:124 +msgid "ON" +msgstr "WŁĄCZONE" -#: .././io/madvise.c:128 -msgid "give advice about use of memory" -msgstr "doradzenie w sprawie użycia pamięci" +#: .././quota/state.c:123 .././quota/state.c:124 +msgid "OFF" +msgstr "WYŁĄCZONE" -#: .././io/mincore.c:92 .././io/mincore.c:102 +#: .././quota/state.c:124 #, c-format -msgid "0x%lx %lu pages (%llu : %lu)\n" -msgstr "0x%lx %lu stron (%llu : %lu)\n" - -#: .././io/mincore.c:122 -msgid "[off len]" -msgstr "[offset długość]" - -#: .././io/mincore.c:123 -msgid "find mapping pages that are memory resident" -msgstr "odnalezienie stron odwzorowań przechowywanych w pamięci" +msgid " Enforcement: %s\n" +msgstr " Wymuszanie: %s\n" -#: .././io/mmap.c:76 +#: .././quota/state.c:126 #, c-format -msgid "offset (%lld) is before start of mapping (%lld)\n" -msgstr "offset (%lld) przed początkiem odwzorowania (%lld)\n" +msgid " Inode: #%llu (%llu blocks, %lu extents)\n" +msgstr " I-węzeł: #%llu (%llu bloków, %lu ekstentów)\n" -#: .././io/mmap.c:82 +#: .././quota/state.c:131 #, c-format -msgid "offset (%lld) is beyond end of mapping (%lld)\n" -msgstr "offset (%lld) za końcem odwzorowania (%lld)\n" +msgid " Inode: N/A\n" +msgstr " I-węzeł: N/A\n" -#: .././io/mmap.c:87 +#: .././quota/state.c:140 #, c-format -msgid "range (%lld:%lld) is beyond mapping (%lld:%ld)\n" -msgstr "przedział (%lld:%lld) poza odwzorowaniem (%lld:%ld)\n" +msgid "%s grace time: %s\n" +msgstr "czas pobłażliwości %s: %s\n" -#: .././io/mmap.c:93 +#: .././quota/state.c:157 #, c-format -msgid "offset address (%p) is not page aligned\n" -msgstr "adres offsetu (%p) nie jest wyrównany do rozmiaru strony\n" +msgid "%s quota are not enabled on %s\n" +msgstr "Limity %s nie są włączone na %s\n" -#: .././io/mmap.c:133 -#, c-format -msgid "" -"\n" -" maps a range within the current file into memory\n" -"\n" -" Example:\n" -" 'mmap -rw 0 1m' - maps one megabyte from the start of the current file\n" -"\n" -" Memory maps a range of a file for subsequent use by other xfs_io commands.\n" -" With no arguments, mmap shows the current mappings. The current mapping\n" -" can be set by using the single argument form (mapping number or address).\n" -" If two arguments are specified (a range), a new mapping is created and the\n" -" following options are available:\n" -" -r -- map with PROT_READ protection\n" -" -w -- map with PROT_WRITE protection\n" -" -x -- map with PROT_EXEC protection\n" -" If no protection mode is specified, all are used by default.\n" -"\n" -msgstr "" -"\n" -" odwzorowanie przedziału z bieżącego pliku w pamięci\n" -"\n" -"Przykład:\n" -" 'mmap -rw 0 1m' - odwzorowuje 1MB od początku bieżącego pliku\n" -"\n" -" mmap odwzorowuje w pamięci przedział z pliku do dalszego wykorzystania przez\n" -" inne polecenia xfs_io.\n" -" Bez argumentów mmap pokazuje aktualne odwzorowania. Bieżące odwzorowanie\n" -" można ustawić przy użyciu formy jednoargumentowej (mmap numer lub adres).\n" -" Jeśli podano dwa argumenty (przedział), tworzone jest nowe odwzorowanie\n" -" i dostępne są następujące opcje:\n" -" -r - odwzorowanie z ochroną PROT_READ\n" -" -w - odwzorowanie z ochroną PROT_WRITE\n" -" -x - odwzorowanie z ochroną PROT_EXEC\n" -" Jeśli nie podano trybu ochrony, domyślnie używane są wszystkie.\n" -"\n" +#: .././quota/state.c:527 .././quota/state.c:543 .././quota/state.c:551 +#: .././quota/state.c:559 +msgid "[-gpu] [-v]" +msgstr "[-gpu] [-v]" -#: .././io/mmap.c:167 .././io/mmap.c:174 .././io/init.c:105 -#, c-format -msgid "no mapped regions, try 'help mmap'\n" -msgstr "nie ma podmapowanych regionów, spróbuj 'help mmap'\n" +#: .././quota/state.c:528 +msgid "permanently switch quota off for a path" +msgstr "wyłączenie limitów na stałe dla ścieżki" -#: .././io/mmap.c:168 .././io/mmap.c:175 .././io/mmap.c:178 .././io/init.c:101 -#: .././io/open.c:273 -#, c-format -msgid "no files are open, try 'help open'\n" -msgstr "nie ma otwartych plików, spróbuj 'help open'\n" +#: .././quota/state.c:535 +msgid "[-gpu] [-a] [-v] [-f file]" +msgstr "[-gpu] [-a] [-v] [-f plik]" -#: .././io/mmap.c:254 +#: .././quota/state.c:536 +msgid "get overall quota state information" +msgstr "uzyskanie ogólnych informacji o stanie quot" + +#: .././quota/state.c:544 +msgid "enable quota enforcement" +msgstr "włączenie wymuszania limitów" + +#: .././quota/state.c:552 +msgid "disable quota enforcement" +msgstr "wyłączenie wymuszania limitów" + +#: .././quota/state.c:560 +msgid "remove quota extents from a filesystem" +msgstr "usunięcie ekstentów związanych z limitami z systemu plików" + +#: .././quota/util.c:59 #, c-format -msgid "" -"\n" -" flushes a range of bytes in the current memory mapping\n" -"\n" -" Writes all modified copies of pages over the specified range (or entire\n" -" mapping if no range specified) to their backing storage locations. Also,\n" -" optionally invalidates so that subsequent references to the pages will be\n" -" obtained from their backing storage locations (instead of cached copies).\n" -" -a -- perform asynchronous writes (MS_ASYNC)\n" -" -i -- invalidate mapped pages (MS_INVALIDATE)\n" -" -s -- perform synchronous writes (MS_SYNC)\n" -"\n" -msgstr "" -"\n" -" zrzucenie przedziału bajtów w bieżącym odwzorowaniu pamięci\n" -"\n" -" msync zapisuje wszystkie zmodyfikowane kopie stron z podanego przedziału\n" -" (lub całego odwzorowania, jeśli nie podano przedziału) do miejsca\n" -" przechowywania danych. Opcjonalnie unieważnia bufor, żeby dalsze odwołania\n" -" do tych stron odbywały się z miejsca przechowywania danych (zamiast kopii\n" -" w pamięci podręcznej).\n" -" -a - wykonanie zapisu asynchronicznego (MS_ASYNC)\n" -" -i - unieważnienie odwzorowanych stron (MS_INVALIDATE)\n" -" -s - wykonanie zapisu synchronicznego (MS_SYNC)\n" -"\n" +msgid "[-none-]" +msgstr "[-brak-]" -#: .././io/mmap.c:330 +#: .././quota/util.c:59 #, c-format -msgid "" -"\n" -" reads a range of bytes in the current memory mapping\n" -"\n" -" Example:\n" -" 'mread -v 512 20' - dumps 20 bytes read from 512 bytes into the mapping\n" -"\n" -" Accesses a range of the current memory mapping, optionally dumping it to\n" -" the standard output stream (with -v option) for subsequent inspection.\n" -" -f -- verbose mode, dump bytes with offsets relative to start of file.\n" -" -r -- reverse order; start accessing from the end of range, moving backward\n" -" -v -- verbose mode, dump bytes with offsets relative to start of mapping.\n" -" The accesses are performed sequentially from the start offset by default.\n" -" Notes:\n" -" References to whole pages following the end of the backing file results\n" -" in delivery of the SIGBUS signal. SIGBUS signals may also be delivered\n" -" on various filesystem conditions, including quota exceeded errors, and\n" -" for physical device errors (such as unreadable disk blocks). No attempt\n" -" has been made to catch signals at this stage...\n" -"\n" -msgstr "" -"\n" -" odczytanie przedziału bajtów w bieżącym odwzorowaniu pamięci\n" -"\n" -" Przykład:\n" -" 'mread -v 512 20' - zrzucenie 20 bajtów odczytanych od 512 bajtu\n" -" w odwzorowaniu\n" -"\n" -" mread odwołuje się do przedziału bieżącego odwzorowania pamięci, opcjonalnie\n" -" zrzucając go na strumień standardowego wyjścia (z opcją -v) do dalszych badań.\n" -" -f - tryb szczegółowy, zrzucenie bajtów z offsetami względem początku pliku.\n" -" -r - odwrotna kolejność; dostęp począwszy od końca przedziału do początku.\n" -" -v - tryb szczegółowy, zrzucenie bajtów z offsetami względem początku\n" -" odwzorowania.\n" -" Dostępy są wykonywane sekwencyjnie, domyślnie od offsetu początkowego.\n" -" Uwagi:\n" -" Odwołania do całych stron za końcem pliku powodują w efekcie sygnał SIGBUS.\n" -" Sygnały SIGBUS mogą być wywołane także przy różnych zdarzeniach związanych\n" -" z systemem plików, włącznie z błędami przekroczenia limitów (quota) oraz\n" -" fizycznymi błędami urządzenia (takimi jak nieczytelne bloki dysku). Na tym\n" -" etapie nie ma prób wyłapania sygnałów...\n" -"\n" +msgid "[--none--]" +msgstr "[--brak--]" -#: .././io/mmap.c:494 +#: .././quota/util.c:62 #, c-format -msgid "" -"\n" -" dirties a range of bytes in the current memory mapping\n" -"\n" -" Example:\n" -" 'mwrite 512 20 - writes 20 bytes at 512 bytes into the current mapping.\n" -"\n" -" Stores a byte into memory for a range within a mapping.\n" -" The default stored value is 'X', repeated to fill the range specified.\n" -" -S -- use an alternate seed character\n" -" -r -- reverse order; start storing from the end of range, moving backward\n" -" The stores are performed sequentially from the start offset by default.\n" -"\n" -msgstr "" -"\n" -" zmiana przedziału bajtów w bieżącym odwzorowaniu pamięci\n" -"\n" -" Przykład:\n" -" 'mwrite 512 20' - zapisuje 20 bajtów od 512 bajtu w bieżącym odwzorowaniu.\n" -"\n" -" mwrite zapisuje bajt do przedziału pamięci w ramach odwzorowania.\n" -" Domyślnie zapisywaną wartością jest 'X', powtarzane do wypełnienia przedziału.\n" -" -S - użycie alternatywnego znaku\n" -" -r - odwrotna kolejność; rozpoczęcie zapisywania od końca przedziału do\n" -" początku\n" -" Zapisy są wykonywane kolejno, domyślnie od offsetu początkowego.\n" -"\n" +msgid "[------]" +msgstr "[------]" -#: .././io/mmap.c:530 .././io/pread.c:315 .././io/pwrite.c:251 -#: .././io/pwrite.c:270 +#: .././quota/util.c:62 #, c-format -msgid "non-numeric seed -- %s\n" -msgstr "nieliczbowy zarodek - %s\n" +msgid "[--------]" +msgstr "[--------]" -#: .././io/mmap.c:586 -msgid "[N] | [-rwx] [off len]" -msgstr "[N] | [-rwx] [offset długość]" +# XXX: ngettext() +#: .././quota/util.c:66 .././quota/util.c:69 +msgid "day" +msgstr "dzień" -#: .././io/mmap.c:588 -msgid "mmap a range in the current file, show mappings" -msgstr "odwzorowanie przedziału w bieżącym pliku, pokazanie odwzorowań" +#: .././quota/util.c:66 .././quota/util.c:69 +msgid "days" +msgstr "dni" -#: .././io/mmap.c:597 -msgid "[-r] [off len]" -msgstr "[-r] [offset długość]" +#: .././quota/util.c:194 +msgid "Blocks" +msgstr "Bloki" -#: .././io/mmap.c:599 -msgid "reads data from a region in the current memory mapping" -msgstr "odczyt danych z regionu w bieżącym odwzorowaniu pamięci" +#: .././quota/util.c:194 +msgid "Inodes" +msgstr "I-węzły" -#: .././io/mmap.c:608 -msgid "[-ais] [off len]" -msgstr "[-ais] [offset długość]" +#: .././quota/util.c:194 +msgid "Realtime Blocks" +msgstr "Bloki realtime" -#: .././io/mmap.c:609 -msgid "flush a region in the current memory mapping" -msgstr "zrzucenie regionu w bieżącym odwzorowaniu pamięci" +#: .././quota/util.c:209 +msgid "User" +msgstr "użytkowników" -#: .././io/mmap.c:618 -msgid "unmaps the current memory mapping" -msgstr "usunięcie bieżącego odwzorowania pamięci" +#: .././quota/util.c:209 +msgid "Group" +msgstr "grup" -#: .././io/mmap.c:626 -msgid "[-r] [-S seed] [off len]" -msgstr "[-r] [-S wartość] [offset długość]" +#: .././quota/util.c:209 +msgid "Project" +msgstr "projektów" -#: .././io/mmap.c:628 -msgid "writes data into a region in the current memory mapping" -msgstr "zapis danych do regionu w bieżącym odwzorowaniu pamięci" +#: .././quota/util.c:417 +#, c-format +msgid "%s: open on %s failed: %s\n" +msgstr "%s: open dla %s nie powiodło się: %s\n" -#: .././io/parent.c:49 +#: .././quota/util.c:423 #, c-format -msgid "%s%s" -msgstr "%s%s" +msgid "%s: fdopen on %s failed: %s\n" +msgstr "%s: fdopen dla %s nie powiodło się: %s\n" -#: .././io/parent.c:54 +#: .././repair/agheader.c:40 #, c-format -msgid "inode-path for inode: %llu is incorrect - path \"%s\" non-existent\n" -msgstr "inode-path dla i-węzła: %llu jest niepoprawna - ścieżka \"%s\" nie istnieje\n" +msgid "bad magic # 0x%x for agf %d\n" +msgstr "błędna liczba magiczna 0x%x dla agf %d\n" -#: .././io/parent.c:58 +#: .././repair/agheader.c:49 #, c-format -msgid "path \"%s\" does not stat for inode: %llu; err = %s\n" -msgstr "ścieżka \"%s\" nie pozwala na stat dla i-węzła: %llu; błąd = %s\n" +msgid "bad version # %d for agf %d\n" +msgstr "błędny numer wersji %d dla agf %d\n" -#: .././io/parent.c:67 +#: .././repair/agheader.c:58 #, c-format -msgid "path \"%s\" found\n" -msgstr "ścieżki \"%s\" nie znaleziono\n" +msgid "bad sequence # %d for agf %d\n" +msgstr "błędny numer sekwencji %d dla agf %d\n" -#: .././io/parent.c:73 +#: .././repair/agheader.c:68 #, c-format -msgid "inode-path for inode: %llu is incorrect - wrong inode#\n" -msgstr "inode-path dla i-węzła: %llu jest niepoprawna - niewłaściwy numer i-węzła\n" +msgid "bad length %d for agf %d, should be %d\n" +msgstr "błędna długość %d dla agf %d, powinno być %d\n" -#: .././io/parent.c:77 .././io/parent.c:107 +#: .././repair/agheader.c:81 #, c-format -msgid "ino mismatch for path \"%s\" %llu vs %llu\n" -msgstr "niezgodność i-węzła dla ścieżki \"%s\" %llu vs %llu\n" +msgid "bad length %d for agf %d, should be %\n" +msgstr "błędna długość %d dla agf %d, powinno być %\n" -#: .././io/parent.c:85 +#: .././repair/agheader.c:95 #, c-format -msgid "inode number match: %llu\n" -msgstr "zgodność numeru i-węzła: %llu\n" +msgid "flfirst %d in agf %d too large (max = %zu)\n" +msgstr "flfirst %d w agf %d zbyt duże (maksimum = %zu)\n" -#: .././io/parent.c:95 +#: .././repair/agheader.c:103 #, c-format -msgid "parent path \"%s\" does not stat: %s\n" -msgstr "ścieżka nadrzędna \"%s\" nie pozwala na stat: %s\n" +msgid "fllast %d in agf %d too large (max = %zu)\n" +msgstr "fllast %d w agf %d zbyt duże (maksimum = %zu)\n" -#: .././io/parent.c:103 +#: .././repair/agheader.c:120 #, c-format -msgid "inode-path for inode: %llu is incorrect - wrong parent inode#\n" -msgstr "inode-path dla i-węzła: %llu jest niepoprawna - niewłaściwy numer i-węzła nadrzędnego\n" +msgid "bad uuid %s for agf %d\n" +msgstr "błędny uuid %s dla agf %d\n" -#: .././io/parent.c:116 +#: .././repair/agheader.c:138 #, c-format -msgid "parent ino match for %llu\n" -msgstr "zgodność numeru i-węzła nadrzędnego dla %llu\n" +msgid "bad magic # 0x%x for agi %d\n" +msgstr "błędna liczba magiczna 0x%x dla agi %d\n" -#: .././io/parent.c:138 +#: .././repair/agheader.c:147 #, c-format -msgid "parentpaths failed for ino %llu: %s\n" -msgstr "parentpaths nie powiodło się dla i-węzła %llu: %s\n" +msgid "bad version # %d for agi %d\n" +msgstr "błędny numer wersji %d dla agi %d\n" -#: .././io/parent.c:149 +#: .././repair/agheader.c:156 #, c-format -msgid "inode-path for inode: %llu is missing\n" -msgstr "brak inode-path dla i-węzła: %llu\n" +msgid "bad sequence # %d for agi %d\n" +msgstr "błędny numer sekwencji %d dla agi %d\n" -#: .././io/parent.c:173 +#: .././repair/agheader.c:166 #, c-format -msgid "can't stat mount point \"%s\": %s\n" -msgstr "nie można wykonać stat na punkcie montowania \"%s\": %s\n" +msgid "bad length # %d for agi %d, should be %d\n" +msgstr "błędna długość %d dla agi %d, powinno być %d\n" -#: .././io/parent.c:194 +#: .././repair/agheader.c:179 #, c-format -msgid "failed to get bulkstat information for inode %llu\n" -msgstr "nie udało się uzyskać informacji bulkstat dla i-węzła %llu\n" +msgid "bad length # %d for agi %d, should be %\n" +msgstr "błędna długość %d dla agi %d, powinno być %\n" -#: .././io/parent.c:200 +#: .././repair/agheader.c:198 #, c-format -msgid "failed to get valid bulkstat information for inode %llu\n" -msgstr "nie udało się uzyskać prawidłowych informacji bulkstat dla i-węzła %llu\n" +msgid "bad uuid %s for agi %d\n" +msgstr "błędny uuid %s dla agi %d\n" -#: .././io/parent.c:212 +#: .././repair/agheader.c:302 #, c-format -msgid "checking inode %llu\n" -msgstr "sprawdzanie i-węzła %llu\n" +msgid "zeroing unused portion of %s superblock (AG #%u)\n" +msgstr "zerowanie nieużywanej części superbloku %s (AG #%u)\n" -#: .././io/parent.c:227 -#, c-format -msgid "syssgi bulkstat failed: %s\n" -msgstr "syssgi bulkstat nie powiodło się: %s\n" +#: .././repair/agheader.c:303 .././repair/agheader.c:318 +msgid "primary" +msgstr "głównego" -#: .././io/parent.c:249 -#, c-format -msgid "unable to open \"%s\" for jdm: %s\n" -msgstr "nie udało się otworzyć \"%s\" dla jdm: %s\n" +#: .././repair/agheader.c:303 .././repair/agheader.c:318 +msgid "secondary" +msgstr "zapasowego" -#: .././io/parent.c:259 +#: .././repair/agheader.c:317 #, c-format -msgid "unable to allocate buffers: %s\n" -msgstr "nie udało się przydzielić buforów: %s\n" +msgid "would zero unused portion of %s superblock (AG #%u)\n" +msgstr "nieużywana część superbloku %s (AG #%u) zostałaby wyzerowana\n" -#: .././io/parent.c:268 +#: .././repair/agheader.c:335 #, c-format -msgid "num errors: %d\n" -msgstr "liczba błędów: %d\n" +msgid "bad flags field in superblock %d\n" +msgstr "błędne pole flag w superbloku %d\n" -#: .././io/parent.c:270 +#: .././repair/agheader.c:358 #, c-format -msgid "succeeded checking %llu inodes\n" -msgstr "udało się sprawdzić %llu i-węzłów\n" +msgid "non-null user quota inode field in superblock %d\n" +msgstr "niezerowe pole i-węzła limitów użytkowników w superbloku %d\n" -#: .././io/parent.c:281 +#: .././repair/agheader.c:373 #, c-format -msgid "p_ino = %llu\n" -msgstr "p_ino = %llu\n" +msgid "non-null group quota inode field in superblock %d\n" +msgstr "niezerowe pole i-węzła limitów grup w superbloku %d\n" -#: .././io/parent.c:282 +#: .././repair/agheader.c:388 #, c-format -msgid "p_gen = %u\n" -msgstr "p_gen = %u\n" +msgid "non-null project quota inode field in superblock %d\n" +msgstr "niezerowe pole i-węzła limitów projektu w superbloku %d\n" -#: .././io/parent.c:283 +#: .././repair/agheader.c:400 #, c-format -msgid "p_reclen = %u\n" -msgstr "p_reclen = %u\n" +msgid "non-null quota flags in superblock %d\n" +msgstr "niezerowe flagi limitów w superbloku %d\n" -#: .././io/parent.c:285 +#: .././repair/agheader.c:418 #, c-format -msgid "p_name = \"%s%s\"\n" -msgstr "p_name = \"%s%s\"\n" +msgid "bad shared version number in superblock %d\n" +msgstr "błędny numer wersji dzielonej w superbloku %d\n" -#: .././io/parent.c:287 +#: .././repair/agheader.c:430 #, c-format -msgid "p_name = \"%s\"\n" -msgstr "p_name = \"%s\"\n" +msgid "bad inode alignment field in superblock %d\n" +msgstr "błędne pole wyrównania i-węzłów w superbloku %d\n" -#: .././io/parent.c:309 +#: .././repair/agheader.c:443 #, c-format -msgid "%s: failed path_to_fshandle \"%s\": %s\n" -msgstr "%s: path_to_fshandle nie powiodło się dla \"%s\": %s\n" +msgid "bad stripe unit/width fields in superblock %d\n" +msgstr "błędne pola jednostki/szerokości pasa w superbloku %d\n" -#: .././io/parent.c:316 +#: .././repair/agheader.c:461 #, c-format -msgid "%s: path_to_handle failed for \"%s\"\n" -msgstr "%s: path_to_handle nie powiodło się dla \"%s\"\n" +msgid "bad log/data device sector size fields in superblock %d\n" +msgstr "błędne pola rozmiaru sektora urządzenia logu/danych w superbloku %d\n" -#: .././io/parent.c:323 +#: .././repair/agheader.c:492 #, c-format -msgid "%s: unable to allocate parent buffer: %s\n" -msgstr "%s: nie udało się przydzielić bufora nadrzędnego: %s\n" +msgid "bad on-disk superblock %d - %s\n" +msgstr "błędny superblok %d na dysku - %s\n" -#: .././io/parent.c:344 +#: .././repair/agheader.c:499 #, c-format -msgid "%s: %s call failed for \"%s\": %s\n" -msgstr "%s: wywołanie %s nie powiodło się dla \"%s\": %s\n" +msgid "primary/secondary superblock %d conflict - %s\n" +msgstr "konflikt głównego/zapasowego superbloku %d - %s\n" -#: .././io/parent.c:353 +#: .././repair/attr_repair.c:110 #, c-format -msgid "%s: inode-path is missing\n" -msgstr "%s: brak inode-path\n" +msgid "bad range claimed [%d, %d) in da block\n" +msgstr "błędny przedział [%d, %d) przypisany w bloku da\n" -#: .././io/parent.c:384 +#: .././repair/attr_repair.c:117 #, c-format -msgid "file argument, \"%s\", is not in a mounted XFS filesystem\n" -msgstr "argument plikowy \"%s\" nie jest na podmontowanym systemie plików XFS\n" +msgid "byte range end [%d %d) in da block larger than blocksize %d\n" +msgstr "koniec przedziału bajtów [%d %d) w bloku da większy niż rozmiar bloku %d\n" -#: .././io/parent.c:424 +#: .././repair/attr_repair.c:124 #, c-format -msgid "" -"\n" -" list the current file's parents and their filenames\n" -"\n" -" -c -- check the current file's file system for parent consistency\n" -" -p -- list the current file's parents and their full paths\n" -" -v -- verbose mode\n" -"\n" -msgstr "" -"\n" -" wypisanie rodziców bieżącego pliku i ich nazw\n" -"\n" -" -c - sprawdzenie systemu plików pod kątem spójności rodziców pliku\n" -" -p - wypisanie rodziców bieżącego pliku i ich pełnych ścieżek\n" -" -v - tryb szczegółowy\n" -"\n" - -#: .././io/parent.c:440 -msgid "[-cpv]" -msgstr "[-cpv]" - -#: .././io/parent.c:442 -msgid "print or check parent inodes" -msgstr "wypisanie lub sprawdzenie i-węzłów nadrzędnych" +msgid "multiply claimed byte %d in da block\n" +msgstr "wielokrotnie użyty bajt %d w bloku da\n" -#: .././io/pread.c:32 +#: .././repair/attr_repair.c:177 #, c-format -msgid "" -"\n" -" reads a range of bytes in a specified block size from the given offset\n" -"\n" -" Example:\n" -" 'pread -v 512 20' - dumps 20 bytes read from 512 bytes into the file\n" -"\n" -" Reads a segment of the currently open file, optionally dumping it to the\n" -" standard output stream (with -v option) for subsequent inspection.\n" -" The reads are performed in sequential blocks starting at offset, with the\n" -" blocksize tunable using the -b option (default blocksize is 4096 bytes),\n" -" unless a different pattern is requested.\n" -" -B -- read backwards through the range from offset (backwards N bytes)\n" -" -F -- read forwards through the range of bytes from offset (default)\n" -" -v -- be verbose, dump out buffers (used when reading forwards)\n" -" -R -- read at random offsets in the range of bytes\n" -" -Z N -- zeed the random number generator (used when reading randomly)\n" -" (heh, zorry, the -s/-S arguments were already in use in pwrite)\n" -" When in \"random\" mode, the number of read operations will equal the\n" -" number required to do a complete forward/backward scan of the range.\n" -" Note that the offset within the range is chosen at random each time\n" -" (an offset may be read more than once when operating in this mode).\n" -"\n" -msgstr "" -"\n" -" odczytanie przedziału bajtów w podanym rozmiarze bloku od podanego offsetu\n" -"\n" -" Przykład:\n" -" 'pread -v 512 20' - zrzucenie 20 bajtów odczytanych od 512 bajtu w pliku\n" -"\n" -" pread odczytuje segment aktualnie otwartego pliku, opcjonalnie zrzucając\n" -" zawartość na strumień standardowego wyjścia (z opcją -v) dla dalszych badań.\n" -" Odczyty są wykonywane sekwencyjnie blokami począwszy od offsetu z rozmiarem\n" -" bloku ustawianym przy użyciu opcji -b (domyślny rozmiar bloku to 4096 bajtów),\n" -" chyba że zażądano innego schematu.\n" -" -B - odczyt przedziału od tyłu począwszy od offsetu (N bajtów do tyłu)\n" -" -F - odczyt przedziału od przodu począwszy od offsetu (domyślny)\n" -" -v - tryb szczegółowy, zrzucenie bufora (przy odczycie od przodu)\n" -" -R - odczyt losowych offsetów z przedziału bajtów\n" -" -Z N - (\"zeed\") nakarmienie generatora liczb losowych (przy odczycie losowym)\n" -" (nieztety opcje -s/-S pasujące do \"seed\" były już zajęte w pwrite)\n" -" W przypadku trybu losowego liczba operacji odczytu będzie równa liczbie\n" -" potrzebnej do pełnego przeskanowania od przodu lub od tyłu całego przedziału.\n" -" Należy zauważyć, że offset w przedziale jest wybierany za każdym razem losowo\n" -" (dowolny offset może być w tym trybie czytany więcej niż raz).\n" -"\n" +msgid "can't read block %u (fsbno %) for directory inode %\n" +msgstr "nie można odczytać bloku %u (fsbno %) dla i-węzła katalogu %\n" -#: .././io/pread.c:286 .././io/pwrite.c:217 +#: .././repair/attr_repair.c:181 #, c-format -msgid "non-numeric bsize -- %s\n" -msgstr "nieliczbowy rozmiar bloku - %s\n" +msgid "can't read block %u (fsbno %) for attrbute fork of inode %\n" +msgstr "nie można odczytać bloku %u (fsbno %) dla gałęzi atrybutów i-węzła %\n" -#: .././io/pread.c:375 +#: .././repair/attr_repair.c:192 #, c-format -msgid "read %lld/%lld bytes at offset %lld\n" -msgstr "odczytano %lld/%lld bajtów od offsetu %lld\n" +msgid "bad dir/attr magic number in inode %, file bno = %u, fsbno = %\n" +msgstr "błędna liczba magiczna katalogu/atrybutu w i-węźle %, bno pliku = %u, fsbno = %\n" -#: .././io/pread.c:377 .././io/pwrite.c:336 .././io/sendfile.c:163 +#: .././repair/attr_repair.c:200 .././repair/dir2.c:205 #, c-format -msgid "%s, %d ops; %s (%s/sec and %.4f ops/sec)\n" -msgstr "%s, %d operacji; %s (%s/sek i %.4f operacji/sek)\n" - -#: .././io/pread.c:396 -msgid "[-b bs] [-v] off len" -msgstr "[-b rozm_bloku] [-v] offset długość" - -#: .././io/pread.c:397 -msgid "reads a number of bytes at a specified offset" -msgstr "odczyt podanej liczby bajtów od podanego offsetu" - -#: .././io/prealloc.c:216 .././io/prealloc.c:224 .././io/prealloc.c:232 -#: .././io/prealloc.c:240 .././io/prealloc.c:250 .././io/prealloc.c:276 -msgid "off len" -msgstr "offset długość" - -#: .././io/prealloc.c:217 -msgid "allocates zeroed space for part of a file" -msgstr "przydzielenie wyzerowanej przestrzeni dla części pliku" +msgid "bad record count in inode %, count = %d, max = %d\n" +msgstr "błędna liczba rekordów w i-węźle %, liczba = %d, maksimum = %d\n" -#: .././io/prealloc.c:225 -msgid "frees space associated with part of a file" -msgstr "zwolnienie miejsca związanego z częścią pliku" +#: .././repair/attr_repair.c:219 .././repair/dir2.c:229 +#, c-format +msgid "bad directory btree for directory inode %\n" +msgstr "błędne b-drzewo katalogu dla i-węzła katalogu %\n" -#: .././io/prealloc.c:234 -msgid "reserves space associated with part of a file" -msgstr "zarezerwowanie miejsca związanego z częścią pliku" +#: .././repair/attr_repair.c:223 +#, c-format +msgid "bad attribute fork btree for inode %\n" +msgstr "błędne b-drzewo gałęzi atrybutów dla i-węzła %\n" -#: .././io/prealloc.c:243 -msgid "frees reserved space associated with part of a file" -msgstr "zwolnienie zarezerwowanego miejsca związanego z częścią pliku" +#: .././repair/attr_repair.c:276 +#, c-format +msgid "release_da_cursor_int got unexpected non-null bp, dabno = %u\n" +msgstr "release_da_cursor_int otrzymało nieoczekiwany niepusty bp, dabno = %u\n" -#: .././io/prealloc.c:252 -msgid "Converts the given range of a file to allocated zeros" -msgstr "Zamiana podanego przedziału pliku na przydzielone zera" +#: .././repair/attr_repair.c:348 +#, c-format +msgid "directory/attribute block used/count inconsistency - %d/%hu\n" +msgstr "niespójność wartości used/count bloku katalogu/atrybutu - %d/%hu\n" -#: .././io/prealloc.c:266 -msgid "[-k] [-p] off len" -msgstr "[-k] [-p] offset długość" +#: .././repair/attr_repair.c:358 .././repair/dir2.c:354 +#, c-format +msgid "directory/attribute block hashvalue inconsistency, expected > %u / saw %u\n" +msgstr "niespójność wartości hasza bloku katalogu/atrybutu - oczekiwano > %u, widziano %u\n" -#: .././io/prealloc.c:268 -msgid "allocates space associated with part of a file via fallocate" -msgstr "przydzielenie miejsca powiązanego z częścią pliku przez fallocate" +#: .././repair/attr_repair.c:365 .././repair/dir2.c:361 +#, c-format +msgid "bad directory/attribute forward block pointer, expected 0, saw %u\n" +msgstr "błędny wskaźnik bloku w przód katalogu/atrybutu - oczekiwano 0, widziano %u\n" -#: .././io/prealloc.c:278 -msgid "de-allocates space assocated with part of a file via fallocate" -msgstr "zwolnienie miejsca powiązanego z częścią pliku przez fallocate" +#: .././repair/attr_repair.c:371 +#, c-format +msgid "bad directory block in dir ino %\n" +msgstr "błędny blok katalogu w i-węźle katalogu %\n" -#: .././io/pwrite.c:31 +#: .././repair/attr_repair.c:399 #, c-format msgid "" -"\n" -" writes a range of bytes (in block size increments) from the given offset\n" -"\n" -" Example:\n" -" 'pwrite 512 20' - writes 20 bytes at 512 bytes into the open file\n" -"\n" -" Writes into a segment of the currently open file, using either a buffer\n" -" filled with a set pattern (0xcdcdcdcd) or data read from an input file.\n" -" The writes are performed in sequential blocks starting at offset, with the\n" -" blocksize tunable using the -b option (default blocksize is 4096 bytes),\n" -" unless a different write pattern is requested.\n" -" -S -- use an alternate seed number for filling the write buffer\n" -" -i -- input file, source of data to write (used when writing forward)\n" -" -d -- open the input file for direct IO\n" -" -s -- skip a number of bytes at the start of the input file\n" -" -w -- call fdatasync(2) at the end (included in timing results)\n" -" -W -- call fsync(2) at the end (included in timing results)\n" -" -B -- write backwards through the range from offset (backwards N bytes)\n" -" -F -- write forwards through the range of bytes from offset (default)\n" -" -R -- write at random offsets in the specified range of bytes\n" -" -Z N -- zeed the random number generator (used when writing randomly)\n" -" (heh, zorry, the -s/-S arguments were already in use in pwrite)\n" -"\n" +"correcting bad hashval in non-leaf dir/attr block\n" +"\tin (level %d) in inode %.\n" msgstr "" -"\n" -" zapisanie przedziału bajtów w podanym rozmiarze bloku od podanego offsetu\n" -"\n" -" Przykład:\n" -" 'pwrite 512 20' - zapisanie 20 bajtów odczytanych od 512 bajtu w pliku\n" -"\n" -" pwrite zapisuje segment aktualnie otwartego pliku, używając bufora wypełnionego\n" -" ustawionym wzorcem (0xcdcdcdcd) lub danymi odczytanymi z pliku wejściowego.\n" -" Zapisy są wykonywane sekwencyjnie blokami począwszy od offsetu z rozmiarem\n" -" bloku ustawianym przy użyciu opcji -b (domyślny rozmiar bloku to 4096 bajtów),\n" -" chyba że zażądano innego schematu.\n" -" -S - użycie innej liczby do wypełnienia bufora zapisu\n" -" -i - plik wejściowy, źródło danych do zapisania (przy pisaniu od przodu)\n" -" -d - otwarcie pliku wejściowego dla bezpośredniego we/wy\n" -" -s - pominięcie podanej liczby bajtów od początku pliku wejściowego\n" -" -w - wywołanie fdatasync(2) na końcu (wliczane w wyniki czasowe)\n" -" -W - wywołanie fsync(2) na końcu (wliczane w wyniki czasowe)\n" -" -B - zapis przedziału od tyłu począwszy od offsetu (N bajtów do tyłu)\n" -" -F - zapis przedziału od przodu począwszy od offsetu (domyślny)\n" -" -R - zapis losowych offsetów z przedziału bajtów\n" -" -Z N - (\"zeed\") nakarmienie generatora liczb losowych (przy zapisie losowym)\n" -" (nieztety opcje -s/-S pasujące do \"seed\" były już zajęte w pwrite)\n" -"\n" +"poprawiono błędne hashval w bloku katalogu/atrybutu nie będącego liściem\n" +"\tw i-węźle (poziomu %d) %.\n" -#: .././io/pwrite.c:244 +#: .././repair/attr_repair.c:407 #, c-format -msgid "non-numeric skip -- %s\n" -msgstr "nieliczbowy liczba bajtów do pominięcia - %s\n" +msgid "" +"would correct bad hashval in non-leaf dir/attr block\n" +"\tin (level %d) in inode %.\n" +msgstr "" +"błędne hashval zostałoby poprawione w bloku katalogu/atrybutu nie będącego liściem\n" +"\tw i-węźle (poziomu %d) %.\n" -#: .././io/pwrite.c:334 +#: .././repair/attr_repair.c:549 .././repair/dir2.c:530 #, c-format -msgid "wrote %lld/%lld bytes at offset %lld\n" -msgstr "zapisano %lld/%lld bajtów od offsetu %lld\n" - -#: .././io/pwrite.c:359 -msgid "[-i infile [-d] [-s skip]] [-b bs] [-S seed] [-wW] off len" -msgstr "[-i plik_wej [-d] [-s do_pominięcia]] [-b rozm_bloku] [-S zarodek] [-wW] offset długość" +msgid "can't get map info for block %u of directory inode %\n" +msgstr "nie można uzyskać informacji o mapie dla bloku %u i-węzła katalogu %\n" -#: .././io/pwrite.c:361 -msgid "writes a number of bytes at a specified offset" -msgstr "zapis podanej liczby bajtów od podanego offsetu" +#: .././repair/attr_repair.c:559 +#, c-format +msgid "can't read block %u (%) for directory inode %\n" +msgstr "nie można odczytać bloku %u (%) dla i-węzła katalogu %\n" -#: .././io/resblks.c:39 +#: .././repair/attr_repair.c:575 #, c-format -msgid "non-numeric argument -- %s\n" -msgstr "nieliczbowy argument - %s\n" +msgid "bad magic number %x in block %u (%) for directory inode %\n" +msgstr "błędna liczba magiczna %x w bloku %u (%) dla i-węzła katalogu %\n" -#: .././io/resblks.c:51 +#: .././repair/attr_repair.c:582 #, c-format -msgid "reserved blocks = %llu\n" -msgstr "zarezerwowane bloki = %llu\n" +msgid "bad back pointer in block %u (%) for directory inode %\n" +msgstr "błędny wskaźnik wstecz w bloku %u (%) dla i-węzła katalogu %\n" -#: .././io/resblks.c:53 +#: .././repair/attr_repair.c:588 #, c-format -msgid "available reserved blocks = %llu\n" -msgstr "dostępne zarezerwowane bloki = %llu\n" +msgid "entry count %d too large in block %u (%) for directory inode %\n" +msgstr "liczba wpisów %d zbyt duża w bloku %u (%) dla i-węzła katalogu %\n" -#: .././io/resblks.c:66 -msgid "[blocks]" -msgstr "[bloki]" +#: .././repair/attr_repair.c:595 +#, c-format +msgid "bad level %d in block %u (%) for directory inode %\n" +msgstr "błędny poziom %d w bloku %u (%) dla i-węzła katalogu %\n" -#: .././io/resblks.c:68 -msgid "get and/or set count of reserved filesystem blocks" -msgstr "pobranie i/lub ustawienie liczby zarezerwowanych bloków w systemie plików" +#: .././repair/attr_repair.c:660 +#, c-format +msgid "" +"correcting bad hashval in interior dir/attr block\n" +"\tin (level %d) in inode %.\n" +msgstr "" +"poprawiono błędne hashval w wewnętrznym bloku katalogu/atrybutu\n" +"\tw i-węźle (poziomu %d) %.\n" -#: .././io/sendfile.c:32 +#: .././repair/attr_repair.c:668 #, c-format msgid "" -"\n" -" transfer a range of bytes from the given offset between files\n" -"\n" -" Example:\n" -" 'send -f 2 512 20' - writes 20 bytes at 512 bytes into the open file\n" -"\n" -" Copies data between one file descriptor and another. Because this copying\n" -" is done within the kernel, sendfile does not need to transfer data to and\n" -" from user space.\n" -" -f -- specifies an input file from which to source data to write\n" -" -i -- specifies an input file name from which to source data to write.\n" -" An offset and length in the source file can be optionally specified.\n" -"\n" +"would correct bad hashval in interior dir/attr block\n" +"\tin (level %d) in inode %.\n" msgstr "" -"\n" -" przesłanie między plikami przedziału bajtów od podanego offsetu\n" -"\n" -" Przykład:\n" -" 'send -f 2 512 20' - zapisanie 20 bajtów od 512 bajtu do otwartego pliku\n" -"\n" -" sendfile kopiuje dane między jednym deskryptorem pliku a innym. Ponieważ to\n" -" kopiowanie jest wykonywane przez jądro, sendfile nie potrzebuje przesyłać\n" -" danych do i z przestrzeni użytkownika.\n" -" -f - podanie plików wejściowego z którego dane mają być czytane\n" -" -i - podanie nazwy pliku wejściowego z którego dane mają być czytane\n" -" Opcjonalnie można podać offset i długość danych w pliku źródłowym.\n" -"\n" +"błędne hashval zostałoby poprawione w wewnętrznym bloku katalogu/atrybutu\n" +"\tw i-węźle (poziomu %d) %.\n" -#: .././io/sendfile.c:161 +#: .././repair/attr_repair.c:755 +msgid "No memory for ACL check!\n" +msgstr "Brak pamięci na sprawdzenie ACL!\n" + +#: .././repair/attr_repair.c:763 +msgid "entry contains illegal value in attribute named SGI_ACL_FILE or SGI_ACL_DEFAULT\n" +msgstr "wpis zawiera niedozwoloną wartość w atrybucie SGI_ACL_FILE lub SGI_ACL_DEFAULT\n" + +#: .././repair/attr_repair.c:789 +msgid "entry contains illegal value in attribute named SGI_MAC_LABEL\n" +msgstr "wpis zawiera niedozwoloną wartość w atrybucie SGI_MAC_LABEL\n" + +#: .././repair/attr_repair.c:795 +msgid "entry contains illegal value in attribute named SGI_CAP_FILE\n" +msgstr "wpis zawiera niedozwoloną wartość w atrybucie SGI_CAP_FILE\n" + +#: .././repair/attr_repair.c:835 #, c-format -msgid "sent %lld/%lld bytes from offset %lld\n" -msgstr "przesłano %lld/%lld bajtów od offsetu %lld\n" +msgid "there are no attributes in the fork for inode %\n" +msgstr "nie ma atrybutów w gałęzi dla i-węzła %\n" -#: .././io/sendfile.c:186 -msgid "-i infile | -f N [off len]" -msgstr "-i plik_wej | -f N [offset długość]" +#: .././repair/attr_repair.c:843 +#, c-format +msgid "would junk the attribute fork since count is 0 for inode %\n" +msgstr "gałąź atrybutów zostałaby usunięta ponieważ licznik wynosi 0 dla i-węzła %\n" -#: .././io/sendfile.c:188 -msgid "Transfer data directly between file descriptors" -msgstr "Przesłanie danych bezpośrednio między deskryptorami plików" +#: .././repair/attr_repair.c:863 +msgid "zero length name entry in attribute fork," +msgstr "wpis nazwy zerowej długości w gałęzi atrybutów," -#: .././io/shutdown.c:59 -msgid "[-f]" -msgstr "[-f]" +#: .././repair/attr_repair.c:866 .././repair/attr_repair.c:886 +#, c-format +msgid " truncating attributes for inode % to %d\n" +msgstr " ucięto atrybuty dla i-węzła % do %d\n" -#: .././io/shutdown.c:61 -msgid "shuts down the filesystem where the current file resides" -msgstr "wyłączenie systemu plików na którym znajduje się bieżący plik" +#: .././repair/attr_repair.c:871 .././repair/attr_repair.c:892 +#, c-format +msgid " would truncate attributes for inode % to %d\n" +msgstr " atrybuty dla i-węzła % zostałyby ucięte do %d\n" -#: .././io/truncate.c:38 +#: .././repair/attr_repair.c:883 +msgid "name or value attribute lengths are too large,\n" +msgstr "długości nazwy lub wartości atrybutów są zbyt duże,\n" + +#: .././repair/attr_repair.c:905 +msgid "entry contains illegal character in shortform attribute name\n" +msgstr "wpis zawiera niedozwolony znak w nazwie atrybutu krótkiego\n" + +#: .././repair/attr_repair.c:911 +msgid "entry has INCOMPLETE flag on in shortform attribute\n" +msgstr "wpis ma flagę NIEPEŁNY w atrybucie krótkim\n" + +#: .././repair/attr_repair.c:928 #, c-format -msgid "non-numeric truncate argument -- %s\n" -msgstr "nieliczbowy argument truncate - %s\n" +msgid "removing attribute entry %d for inode %\n" +msgstr "usunięto wpis atrybutu %d dla i-węzła %\n" -#: .././io/truncate.c:58 -msgid "off" -msgstr "offset" +#: .././repair/attr_repair.c:940 +#, c-format +msgid "would remove attribute entry %d for inode %\n" +msgstr "wpis atrybutu %d dla i-węzła % zostałby usunięty\n" -#: .././io/truncate.c:60 -msgid "truncates the current file at the given offset" -msgstr "ucięcie bieżącego pliku na podanym offsecie" +#: .././repair/attr_repair.c:955 +#, c-format +msgid "would have corrected attribute entry count in inode % from %d to %d\n" +msgstr "liczba wpisów atrybutów w i-węźle % zostałaby poprawiona z %d na %d\n" -#: .././io/attr.c:59 +#: .././repair/attr_repair.c:959 #, c-format -msgid "" -"\n" -" displays the set of extended inode flags associated with the current file\n" -"\n" -" Each individual flag is displayed as a single character, in this order:\n" -" r -- file data is stored in the realtime section\n" -" p -- file has preallocated extents (cannot be changed using chattr)\n" -" i -- immutable, file cannot be modified\n" -" a -- append-only, file can only be appended to\n" -" s -- all updates are synchronous\n" -" A -- the access time is not updated for this inode\n" -" d -- do not include this file in a dump of the filesystem\n" -" t -- child created in this directory has realtime bit set by default\n" -" P -- child created in this directory has parents project ID by default\n" -" n -- symbolic links cannot be created in this directory\n" -" e -- for non-realtime files, observe the inode extent size value\n" -" E -- children created in this directory inherit the extent size value\n" -" f -- do not include this file when defragmenting the filesystem\n" -" S -- enable filestreams allocator for this directory\n" -"\n" -" Options:\n" -" -R -- recursively descend (useful when current file is a directory)\n" -" -D -- recursively descend, but only list attributes on directories\n" -" -a -- show all flags which can be set alongside those which are set\n" -" -v -- verbose mode; show long names of flags, not single characters\n" -"\n" -msgstr "" -"\n" -" wyświetlanie zbioru rozszerzonych flag i-węzłów związanych z bieżącym plikiem\n" -"\n" -" Każda flaga jest wyświetlana jako pojedynczy znak, w tej kolejności:\n" -" r - dane pliku są zapisane w sekcji realtime\n" -" p - plik ma już przydzielone ekstenty (nie do zmiany przez chattr)\n" -" i - niezmienny, pliku nie można modyfikować\n" -" a - tylko do dopisywania, do pliku można tylko dopisywać\n" -" s - wszystkie uaktualnienia są synchroniczne\n" -" A - czas dostępu nie jest uaktualniany dla tego i-węzła\n" -" d - nie dołączanie pliku do zrzutu systemu plików\n" -" t - wpisy tworzone w tym katalogu mają domyślnie ustawiony bit realtime\n" -" P - wpisy tworzone w tym katalogu mają domyślnie ID projektu rodzica\n" -" n - w tym katalogu nie można tworzyć dowiązań symbolicznych\n" -" e - dla plików nie-realtime - przestrzeganie wartości rozmiaru ekstentu i-węzła\n" -" E - wpisy tworzone w tym katalogu dziedziczą wartość rozmiaru ekstentu\n" -" f - nie uwzględnianie tego pliku przy defragmentacji systemu plików\n" -" S - włączenie przydzielania strumieni plikowych dla tego katalogu\n" -"\n" -" Opcje:\n" -" -R - rekurencyjne zagłębianie się (przydatne kiedy bieżący plik jest katalogiem)\n" -" -D - rekurencyjne zagłębianie się, ale wypisywanie atrybutów tylko katalogów\n" -" -a - pokazywanie wszystkich flag, które można ustawić, obok ustawionych\n" -" -v - tryb szczegółowy; pokazywanie długich nazw flag zamiast pojedynczych znaków\n" -"\n" +msgid "corrected attribute entry count in inode %, was %d, now %d\n" +msgstr "poprawiono liczbę wpisów atrybutów w i-węźle % - było %d, jest %d\n" -#: .././io/attr.c:90 +#: .././repair/attr_repair.c:970 #, c-format -msgid "" -"\n" -" modifies the set of extended inode flags associated with the current file\n" -"\n" -" Examples:\n" -" 'chattr +a' - sets the append-only flag\n" -" 'chattr -a' - clears the append-only flag\n" -"\n" -" -R -- recursively descend (useful when current file is a directory)\n" -" -D -- recursively descend, only modifying attributes on directories\n" -" +/-r -- set/clear the realtime flag\n" -" +/-i -- set/clear the immutable flag\n" -" +/-a -- set/clear the append-only flag\n" -" +/-s -- set/clear the sync flag\n" -" +/-A -- set/clear the no-atime flag\n" -" +/-d -- set/clear the no-dump flag\n" -" +/-t -- set/clear the realtime inheritance flag\n" -" +/-P -- set/clear the project ID inheritance flag\n" -" +/-n -- set/clear the no-symbolic-links flag\n" -" +/-e -- set/clear the extent-size flag\n" -" +/-E -- set/clear the extent-size inheritance flag\n" -" +/-f -- set/clear the no-defrag flag\n" -" +/-S -- set/clear the filestreams allocator flag\n" -" Note1: user must have certain capabilities to modify immutable/append-only.\n" -" Note2: immutable/append-only files cannot be deleted; removing these files\n" -" requires the immutable/append-only flag to be cleared first.\n" -" Note3: the realtime flag can only be set if the filesystem has a realtime\n" -" section, and the (regular) file must be empty when the flag is set.\n" -"\n" -msgstr "" -"\n" -" zmiana zbioru rozszerzonych flag i-węzłów związanych z bieżącym plikiem\n" -"\n" -" Przykłady:\n" -" 'chattr +a' - ustawia flagę tylko do dopisywania\n" -" 'chattr -a' - zdejmuje flagę tylko do dopisywania\n" -"\n" -" -R - rekurencyjne zagłębianie się (przydatne kiedy bieżący plik jest katalogiem)\n" -" -D - rekurencyjne zagłębianie się, ale zmiana atrybutów tylko katalogów\n" -" +/-r - ustawienie/zdjęcie flagi realtime\n" -" +/-i - ustawienie/zdjęcie flagi immutable (niezmienności)\n" -" +/-a - ustawienie/zdjęcie flagi append-only (tylko do dopisywania)\n" -" +/-s - ustawienie/zdjęcie flagi sync (synchronicznego zapisu)\n" -" +/-A - ustawienie/zdjęcie flagi no-atime\n" -" +/-d - ustawienie/zdjęcie flagi no-dump\n" -" +/-t - ustawienie/zdjęcie flagi dziedziczenia realtime\n" -" +/-P - ustawienie/zdjęcie flagi dziedziczenia ID projektu\n" -" +/-n - ustawienie/zdjęcie flagi braku dowiązań symbolicznych\n" -" +/-e - ustawienie/zdjęcie flagi rozmiaru ekstentu\n" -" +/-E - ustawienie/zdjęcie flagi dziedziczenia rozmiaru ekstentu\n" -" +/-f - ustawienie/zdjęcie flagi no-defrag\n" -" +/-S - ustawienie/zdjęcie flagi przydzielania strumieni plikowych\n" -" Uwaga1: użytkownik musi mieć pewne uprawnienia do zmiany flag\n" -" immutable/append-only\n" -" Uwaga2: plików immutable/append-only nie można usuwać; usuwanie tych plików\n" -" wymaga zdjęcia flag immutable/append-only przed usunięciem.\n" -" Uwaga3: flagę realtime można ustawić tylko jeśli system plików ma sekcję\n" -" realtime i (zwykły) plik musi być pusty przy ustawianiu flagi.\n" -"\n" +msgid "would have corrected attribute totsize in inode % from %d to %d\n" +msgstr "totsize atrybutów w i-węźle % zostałby poprawiony z %d na %d\n" -#: .././io/attr.c:256 .././io/attr.c:327 +#: .././repair/attr_repair.c:975 #, c-format -msgid "%s: cannot set flags on %s: %s\n" -msgstr "%s: nie można ustawić flag %s: %s\n" +msgid "corrected attribute entry totsize in inode %, was %d, now %d\n" +msgstr "poprawiono totsize wpisu atrybutów w i-węźle % - było %d, jest %d\n" -#: .././io/attr.c:291 .././io/attr.c:305 +#: .././repair/attr_repair.c:1009 #, c-format -msgid "%s: unknown flag\n" -msgstr "%s: nieznana flaga\n" +msgid "remote block for attributes of inode % is missing\n" +msgstr "brak odległego bloku dla atrybutów i-węzła %\n" -#: .././io/attr.c:311 +#: .././repair/attr_repair.c:1018 #, c-format -msgid "%s: bad chattr command, not +/-X\n" -msgstr "%s: złe polecenie chattr - nie +/-X\n" +msgid "can't read remote block for attributes of inode %\n" +msgstr "nie można odczytać odległego bloku dla atrybutów i-węzła %\n" -#: .././io/attr.c:338 -msgid "[-R|-D] [+/-" -msgstr "[-R|-D] [+/-" +#: .././repair/attr_repair.c:1025 +#, c-format +msgid "Corrupt remote block for attributes of inode %\n" +msgstr "Uszkodzony odległy blok dla atrybutów i-węzła %\n" -#: .././io/attr.c:343 -msgid "change extended inode flags on the currently open file" -msgstr "zmiana rozszerzonych flag i-węzłów aktualnie otwartego pliku" +#: .././repair/attr_repair.c:1066 +#, c-format +msgid "attribute entry %d in attr block %u, inode % has bad name (namelen = %d)\n" +msgstr "wpis atrybutu %d w bloku atrybutów %u, i-węźle % ma błędną nazwę (namelen = %d)\n" -#: .././io/attr.c:348 -msgid "[-R|-D|-a|-v]" -msgstr "[-R|-D|-a|-v]" +#: .././repair/attr_repair.c:1083 +#, c-format +msgid "bad hashvalue for attribute entry %d in attr block %u, inode %\n" +msgstr "błędna wartość hasza dla wpisu atrybutu %d w bloku atrybutów %u, i-węźle %\n" -#: .././io/attr.c:353 -msgid "list extended inode flags set on the currently open file" -msgstr "wypisanie rozszerzonych flag i-węzłów aktualnie otwartego pliku" +#: .././repair/attr_repair.c:1093 +#, c-format +msgid "bad security value for attribute entry %d in attr block %u, inode %\n" +msgstr "błędna wartość bezpieczeństwa dla wpisu atrybutu %d w bloku atrybutów %u, i-węźle %\n" -#: .././io/bmap.c:30 +#: .././repair/attr_repair.c:1126 #, c-format -msgid "" -"\n" -" prints the block mapping for an XFS file's data or attribute forks\n" -" Example:\n" -" 'bmap -vp' - tabular format verbose map, including unwritten extents\n" -"\n" -" bmap prints the map of disk blocks used by the current file.\n" -" The map lists each extent used by the file, as well as regions in the\n" -" file that do not have any corresponding blocks (holes).\n" -" By default, each line of the listing takes the following form:\n" -" extent: [startoffset..endoffset]: startblock..endblock\n" -" Holes are marked by replacing the startblock..endblock with 'hole'.\n" -" All the file offsets and disk blocks are in units of 512-byte blocks.\n" -" -a -- prints the attribute fork map instead of the data fork.\n" -" -d -- suppresses a DMAPI read event, offline portions shown as holes.\n" -" -l -- also displays the length of each extent in 512-byte blocks.\n" -" -n -- query n extents.\n" -" -p -- obtain all unwritten extents as well (w/ -v show which are unwritten.)\n" -" -v -- Verbose information, specify ag info. Show flags legend on 2nd -v\n" -" Note: the bmap for non-regular files can be obtained provided the file\n" -" was opened appropriately (in particular, must be opened read-only).\n" -"\n" -msgstr "" -"\n" -" wypisanie mapowania bloków dla danych lub atrybutów pliku na XFS-ie\n" -" Przykład:\n" -" 'bmap -vp' - szczegółowa mapa w formacie tabeli wraz z nie zapisanymi\n" -" ekstentami\n" -"\n" -" bmap wypisuje mapę bloków dysku używanych przez bieżący plik.\n" -" Mapa opisuje każdy ekstent użyty przez plik, a także regiony w pliku\n" -" nie mające przypisanych bloków (dziury).\n" -" Domyślnie każda linia listingu przyjmuje następującą postać:\n" -" ekstent: [offsetpocz..offsetkońc]: blokpocz..blokkońc\n" -" Dziury są oznaczane przez zastąpienie blokpocz..blokkońc przez 'dziura'.\n" -" Wszystkie offsety w plikach i bloki dysku są w jednostkach 512-bajtowych.\n" -" -a - wypisanie mapy gałęzi atrybutów zamiast gałęzi danych.\n" -" -d - pominięcie zdarzenia odczytu DMAPI, pokazanie części offline jako dziur.\n" -" -l - wyświetlenie także długości każdego fragmentu w 512-bajtowych blokach.\n" -" -n - odpytanie n ekstentów.\n" -" -p - wypisanie także nie zapisanych ekstentów (z -v pokazuje, które są nie\n" -" zapisane).\n" -" -v - szczegółowe informacje z podaniem informacji ag; legenda drugim -v\n" -" Uwaga: bmap dla plików nie będących plikami zwykłymi można uzyskać pod\n" -" warunkiem, że plik został otwarty odpowiednio (w szczególności musi być\n" -" otwarty tylko do odczytu).\n" -"\n" +msgid "inconsistent remote attribute entry %d in attr block %u, ino %\n" +msgstr "niespójny wpis odległego atrybutu %d w bloku atrybutów %u, i-węźle %\n" -#: .././io/bmap.c:123 +#: .././repair/attr_repair.c:1136 #, c-format -msgid "%s: can't get geometry [\"%s\"]: %s\n" -msgstr "%s: nie można uzyskać geometrii [\"%s\"]: %s\n" +msgid "cannot malloc enough for remotevalue attribute for inode %\n" +msgstr "nie można przydzielić wystarczająco dużo dla atrybutu remotevalue dla i-węzła %\n" -#: .././io/bmap.c:131 +#: .././repair/attr_repair.c:1138 +msgid "SKIPPING this remote attribute\n" +msgstr "POMINIĘTO ten atrybut odległy\n" + +#: .././repair/attr_repair.c:1144 #, c-format -msgid "%s: cannot read attrs on \"%s\": %s\n" -msgstr "%s: nie można odczytać atrybutów \"%s\": %s\n" +msgid "remote attribute get failed for entry %d, inode %\n" +msgstr "pobranie odległego atrybutu nie powiodło się dla wpisu %d, i-węzła %\n" -#: .././io/bmap.c:197 +#: .././repair/attr_repair.c:1151 #, c-format -msgid "%s: xfsctl(XFS_IOC_GETBMAPX) iflags=0x%x [\"%s\"]: %s\n" -msgstr "%s: xfsctl(XFS_IOC_GETBMAPX) iflags=0x%x [\"%s\"]: %s\n" +msgid "remote attribute value check failed for entry %d, inode %\n" +msgstr "sprawdzenie wartości odległego atrybutu nie powiodło się dla wpisu %d, i-węzła %\n" -#: .././io/bmap.c:228 +#: .././repair/attr_repair.c:1189 #, c-format -msgid "%s: cannot realloc %d bytes\n" -msgstr "%s: nie można wykonać realloc na %d bajtów\n" +msgid "bad attribute count %d in attr block %u, inode %\n" +msgstr "błędna liczba atrybutów %d w bloku atrybutów %u, i-węźle %\n" -#: .././io/bmap.c:237 +#: .././repair/attr_repair.c:1204 #, c-format -msgid "%s: no extents\n" -msgstr "%s: brak ekstentów\n" +msgid "bad attribute nameidx %d in attr block %u, inode %\n" +msgstr "błędny nameidx atrybutu %d w bloku atrybutów %u, i-węźle %\n" -#: .././io/bmap.c:260 +#: .././repair/attr_repair.c:1213 #, c-format -msgid " %lld blocks\n" -msgstr " %lld bloków\n" +msgid "attribute entry #%d in attr block %u, inode % is INCOMPLETE\n" +msgstr "wpis atrybutu #%d w bloku atrybutów %u, i-węźle % jest NIEPEŁNY\n" -#: .././io/bmap.c:341 -msgid "RT-BLOCK-RANGE" -msgstr "ZAKRES-BLOKÓW-RT" +#: .././repair/attr_repair.c:1224 +#, c-format +msgid "attribute entry %d in attr block %u, inode % claims already used space\n" +msgstr "wpis atrybutu %d w bloku atrybutów %u, i-węźle % odwołuje się do już użytego miejsca\n" -#: .././io/bmap.c:342 -msgid "AG" -msgstr "AG" +#: .././repair/attr_repair.c:1247 +#, c-format +msgid "attribute entry %d in attr block %u, inode % claims used space\n" +msgstr "wpis atrybutu %d w bloku atrybutów %u, i-węźle % odwołuje się do używanego miejsca\n" -#: .././io/bmap.c:343 -msgid "AG-OFFSET" -msgstr "OFFSET-AG" +#: .././repair/attr_repair.c:1271 +#, c-format +msgid "- resetting first used heap value from %d to %d in block %u of attribute fork of inode %\n" +msgstr "- przestawiono pierwszą używaną wartość sterty z %d na %d w bloku %u gałęzi atrybutów i-węzła %\n" -#: .././io/bmap.c:345 -msgid " FLAGS" -msgstr " FLAGI" +#: .././repair/attr_repair.c:1279 +#, c-format +msgid "- would reset first used value from %d to %d in block %u of attribute fork of inode %\n" +msgstr "- pierwsza używana wartość zostałaby przestawiona z %d na %d w bloku %u gałęzi atrybutów i-węzła %\n" -#: .././io/bmap.c:413 +#: .././repair/attr_repair.c:1289 #, c-format -msgid " FLAG Values:\n" -msgstr " Wartości FLAG:\n" +msgid "- resetting usedbytes cnt from %d to %d in block %u of attribute fork of inode %\n" +msgstr "- przestawiono liczbę użytych bajtów z %d na %d w bloku %u gałęzi atrybutów i-węzła %\n" -#: .././io/bmap.c:414 +#: .././repair/attr_repair.c:1297 #, c-format -msgid " %*.*o Unwritten preallocated extent\n" -msgstr " %*.*o Nie zapisany, już przydzielony ekstent\n" +msgid "- would reset usedbytes cnt from %d to %d in block %u of attribute fork of %\n" +msgstr "- liczba użytych bajtów zostałaby przestawiona z %d na %d w bloku %u gałęzi atrybutów i-węzła %\n" -#: .././io/bmap.c:416 +#: .././repair/attr_repair.c:1352 #, c-format -msgid " %*.*o Doesn't begin on stripe unit\n" -msgstr " %*.*o Nie zaczyna się od jednostki pasa\n" +msgid "can't map block %u for attribute fork for inode %\n" +msgstr "nie można odwzorować bloku %u dla gałęzi atrybutów dla i-węzła %\n" -#: .././io/bmap.c:418 +#: .././repair/attr_repair.c:1362 #, c-format -msgid " %*.*o Doesn't end on stripe unit\n" -msgstr " %*.*o Nie kończy się na jednostce pasa\n" +msgid "can't read file block %u (fsbno %) for attribute fork of inode %\n" +msgstr "nie można odczytać bloku pliku %u (fsbno %) dla gałęzi atrybutów i-węzła %\n" -#: .././io/bmap.c:420 +#: .././repair/attr_repair.c:1376 #, c-format -msgid " %*.*o Doesn't begin on stripe width\n" -msgstr " %*.*o Nie zaczyna się na szerokości pasa\n" +msgid "bad attribute leaf magic %#x for inode %\n" +msgstr "błędna liczba magiczna liścia atrybutu %#x dla i-węzła %\n" -#: .././io/bmap.c:422 +#: .././repair/attr_repair.c:1407 #, c-format -msgid " %*.*o Doesn't end on stripe width\n" -msgstr " %*.*o Nie kończy się na szerokości pasa\n" +msgid "bad sibling back pointer for block %u in attribute fork for inode %\n" +msgstr "błędny wskaźnik wsteczny dla bloku %u w gałęzi atrybutów dla i-węzła %\n" -#: .././io/bmap.c:438 -msgid "[-adlpv] [-n nx]" -msgstr "[-adlpv] [-n nx]" +#: .././repair/attr_repair.c:1434 +#, c-format +msgid "bad hash path in attribute fork for inode %\n" +msgstr "błędna ścieżka hasza w gałęzi atrybutów dla i-węzła %\n" -#: .././io/bmap.c:439 -msgid "print block mapping for an XFS file" -msgstr "wypisanie mapowania bloków dla pliku na XFS-ie" +#: .././repair/attr_repair.c:1534 +#, c-format +msgid "block 0 of inode % attribute fork is missing\n" +msgstr "brak bloku 0 i-węzła % gałęzi atrybutów\n" -#: .././io/fadvise.c:31 +#: .././repair/attr_repair.c:1541 #, c-format -msgid "" -"\n" -" advise the page cache about expected I/O patterns on the current file\n" -"\n" -" Modifies kernel page cache behaviour when operating on the current file.\n" -" The range arguments are required by some advise commands ([*] below).\n" -" With no arguments, the POSIX_FADV_NORMAL advice is implied.\n" -" -d -- don't need these pages (POSIX_FADV_DONTNEED) [*]\n" -" -n -- data will be accessed once (POSIX_FADV_NOREUSE) [*]\n" -" -r -- expect random page references (POSIX_FADV_RANDOM)\n" -" -s -- expect sequential page references (POSIX_FADV_SEQUENTIAL)\n" -" -w -- will need these pages (POSIX_FADV_WILLNEED) [*]\n" -" Notes: these interfaces are not supported in Linux kernels before 2.6.\n" -" NORMAL sets the default readahead setting on the file.\n" -" RANDOM sets the readahead setting on the file to zero.\n" -" SEQUENTIAL sets double the default readahead setting on the file.\n" -" WILLNEED and NOREUSE are equivalent, and force the maximum readahead.\n" -"\n" -msgstr "" -"\n" -" doradzenie buforowi stron w sprawie oczekiwanych schematów we/wy na bieżącym\n" -" pliku\n" -"\n" -" fadvise modyfikuje zachowanie bufora stron przy operacjach na bieżącym pliku.\n" -" Niektóre polecenia fadvise ([*] poniżej) wymagają podania zakresu.\n" -" Bez argumentów zakłada się doradzenie POSIX_FADV_NORMAL.\n" -" -d - podane strony nie są wymagane (POSIX_FADV_DONTNEED) [*]\n" -" -n - dostęp do danych będzie jednokrotny (POSIX_FADV_NOREUSE) [*]\n" -" -r - należy oczekiwać losowych odwołań do stron (POSIX_FADV_RANDOM)\n" -" -s - należy oczekiwać sekwencyjnych odwołań do stron (POSIX_FADV_SEQUENTIAL)\n" -" -w - podane strony będą potrzebne (POSIX_FADV_WILLNEED) [*]\n" -" Uwagi: te interfejsy nie były obsługiwane przez jądra Linuksa przed 2.6.\n" -" NORMAL ustawia domyślną wartość czytania z wyprzedzeniem dla pliku.\n" -" RANDOM ustawia czytanie z wyprzedzeniem dla pliku na zero.\n" -" SEQUENTIAL ustawia podwójną domyślną wartość czytania z wyprzedzeniem.\n" -" WILLNEED i NOREUSE są równoznaczne i wymuszają maksymalne czytanie\n" -" z wyprzedzeniem.\n" -"\n" - -#: .././io/fadvise.c:122 -msgid "[-dnrsw] [off len]" -msgstr "[-dnrsw] [offset długość]" - -#: .././io/fadvise.c:123 -msgid "advisory commands for sections of a file" -msgstr "polecenia doradcze dla sekcji pliku" - -#: .././io/fsync.c:59 -msgid "calls fsync(2) to flush all in-core file state to disk" -msgstr "wywołanie fsync(2) aby zrzucić cały stan pliku z pamięci na dysk" - -#: .././io/fsync.c:66 -msgid "calls fdatasync(2) to flush the files in-core data to disk" -msgstr "wywołanie fdatasync(2) aby zrzucić dane pliku z pamięci na dysk" +msgid "agno of attribute fork of inode % out of regular partition\n" +msgstr "agno gałęzi atrybutów i-węzła % spoza zwykłej partycji\n" -#: .././io/file.c:39 +#: .././repair/attr_repair.c:1549 #, c-format -msgid "%c%03d%c %-14s (%s,%s,%s,%s%s%s%s)\n" -msgstr "%c%03d%c %-14s (%s,%s,%s,%s%s%s%s)\n" - -#: .././io/file.c:41 -msgid "foreign" -msgstr "obcy" +msgid "can't read block 0 of inode % attribute fork\n" +msgstr "nie można odczytać bloku 0 i-węzła % gałęzi atrybutów\n" -#: .././io/file.c:41 -msgid "xfs" -msgstr "xfs" +#: .././repair/attr_repair.c:1566 +#, c-format +msgid "clearing forw/back pointers in block 0 for attributes in inode %\n" +msgstr "wyczyszczono wskaźniki forw/back w bloku 0 dla atrybutów w i-węźle %\n" -#: .././io/file.c:42 .././io/open.c:82 -msgid "sync" -msgstr "synchr" +#: .././repair/attr_repair.c:1574 +#, c-format +msgid "would clear forw/back pointers in block 0 for attributes in inode %\n" +msgstr "wskaźniki forw/back w bloku 0 dla atrybutów w i-węźle % zostałyby wyczyszczone\n" -#: .././io/file.c:42 .././io/open.c:82 -msgid "non-sync" -msgstr "niesynchr" +#: .././repair/attr_repair.c:1606 +#, c-format +msgid "bad attribute leaf magic # %#x for dir ino %\n" +msgstr "błędna liczba magiczna liścia atrybutu %#x dla i-węzła katalogu %\n" -#: .././io/file.c:43 .././io/open.c:83 -msgid "direct" -msgstr "bezpośredni" +#: .././repair/attr_repair.c:1635 +#, c-format +msgid "Too many ACL entries, count %d\n" +msgstr "Za dużo wpisów ACL, liczba %d\n" -#: .././io/file.c:43 .././io/open.c:83 -msgid "non-direct" -msgstr "niebezpośredni" +#: .././repair/attr_repair.c:1644 +msgid "cannot malloc enough for ACL attribute\n" +msgstr "nie można wykonać wystarczającego malloc dla atrybutu ACL\n" -#: .././io/file.c:44 .././io/open.c:84 -msgid "read-only" -msgstr "tylko do odczytu" +#: .././repair/attr_repair.c:1645 +msgid "SKIPPING this ACL\n" +msgstr "POMINIĘTO ten ACL\n" -#: .././io/file.c:44 .././io/open.c:84 -msgid "read-write" -msgstr "odczyt i zapis" +#: .././repair/attr_repair.c:1695 .././repair/dinode.c:2053 +#, c-format +msgid "illegal attribute format %d, ino %\n" +msgstr "niedozwolony format atrybutu %d, i-węzeł %\n" -#: .././io/file.c:45 .././io/open.c:85 -msgid ",real-time" -msgstr ",real-time" +#: .././repair/avl.c:1011 .././repair/avl64.c:1032 +#, c-format +msgid "avl_insert: Warning! duplicate range [%llu,%llu]\n" +msgstr "avl_insert: Uwaga! powtórzony przedział [%llu,%llu]\n" -#: .././io/file.c:46 .././io/open.c:86 -msgid ",append-only" -msgstr ",tylko dopisywanie" +#: .././repair/avl.c:1206 .././repair/avl64.c:1227 +#, c-format +msgid "Command [fpdir] : " +msgstr "Polecenie [fpdir] : " -#: .././io/file.c:47 .././io/open.c:87 -msgid ",non-block" -msgstr ",nieblokujący" +#: .././repair/avl.c:1215 .././repair/avl64.c:1236 +#, c-format +msgid "end of range ? " +msgstr "koniec przedziału? " -#: .././io/file.c:99 -msgid "set the current file" -msgstr "ustawienie bieżącego pliku" +#: .././repair/avl.c:1226 .././repair/avl64.c:1247 +#, c-format +msgid "Cannot find %d\n" +msgstr "Nie można odnaleźć %d\n" -#: .././io/file.c:108 -msgid "list current open files and memory mappings" -msgstr "wypisanie aktualnie otwartych plików i odwzorowań w pamięci" +#: .././repair/avl.c:1239 .././repair/avl64.c:1260 +#, c-format +msgid "size of range ? " +msgstr "rozmiar przedziału? " -#: .././io/init.c:35 +#: .././repair/avl.c:1250 .././repair/avl64.c:1271 #, c-format -msgid "Usage: %s [-adfmrRstx] [-p prog] [-c cmd]... file\n" -msgstr "Składnia: %s [-adfmrRstx] [-p program] [-c polecenie]... plik\n" +msgid "End of range ? " +msgstr "Koniec przedziału? " -#: .././io/init.c:111 +#: .././repair/avl.c:1254 .././repair/avl64.c:1275 #, c-format -msgid "foreign file active, %s command is for XFS filesystems only\n" -msgstr "aktywny jest plik obcy, polecenie %s jest tylko dla systemów plików XFS\n" +msgid "checklen 0/1 ? " +msgstr "checklen 0/1 ? " -#: .././io/init.c:156 .././io/open.c:295 +#: .././repair/avl.c:1261 .././repair/avl64.c:1282 #, c-format -msgid "non-numeric mode -- %s\n" -msgstr "tryb nieliczbowy - %s\n" +msgid "Found something\n" +msgstr "Znaleziono coś\n" -#: .././io/open.c:53 -msgid "socket" -msgstr "gniazdo" +#: .././repair/bmap.c:53 +#, c-format +msgid "" +"Number of extents requested in blkmap_alloc (%d) overflows 32 bits.\n" +"If this is not a corruption, then you will need a 64 bit system\n" +"to repair this filesystem.\n" +msgstr "" +"Liczba ekstentów żądanych w blkmap_alloc (%d) przepełnia 32 bity.\n" +"Jeśli nie jest to efekt uszkodzenia, do naprawy tego systemu plików\n" +"niezbędny jest system 64-bitowy.\n" -#: .././io/open.c:55 -msgid "directory" -msgstr "katalog" +#: .././repair/bmap.c:66 +#, c-format +msgid "malloc failed in blkmap_alloc (%zu bytes)\n" +msgstr "malloc nie powiodło się w blkmap_alloc (%zu bajtów)\n" -#: .././io/open.c:57 -msgid "char device" -msgstr "urządzenie znakowe" +#: .././repair/bmap.c:174 +#, c-format +msgid "blkmap_getn malloc failed (% bytes)\n" +msgstr "malloc w blkmap_getn nie powiodło się (% bajtów)\n" -#: .././io/open.c:59 -msgid "block device" -msgstr "urządzenie blokowe" +#: .././repair/bmap.c:281 +#, c-format +msgid "" +"Number of extents requested in blkmap_grow (%d) overflows 32 bits.\n" +"You need a 64 bit system to repair this filesystem.\n" +msgstr "" +"Liczba ekstentów żądanych w blkmap_grow (%d) przepełnia 32 bity.\n" +"Do naprawy tego systemu plików niezbędny jest system 64-bitowy.\n" -#: .././io/open.c:61 -msgid "regular file" -msgstr "plik zwykły" +#: .././repair/bmap.c:289 +#, c-format +msgid "" +"Number of extents requested in blkmap_grow (%d) overflowed the\n" +"maximum number of supported extents (%d).\n" +msgstr "" +"Liczba ekstentów żądanych w blkmap_grow (%d) przepełniła maksymalną\n" +"liczbę obsługiwanych ekstentów (%d).\n" -#: .././io/open.c:63 -msgid "symbolic link" -msgstr "dowiązanie symboliczne" +#: .././repair/bmap.c:297 +msgid "realloc failed in blkmap_grow\n" +msgstr "realloc nie powiodło się w blkmap_grow\n" -#: .././io/open.c:65 -msgid "fifo" -msgstr "potok" +#: .././repair/dino_chunks.c:57 +#, c-format +msgid "cannot read agbno (%u/%u), disk block %\n" +msgstr "nie można odczytać agbno (%u/%u), blok dysku %\n" -#: .././io/open.c:80 .././io/open.c:719 +#: .././repair/dino_chunks.c:150 #, c-format -msgid "fd.path = \"%s\"\n" -msgstr "fd.path = \"%s\"\n" +msgid "uncertain inode block %d/%d already known\n" +msgstr "niepewny blok i-węzła %d/%d już znany\n" -#: .././io/open.c:81 +#: .././repair/dino_chunks.c:166 .././repair/dino_chunks.c:438 +#: .././repair/dino_chunks.c:497 #, c-format -msgid "fd.flags = %s,%s,%s%s%s%s\n" -msgstr "fd.flags = %s,%s,%s%s%s%s\n" +msgid "inode block %d/%d multiply claimed, (state %d)\n" +msgstr "blok i-węzła %d/%d już przypisany (stan %d)\n" -#: .././io/open.c:91 +#: .././repair/dino_chunks.c:173 .././repair/dino_chunks.c:502 #, c-format -msgid "stat.ino = %lld\n" -msgstr "stat.ino = %lld\n" +msgid "inode block %d/%d bad state, (state %d)\n" +msgstr "blok i-węzła (%d/%d) w błędnym stanie (stan %d)\n" -#: .././io/open.c:92 +#: .././repair/dino_chunks.c:445 #, c-format -msgid "stat.type = %s\n" -msgstr "stat.type = %s\n" +msgid "uncertain inode block overlap, agbno = %d, ino = %\n" +msgstr "niepewny blok i-węzła pokrywa się, agbno = %d, i-węzeł %\n" -#: .././io/open.c:93 +#: .././repair/dino_chunks.c:484 #, c-format -msgid "stat.size = %lld\n" -msgstr "stat.size = %lld\n" +msgid "uncertain inode block % already known\n" +msgstr "niepewny blok i-węzła % już znany\n" -#: .././io/open.c:94 +#: .././repair/dino_chunks.c:621 #, c-format -msgid "stat.blocks = %lld\n" -msgstr "stat.blocks = %lld\n" +msgid "failed to allocate %zd bytes of memory\n" +msgstr "nie udało się przydzielić %zd bajtów pamięci\n" -#: .././io/open.c:96 +#: .././repair/dino_chunks.c:633 #, c-format -msgid "stat.atime = %s" -msgstr "stat.atime = %s" +msgid "cannot read inode %, disk block %, cnt %d\n" +msgstr "nie można odczytać i-węzła %, blok dysku %, cnt %d\n" -#: .././io/open.c:97 +#: .././repair/dino_chunks.c:750 .././repair/dino_chunks.c:939 #, c-format -msgid "stat.mtime = %s" -msgstr "stat.mtime = %s" +msgid "bad state in block map %d\n" +msgstr "błędny stan w mapie bloku %d\n" -#: .././io/open.c:98 +#: .././repair/dino_chunks.c:754 .././repair/dino_chunks.c:945 #, c-format -msgid "stat.ctime = %s" -msgstr "stat.ctime = %s" +msgid "inode block % multiply claimed, state was %d\n" +msgstr "blok i-węzła % wielokrotnie przydzielony, stan był %d\n" -#: .././io/open.c:107 +#: .././repair/dino_chunks.c:796 #, c-format -msgid "fsxattr.xflags = 0x%x " -msgstr "fsxattr.xflags = 0x%x " +msgid "imap claims in-use inode % is free, " +msgstr "imap twierdzi, że używany i-węzeł % jest wolny, " -#: .././io/open.c:109 +#: .././repair/dino_chunks.c:801 +msgid "correcting imap\n" +msgstr "poprawiono imap\n" + +#: .././repair/dino_chunks.c:803 +msgid "would correct imap\n" +msgstr "imap zostałoby poprawione\n" + +#: .././repair/dino_chunks.c:858 #, c-format -msgid "fsxattr.projid = %u\n" -msgstr "fsxattr.projid = %u\n" +msgid "cleared root inode %\n" +msgstr "wyczyszczono główny i-węzeł %\n" -#: .././io/open.c:110 +#: .././repair/dino_chunks.c:862 #, c-format -msgid "fsxattr.extsize = %u\n" -msgstr "fsxattr.extsize = %u\n" +msgid "would clear root inode %\n" +msgstr "główny węzeł % zostałby wyczyszczony\n" -#: .././io/open.c:111 +#: .././repair/dino_chunks.c:870 #, c-format -msgid "fsxattr.nextents = %u\n" -msgstr "fsxattr.nextents = %u\n" +msgid "cleared realtime bitmap inode %\n" +msgstr "wyczyszczono i-węzeł bitmapy realtime %\n" -#: .././io/open.c:112 +#: .././repair/dino_chunks.c:874 #, c-format -msgid "fsxattr.naextents = %u\n" -msgstr "fsxattr.naextents = %u\n" +msgid "would clear realtime bitmap inode %\n" +msgstr "i-węzeł bitmapy realtime % zostałby wyczyszczony\n" -#: .././io/open.c:117 +#: .././repair/dino_chunks.c:882 #, c-format -msgid "dioattr.mem = 0x%x\n" -msgstr "dioattr.mem = 0x%x\n" +msgid "cleared realtime summary inode %\n" +msgstr "wyczyszczono i-węzeł opisu realtime %\n" -#: .././io/open.c:118 +#: .././repair/dino_chunks.c:886 #, c-format -msgid "dioattr.miniosz = %u\n" -msgstr "dioattr.miniosz = %u\n" +msgid "would clear realtime summary inode %\n" +msgstr "i-węzeł opisu realtime % zostałby wyczyszczony\n" -#: .././io/open.c:119 +#: .././repair/dino_chunks.c:890 #, c-format -msgid "dioattr.maxiosz = %u\n" -msgstr "dioattr.maxiosz = %u\n" +msgid "cleared inode %\n" +msgstr "wyczyszczono i-węzeł %\n" -#: .././io/open.c:235 +#: .././repair/dino_chunks.c:893 #, c-format -msgid "" -"\n" -" opens a new file in the requested mode\n" -"\n" -" Example:\n" -" 'open -cd /tmp/data' - creates/opens data file read-write for direct IO\n" -"\n" -" Opens a file for subsequent use by all of the other xfs_io commands.\n" -" With no arguments, open uses the stat command to show the current file.\n" -" -F -- foreign filesystem file, disallow XFS-specific commands\n" -" -a -- open with the O_APPEND flag (append-only mode)\n" -" -d -- open with O_DIRECT (non-buffered IO, note alignment constraints)\n" -" -f -- open with O_CREAT (create the file if it doesn't exist)\n" -" -m -- permissions to use in case a new file is created (default 0600)\n" -" -n -- open with O_NONBLOCK\n" -" -r -- open with O_RDONLY, the default is O_RDWR\n" -" -s -- open with O_SYNC\n" -" -t -- open with O_TRUNC (truncate the file to zero length if it exists)\n" -" -R -- mark the file as a realtime XFS file immediately after opening it\n" -" Note1: usually read/write direct IO requests must be blocksize aligned;\n" -" some kernels, however, allow sectorsize alignment for direct IO.\n" -" Note2: the bmap for non-regular files can be obtained provided the file\n" -" was opened correctly (in particular, must be opened read-only).\n" -"\n" -msgstr "" -"\n" -" otwarcie nowego pliku w żądanym trybie\n" -"\n" -" Przykład:\n" -" 'open -cd /tmp/data' - utworzenie/otwarcie pliku danych do odczytu i zapisu\n" -" z bezpośrednim we/wy\n" -"\n" -" open otwiera plik do późniejszego wykorzystania przez wszystkie inne polecenia\n" -" xfs_io.\n" -" Bez argumentów używa polecenia stat do pokazania bieżącego pliku.\n" -" -F - plik na obcym systemie plików, zabronienie używania poleceń dla XFS-a\n" -" -a - otwarcie z flagą O_APPEND (w trybie tylko dopisywania)\n" -" -d - otwarcie z flagą O_DIRECT (niebuforowane we/wy, ograniczenia wyrównania)\n" -" -f - otwarcie z flagą O_CREAT (utworzenie pliku jeśli nie istnieje)\n" -" -m - uprawnienia do użycia w przypadku tworzenia pliku (domyślnie 0600)\n" -" -n - otwarcie z flagą O_NONBLOCK\n" -" -r - otwarcie z flagą O_RDONLY (domyślne jest O_RDWR)\n" -" -s - otwarcie z flagą O_SYNC\n" -" -t - otwarcie z flagą O_TRUNC (ucięcie do zerowej długości jeśli istnieje)\n" -" -R - oznaczenie pliku jako realtime na XFS-ie zaraz po otwarciu\n" -" Uwaga1: zwykle żądania bezpośredniego we/wy muszą być wyrównane do rozmiaru\n" -" bloku; niektóre jądra pozwalają na wyrównanie do rozmiaru sektora\n" -" Uwaga2: bmap dla plików innych niż zwykłe można uzyskać pod warunkiem, że\n" -" plik zostanie poprawnie otwarty (w szczególności tylko do odczytu).\n" +msgid "would have cleared inode %\n" +msgstr "i-węzeł % zostałby wyczyszczony\n" + +#: .././repair/dino_chunks.c:1100 .././repair/dino_chunks.c:1135 +#: .././repair/dino_chunks.c:1249 +msgid "found inodes not in the inode allocation tree\n" +msgstr "znaleziono i-węzły nieobecne w drzewie alokacji i-węzłów\n" + +#: .././repair/dinode.c:52 +msgid "real-time" +msgstr "realtime" + +#: .././repair/dinode.c:53 +msgid "regular" +msgstr "zwykłym" -#: .././io/open.c:374 +#: .././repair/dinode.c:76 #, c-format -msgid "" -"\n" -" displays the project identifier associated with the current path\n" -"\n" -" Options:\n" -" -R -- recursively descend (useful when current path is a directory)\n" -" -D -- recursively descend, but only list projects on directories\n" -"\n" -msgstr "" -"\n" -" wyświetlenie identyfikatora projektu związanego z bieżącą ścieżką\n" -"\n" -" Opcje:\n" -" -R - rekurencyjne zagłębianie się (przydatne kiedy bieżący plik jest katalogiem)\n" -" -D - rekurencyjne zagłębianie się, ale wypisywanie projektów tylko katalogów\n" -"\n" +msgid "clearing inode % attributes\n" +msgstr "wyczyszczono atrybuty i-węzła %\n" -#: .././io/open.c:440 +#: .././repair/dinode.c:79 #, c-format -msgid "projid = %u\n" -msgstr "projid = %u\n" +msgid "would have cleared inode % attributes\n" +msgstr "atrybuty i-węzła % zostałyby wyczyszczone\n" -#: .././io/open.c:448 +#: .././repair/dinode.c:443 #, c-format -msgid "" -"\n" -" modifies the project identifier associated with the current path\n" -"\n" -" -R -- recursively descend (useful when current path is a directory)\n" -" -D -- recursively descend, only modifying projects on directories\n" -"\n" -msgstr "" -"\n" -" modyfikacja identyfikatora projektu związanego z bieżącą ścieżką\n" -"\n" -" -R - rekurencyjne zagłębianie się (przydatne kiedy bieżący plik jest katalogiem)\n" -" -D - rekurencyjne zagłębianie się, ale zmiana projektów tylko katalogów\n" -"\n" +msgid "inode % - bad rt extent start block number %, offset %\n" +msgstr "i-węzeł % - błędny numer bloku początkowego ekstentu rt %, offset %\n" -#: .././io/open.c:507 +#: .././repair/dinode.c:451 #, c-format -msgid "invalid project ID -- %s\n" -msgstr "nieprawidłowy ID projektu - %s\n" +msgid "inode % - bad rt extent last block number %, offset %\n" +msgstr "i-węzeł % - błędny numer bloku końcowego ekstentu rt %, offset %\n" -#: .././io/open.c:523 +#: .././repair/dinode.c:459 #, c-format -msgid "" -"\n" -" report or modify preferred extent size (in bytes) for the current path\n" -"\n" -" -R -- recursively descend (useful when current path is a directory)\n" -" -D -- recursively descend, only modifying extsize on directories\n" -"\n" -msgstr "" -"\n" -" odczyt lub zmiana preferowanego rozmiaru ekstentu (w bajtach) dla bieżącej\n" -" ścieżki\n" -"\n" -" -R - rekurencyjne zagłębianie się (przydatne kiedy bieżący plik jest katalogiem)\n" -" -D - rekurencyjne zagłębianie się, ale zmiana extsize tylko katalogów\n" -"\n" +msgid "inode % - bad rt extent overflows - start %, end %, offset %\n" +msgstr "i-węzeł % - błędne przepełnienie ekstentu rt - początek %, koniec %, offset %\n" -#: .././io/open.c:566 +#: .././repair/dinode.c:476 #, c-format -msgid "invalid target file type - file %s\n" -msgstr "nieprawidłowy rodzaj bliku docelowego - plik %s\n" +msgid "malformed rt inode extent [% %] (fs rtext size = %u)\n" +msgstr "zniekształcony ekstent i-węzła rt [% %] (rozmiar fs rtext = %u)\n" -#: .././io/open.c:652 +#: .././repair/dinode.c:497 #, c-format -msgid "non-numeric extsize argument -- %s\n" -msgstr "nieliczbowy argument extsize - %s\n" +msgid "data fork in rt ino % claims dup rt extent,off - %, start - %, count %\n" +msgstr "gałąź danych w i-węźle rt % odwołuje się do powtórzonego ekstentu rt, offset %, początek %, liczba %\n" -#: .././io/open.c:699 +#: .././repair/dinode.c:516 #, c-format -msgid "invalid setfl argument -- '%c'\n" -msgstr "nieprawidłowy argument setfl - '%c'\n" +msgid "bad state in rt block map %\n" +msgstr "błędny stan w mapie bloku rt %\n" -#: .././io/open.c:723 +#: .././repair/dinode.c:522 #, c-format -msgid "statfs.f_bsize = %lld\n" -msgstr "statfs.f_bsize = %lld\n" +msgid "data fork in rt inode % found metadata block % in rt bmap\n" +msgstr "gałąź danych w i-węźle rt % - znaleziono blok metadanych % w bmapie rt\n" -#: .././io/open.c:724 +#: .././repair/dinode.c:530 #, c-format -msgid "statfs.f_blocks = %lld\n" -msgstr "statfs.f_blocks = %lld\n" +msgid "data fork in rt inode % claims used rt block %\n" +msgstr "gałąź danych w i-węźle rt % odwołuje się do używanego bloku rt %\n" -#: .././io/open.c:726 +#: .././repair/dinode.c:536 #, c-format -msgid "statfs.f_frsize = %lld\n" -msgstr "statfs.f_frsize = %lld\n" +msgid "illegal state %d in rt block map %\n" +msgstr "niedozwolony stan %d w mapie bloku rt %\n" -#: .././io/open.c:728 +#: .././repair/dinode.c:599 #, c-format -msgid "statfs.f_bavail = %lld\n" -msgstr "statfs.f_bavail = %lld\n" +msgid "bmap rec out of order, inode % entry %d [o s c] [% % %], %d [% % %]\n" +msgstr "rekord bmap uszkodzony, i-węzeł % wpis %d [o s c] [% % %], %d [% % %]\n" -#: .././io/open.c:730 +#: .././repair/dinode.c:615 #, c-format -msgid "statfs.f_files = %lld\n" -msgstr "statfs.f_files = %lld\n" +msgid "zero length extent (off = %, fsbno = %) in ino %\n" +msgstr "ekstent zerowej długości (off = %, fsbno = %) w i-węźle %\n" -#: .././io/open.c:731 +#: .././repair/dinode.c:646 #, c-format -msgid "statfs.f_ffree = %lld\n" -msgstr "statfs.f_ffree = %lld\n" +msgid "inode % - bad extent starting block number %, offset %\n" +msgstr "i-węzeł % - błędny numer bloku początkowego ekstentu %, offset %\n" -#: .././io/open.c:738 +#: .././repair/dinode.c:654 #, c-format -msgid "geom.bsize = %u\n" -msgstr "geom.bsize = %u\n" +msgid "inode % - bad extent last block number %, offset %\n" +msgstr "i-węzeł % - błędny numer bloku końcowego ekstentu %, offset %\n" -#: .././io/open.c:739 +#: .././repair/dinode.c:662 #, c-format -msgid "geom.agcount = %u\n" -msgstr "geom.agcount = %u\n" +msgid "inode % - bad extent overflows - start %, end %, offset %\n" +msgstr "i-węzeł % - błędne przepełnienie ekstentu - początek %, koniec %, offset %\n" -#: .././io/open.c:740 +#: .././repair/dinode.c:672 #, c-format -msgid "geom.agblocks = %u\n" -msgstr "geom.agblocks = %u\n" +msgid "inode % - extent offset too large - start %, count %, offset %\n" +msgstr "i-węzeł % - offset ekstentu zbyt duży - początek %, liczba %, offset %\n" -#: .././io/open.c:741 +#: .././repair/dinode.c:693 #, c-format -msgid "geom.datablocks = %llu\n" -msgstr "geom.datablocks = %llu\n" +msgid "" +"Fatal error: inode % - blkmap_set_ext(): %s\n" +"\t%s fork, off - %, start - %, cnt %\n" +msgstr "" +"Błąd krytyczny: i-węzeł % - blkmap_set_ext(): %s\n" +"\tgałąź %s, offset %, początek %, liczba %\n" -#: .././io/open.c:743 +#: .././repair/dinode.c:724 #, c-format -msgid "geom.rtblocks = %llu\n" -msgstr "geom.rtblocks = %llu\n" +msgid "%s fork in ino % claims dup extent, off - %, start - %, cnt %\n" +msgstr "gałąź %s w i-węźle % odwołuje się do powtórzonego ekstentu, offset %, początek %, liczba %\n" -#: .././io/open.c:745 +#: .././repair/dinode.c:743 #, c-format -msgid "geom.rtextents = %llu\n" -msgstr "geom.rtextents = %llu\n" +msgid "%s fork in ino % claims free block %\n" +msgstr "gałąź %s w i-węźle % odwołuje się do wolnego bloku %\n" -#: .././io/open.c:747 +#: .././repair/dinode.c:751 #, c-format -msgid "geom.rtextsize = %u\n" -msgstr "geom.rtextsize = %u\n" +msgid "bad state in block map %\n" +msgstr "błędny stan w mapie bloku %\n" -#: .././io/open.c:748 +#: .././repair/dinode.c:757 #, c-format -msgid "geom.sunit = %u\n" -msgstr "geom.sunit = %u\n" +msgid "%s fork in inode % claims metadata block %\n" +msgstr "gałąź %s w i-węźle % odwołuje się do bloku metadanych %\n" -#: .././io/open.c:749 +#: .././repair/dinode.c:765 #, c-format -msgid "geom.swidth = %u\n" -msgstr "geom.swidth = %u\n" +msgid "%s fork in %s inode % claims used block %\n" +msgstr "gałąź %s w i-węźle %s % odwołuje się do używanego bloku %\n" -#: .././io/open.c:754 +#: .././repair/dinode.c:771 #, c-format -msgid "counts.freedata = %llu\n" -msgstr "counts.freedata = %llu\n" +msgid "illegal state %d in block map %\n" +msgstr "niedozwolony stan %d w mapie bloku %\n" -#: .././io/open.c:756 +#: .././repair/dinode.c:784 #, c-format -msgid "counts.freertx = %llu\n" -msgstr "counts.freertx = %llu\n" +msgid "correcting nextents for inode %\n" +msgstr "poprawiono nextents dla i-węzła %\n" -#: .././io/open.c:758 +#: .././repair/dinode.c:857 #, c-format -msgid "counts.freeino = %llu\n" -msgstr "counts.freeino = %llu\n" +msgid "cannot read inode (%u/%u), disk block %\n" +msgstr "nie można odczytać i-węzła (%u/%u), blok dysku %\n" -#: .././io/open.c:760 +#: .././repair/dinode.c:928 #, c-format -msgid "counts.allocino = %llu\n" -msgstr "counts.allocino = %llu\n" +msgid "bad level %d in inode % bmap btree root block\n" +msgstr "błędny poziom %d w bloku głównym bmap btree i-węzła %\n" -#: .././io/open.c:775 -msgid "[-acdrstx] [path]" -msgstr "[-acdrstx] [ścieżka]" +#: .././repair/dinode.c:934 +#, c-format +msgid "bad numrecs 0 in inode % bmap btree root block\n" +msgstr "błędne numrecs 0 w bloku głównym bmap btree i-węzła %\n" -#: .././io/open.c:776 -msgid "open the file specified by path" -msgstr "otwarcie pliku określonego ścieżką" +#: .././repair/dinode.c:943 +#, c-format +msgid "indicated size of %s btree root (%d bytes) greater than space in inode % %s fork\n" +msgstr "oznaczony rozmiar korzenia b-drzewa %s (%d bajtów) większy niż miejsce w i-węźle % gałęzi %s\n" -#: .././io/open.c:784 -msgid "[-v]" -msgstr "[-v]" +#: .././repair/dinode.c:963 .././repair/scan.c:429 +#, c-format +msgid "bad bmap btree ptr 0x%llx in ino %\n" +msgstr "błędny wskaźnik bmap btree 0x%llx w i-węźle %\n" -#: .././io/open.c:785 -msgid "statistics on the currently open file" -msgstr "statystyki dla aktualnie otwartego pliku" +#: .././repair/dinode.c:982 +#, c-format +msgid "correcting key in bmbt root (was %llu, now %) in inode % %s fork\n" +msgstr "poprawiono klucz w korzeniu bmbt (był %llu, jest %) w i-węźle % gałęzi %s\n" -#: .././io/open.c:793 -msgid "close the current open file" -msgstr "zamknięcie bieżącego otwartego pliku" +#: .././repair/dinode.c:994 +#, c-format +msgid "bad key in bmbt root (is %llu, would reset to %) in inode % %s fork\n" +msgstr "błędny klucz w korzeniu bmbt (jest %llu, zostałby przestawiony na %) w i-węźle % gałęzi %s\n" -#: .././io/open.c:797 -msgid "[-adx]" -msgstr "[-adx]" - -#: .././io/open.c:800 -msgid "set/clear append/direct flags on the open file" -msgstr "ustawienie/zdjęcie flag dopisywania/bezpośredniego we/wy dla otwartego pliku" +#: .././repair/dinode.c:1011 +#, c-format +msgid "out of order bmbt root key % in inode % %s fork\n" +msgstr "niepoprawny klucz korzenia bmbt % w i-węźle % gałęzi %s\n" -#: .././io/open.c:806 -msgid "statistics on the filesystem of the currently open file" -msgstr "statystyki dla systemu plików aktualnie otwartego pliku" +#: .././repair/dinode.c:1028 +#, c-format +msgid "extent count for ino % %s fork too low (%) for file format\n" +msgstr "i-węzeł %: liczba ekstentów dla odgałęzienia %s zbyt mała (%) dla formatu pliku\n" -#: .././io/open.c:810 -msgid "[-D | -R] projid" -msgstr "[-D | -R] projid" +#: .././repair/dinode.c:1039 +#, c-format +msgid "bad fwd (right) sibling pointer (saw % should be NULLDFSBNO)\n" +msgstr "błędny wskaźnik fwd (prawy) (widziano %, powinno być NULLDFSBNO)\n" -#: .././io/open.c:815 -msgid "change project identifier on the currently open file" -msgstr "zmiana identyfikatora projektu aktualnie otwartego pliku" +#: .././repair/dinode.c:1042 +#, c-format +msgid "\tin inode % (%s fork) bmap btree block %\n" +msgstr "\tw i-węźle % (gałęzi %s) bloku bmap btree %\n" -#: .././io/open.c:820 -msgid "[-D | -R]" -msgstr "[-D | -R]" +#: .././repair/dinode.c:1124 +#, c-format +msgid "local inode % data fork is too large (size = %lld, max = %d)\n" +msgstr "gałąź danych lokalnego i-węzła % zbyt duża (rozmiar = %lld, maksimum = %d)\n" -#: .././io/open.c:825 -msgid "list project identifier set on the currently open file" -msgstr "wypisanie identyfikatora projektu aktualnie otwartego pliku" +#: .././repair/dinode.c:1132 +#, c-format +msgid "local inode % attr fork too large (size %d, max = %d)\n" +msgstr "gałąź atrybutów lokalnego i-węzła % zbyt duża (rozmiar %d, maksimum = %d)\n" -#: .././io/open.c:830 -msgid "[-D | -R] [extsize]" -msgstr "[-D | -R] [rozmiar_fragmentu]" - -#: .././io/open.c:835 -msgid "get/set preferred extent size (in bytes) for the open file" -msgstr "pobranie/ustawienie preferowanego rozmiaru ekstentu (w bajtach) dla otwartego pliku" - -#: .././growfs/xfs_growfs.c:34 +#: .././repair/dinode.c:1139 #, c-format -msgid "" -"Usage: %s [options] mountpoint\n" -"\n" -"Options:\n" -"\t-d grow data/metadata section\n" -"\t-l grow log section\n" -"\t-r grow realtime section\n" -"\t-n don't change anything, just show geometry\n" -"\t-I allow inode numbers to exceed %d significant bits\n" -"\t-i convert log from external to internal format\n" -"\t-t alternate location for mount table (/etc/mtab)\n" -"\t-x convert log from internal to external format\n" -"\t-D size grow data/metadata section to size blks\n" -"\t-L size grow/shrink log section to size blks\n" -"\t-R size grow realtime section to size blks\n" -"\t-e size set realtime extent size to size blks\n" -"\t-m imaxpct set inode max percent to imaxpct\n" -"\t-V print version information\n" -msgstr "" -"Składnia: %s [opcje] punkt_montowania\n" -"\n" -"Opcje:\n" -"\t-d powiększenie sekcji danych/metadanych\n" -"\t-l powiększenie sekcji logu\n" -"\t-r powiększenie sekcji realtime\n" -"\t-n bez zmian, tylko pokazanie geometrii\n" -"\t-I zezwolenie na przekroczenie %d bitów przez numery i-węzłów\n" -"\t-i przekształcenie logu z formatu zewnętrznego na wewnętrzny\n" -"\t-t inne położenie tabeli montowań (/etc/mtab)\n" -"\t-x przekształcenie logu z formatu wewnętrznego na zewnętrzny\n" -"\t-D rozmiar powiększenie sekcji danych/metadanych do rozmiaru w blokach\n" -"\t-L rozmiar powiększenie/zmniejszenie sekcji logu do rozmiaru w blokach\n" -"\t-R rozmiar powiększenie sekcji realtime do rozmiaru w blokach\n" -"\t-e rozmiar stawienie rozmiaru ekstentu realtime na rozmiar w blokach\n" -"\t-m imaxpct ustawienie maksymalnego procentu i-węzłów na imaxpct\n" -"\t-V wypisanie informacji o wersji\n" +msgid "local inode % attr too small (size = %d, min size = %zd)\n" +msgstr "gałąź atrybutów lokalnego i-węzła % zbyt mała (rozmiar = %d, minimum = %zd)\n" -#: .././growfs/xfs_growfs.c:68 +#: .././repair/dinode.c:1163 #, c-format -msgid "" -"meta-data=%-22s isize=%-6u agcount=%u, agsize=%u blks\n" -" =%-22s sectsz=%-5u attr=%u\n" -"data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" -" =%-22s sunit=%-6u swidth=%u blks\n" -"naming =version %-14u bsize=%-6u ascii-ci=%d\n" -"log =%-22s bsize=%-6u blocks=%u, version=%u\n" -" =%-22s sectsz=%-5u sunit=%u blks, lazy-count=%u\n" -"realtime =%-22s extsz=%-6u blocks=%llu, rtextents=%llu\n" -msgstr "" -"metadane=%-22s isize=%-6u agcount=%u, agsize=%u bloków\n" -" =%-22s sectsz=%-5u attr=%u\n" -"dane =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" -" =%-22s sunit=%-6u swidth=%u bloków\n" -"nazwy =wersja %-14u bsize=%-6u\n" -" ascii-ci=%d\n" -"log =%-22s bsize=%-6u blocks=%u, wersja=%u\n" -" =%-22s sectsz=%-5u sunit=%u bloków, lazy-count=%u\n" -"realtime=%-22s extsz=%-6u blocks=%llu, rtextents=%llu\n" - -#: .././growfs/xfs_growfs.c:83 .././growfs/xfs_growfs.c:444 -#: .././growfs/xfs_growfs.c:445 -msgid "internal" -msgstr "wewnętrzny" - -#: .././growfs/xfs_growfs.c:83 .././growfs/xfs_growfs.c:86 -#: .././growfs/xfs_growfs.c:444 .././growfs/xfs_growfs.c:445 -msgid "external" -msgstr "zewnętrzny" +msgid "mismatch between format (%d) and size (%) in symlink ino %\n" +msgstr "niezgodność między formatem (%d) a rozmiarem (%) w i-węźle dowiązania symbolicznego %\n" -#: .././growfs/xfs_growfs.c:199 +#: .././repair/dinode.c:1170 #, c-format -msgid "%s: %s is not a mounted XFS filesystem\n" -msgstr "%s: %s nie jest podmontowanym systemem plików XFS\n" +msgid "mismatch between format (%d) and size (%) in symlink inode %\n" +msgstr "niezgodność między formatem (%d) a rozmiarem (%) w i-węźle dowiązania symbolicznego %\n" -#: .././growfs/xfs_growfs.c:216 +#: .././repair/dinode.c:1185 #, c-format -msgid "%s: specified file [\"%s\"] is not on an XFS filesystem\n" -msgstr "%s: podany plik [\"%s\"] nie jest na systemie plików XFS\n" +msgid "bad number of extents (%d) in symlink % data fork\n" +msgstr "błędna liczba ekstentów (%d) w gałęzi danych dowiązania symbolicznego %\n" -#: .././growfs/xfs_growfs.c:233 +#: .././repair/dinode.c:1198 #, c-format -msgid "%s: cannot determine geometry of filesystem mounted at %s: %s\n" -msgstr "%s: nie można określić geometrii systemu plików podmontowanego pod %s: %s\n" +msgid "bad extent #%d offset (%) in symlink % data fork\n" +msgstr "błędny offset ekstentu %d (%) w gałęzi danych dowiązania symbolicznego %\n" -#: .././growfs/xfs_growfs.c:268 +#: .././repair/dinode.c:1204 #, c-format -msgid "%s: failed to access data device for %s\n" -msgstr "%s: nie udało się uzyskać dostępu do urządzenia z danymi dla %s\n" +msgid "bad extent #%d count (%) in symlink % data fork\n" +msgstr "błędna liczba ekstentów #%d (%) w gałęzi danych dowiązania symbolicznego %\n" -#: .././growfs/xfs_growfs.c:273 +#: .././repair/dinode.c:1262 #, c-format -msgid "%s: failed to access external log for %s\n" -msgstr "%s: nie udało się uzyskać dostępu do zewnętrznego logu dla %s\n" +msgid "cannot read inode %, file block %d, NULL disk block\n" +msgstr "nie można odczytać i-węzła %, blok pliku %d, zerowy blok dysku\n" -#: .././growfs/xfs_growfs.c:279 +#: .././repair/dinode.c:1284 #, c-format -msgid "%s: failed to access realtime device for %s\n" -msgstr "%s: nie udało się uzyskać dostępu do urządzenia realtime dla %s\n" +msgid "cannot read inode %, file block %d, disk block %\n" +msgstr "nie można odczytać i-węzła %, blok pliku %d, blok dysku %\n" -#: .././growfs/xfs_growfs.c:314 +#: .././repair/dinode.c:1290 #, c-format -msgid "data size %lld too large, maximum is %lld\n" -msgstr "rozmiar danych %lld zbyt duży, maksymalny to %lld\n" +msgid "" +"Bad symlink buffer CRC, block %, inode %.\n" +"Correcting CRC, but symlink may be bad.\n" +msgstr "" +"Błędna suma kontrolna bufora dowiązania symbolicznego, blok %, i-węzeł %.\n" +"Poprawianie CRC, ale dowiązanie symboliczne może być błędne.\n" -#: .././growfs/xfs_growfs.c:321 +#: .././repair/dinode.c:1303 #, c-format -msgid "data size %lld too small, old size is %lld\n" -msgstr "rozmiar danych %lld zbyt mały, stary rozmiar to %lld\n" +msgid "bad symlink header ino %, file block %d, disk block %\n" +msgstr "błędny i-węzeł nagłówka dowiązania symbolicznego %, blok pliku %d, blok dysku %\n" -#: .././growfs/xfs_growfs.c:329 +#: .././repair/dinode.c:1346 #, c-format -msgid "data size unchanged, skipping\n" -msgstr "rozmiar danych nie zmieniony, pominięto\n" +msgid "symlink in inode % too long (%llu chars)\n" +msgstr "dowiązanie symboliczne w i-węźle % zbyt długie (%llu znaków)\n" -#: .././growfs/xfs_growfs.c:332 +#: .././repair/dinode.c:1378 #, c-format -msgid "inode max pct unchanged, skipping\n" -msgstr "maksymalny procent i-węzłów nie zmieniony, pominięto\n" +msgid "found illegal null character in symlink inode %\n" +msgstr "znaleziono niedozwolony znak null w i-węźle dowiązania symbolicznego %\n" -#: .././growfs/xfs_growfs.c:339 .././growfs/xfs_growfs.c:378 -#: .././growfs/xfs_growfs.c:413 +#: .././repair/dinode.c:1392 .././repair/dinode.c:1402 #, c-format -msgid "%s: growfs operation in progress already\n" -msgstr "%s: operacja growfs już trwa\n" +msgid "component of symlink in inode % too long\n" +msgstr "składnik dowiązania symbolicznego w i-węźle % zbyt długi\n" -#: .././growfs/xfs_growfs.c:343 +#: .././repair/dinode.c:1428 #, c-format -msgid "%s: XFS_IOC_FSGROWFSDATA xfsctl failed: %s\n" -msgstr "%s: xfsctl XFS_IOC_FSGROWFSDATA nie powiodło się: %s\n" +msgid "inode % has bad inode type (IFMNT)\n" +msgstr "i-węzeł % ma błędny typ i-węzła (IFMNT)\n" -#: .././growfs/xfs_growfs.c:359 +#: .././repair/dinode.c:1439 #, c-format -msgid "realtime size %lld too large, maximum is %lld\n" -msgstr "rozmiar realtime %lld zbyt duży, maksymalny to %lld\n" +msgid "size of character device inode % != 0 (% bytes)\n" +msgstr "rozmiar i-węzła urządzenia znakowego % != 0 (% bajtów)\n" -#: .././growfs/xfs_growfs.c:365 +#: .././repair/dinode.c:1444 #, c-format -msgid "realtime size %lld too small, old size is %lld\n" -msgstr "rozmiar realtime %lld zbyt mały, stary rozmiar to %lld\n" +msgid "size of block device inode % != 0 (% bytes)\n" +msgstr "rozmiar i-węzła urządzenia blokowego % != 0 (% bajtów)\n" -#: .././growfs/xfs_growfs.c:371 +#: .././repair/dinode.c:1449 #, c-format -msgid "realtime size unchanged, skipping\n" -msgstr "rozmiar realtime nie zmieniony, pominięto\n" +msgid "size of socket inode % != 0 (% bytes)\n" +msgstr "rozmiar i-węzła gniazda % != 0 (% bajtów)\n" -#: .././growfs/xfs_growfs.c:382 +#: .././repair/dinode.c:1454 #, c-format -msgid "%s: realtime growth not implemented\n" -msgstr "%s: powiększanie realtime nie jest zaimplementowane\n" +msgid "size of fifo inode % != 0 (% bytes)\n" +msgstr "rozmiar i-węzła potoku % != 0 (% bajtów)\n" -#: .././growfs/xfs_growfs.c:386 +#: .././repair/dinode.c:1458 #, c-format -msgid "%s: XFS_IOC_FSGROWFSRT xfsctl failed: %s\n" -msgstr "%s: xfsctl XFS_IOC_FSGROWFSRT nie powiodło się: %s\n" +msgid "Internal error - process_misc_ino_types, illegal type %d\n" +msgstr "Błąd wewnętrzny - process_misc_ino_types, niedozwolony typ %d\n" -#: .././growfs/xfs_growfs.c:407 +#: .././repair/dinode.c:1485 #, c-format -msgid "log size unchanged, skipping\n" -msgstr "rozmiar logu nie zmieniony, pominięto\n" +msgid "size of character device inode % != 0 (% blocks)\n" +msgstr "rozmiar i-węzła urządzenia znakowego % != 0 (% bloków)\n" -#: .././growfs/xfs_growfs.c:417 +#: .././repair/dinode.c:1490 #, c-format -msgid "%s: log growth not supported yet\n" -msgstr "%s: powiększanie logu nie jest jeszcze obsługiwane\n" +msgid "size of block device inode % != 0 (% blocks)\n" +msgstr "rozmiar i-węzła urządzenia blokowego % != 0 (% bloków)\n" -#: .././growfs/xfs_growfs.c:421 +#: .././repair/dinode.c:1495 #, c-format -msgid "%s: XFS_IOC_FSGROWFSLOG xfsctl failed: %s\n" -msgstr "%s: xfsctl XFS_IOC_FSGROWFSLOG nie powiodło się: %s\n" +msgid "size of socket inode % != 0 (% blocks)\n" +msgstr "rozmiar i-węzła gniazda % != 0 (% bloków)\n" -#: .././growfs/xfs_growfs.c:429 +#: .././repair/dinode.c:1500 #, c-format -msgid "%s: XFS_IOC_FSGEOMETRY xfsctl failed: %s\n" -msgstr "%s: xfsctl XFS_IOC_FSGEOMETRY nie powiodło się: %s\n" +msgid "size of fifo inode % != 0 (% blocks)\n" +msgstr "rozmiar i-węzła potoku % != 0 (% bloków)\n" -#: .././growfs/xfs_growfs.c:434 +#: .././repair/dinode.c:1578 #, c-format -msgid "data blocks changed from %lld to %lld\n" -msgstr "bloki danych zmienione z %lld na %lld\n" +msgid "root inode % has bad type 0x%x\n" +msgstr "i-węzeł główny % ma błędny typ 0x%x\n" -#: .././growfs/xfs_growfs.c:437 -#, c-format -msgid "inode max percent changed from %d to %d\n" -msgstr "maksymalny procent i-węzłów zmieniony z %d na %d\n" +#: .././repair/dinode.c:1582 +msgid "resetting to directory\n" +msgstr "przestawiono na katalog\n" -#: .././growfs/xfs_growfs.c:440 -#, c-format -msgid "log blocks changed from %d to %d\n" -msgstr "bloki logu zmienione z %d na %d\n" +#: .././repair/dinode.c:1586 +msgid "would reset to directory\n" +msgstr "zostałby przestawiony na katalog\n" -#: .././growfs/xfs_growfs.c:443 +#: .././repair/dinode.c:1592 #, c-format -msgid "log changed from %s to %s\n" -msgstr "log zmieniony - był %s, jest %s\n" +msgid "user quota inode % has bad type 0x%x\n" +msgstr "i-węzeł limitu użytkownika % ma błędny typ 0x%x\n" -#: .././growfs/xfs_growfs.c:447 +#: .././repair/dinode.c:1601 #, c-format -msgid "realtime blocks changed from %lld to %lld\n" -msgstr "bloki realtime zmienione z %lld na %lld\n" +msgid "group quota inode % has bad type 0x%x\n" +msgstr "i-węzeł limitu grupy % ma błędny typ 0x%x\n" -#: .././growfs/xfs_growfs.c:450 +#: .././repair/dinode.c:1610 #, c-format -msgid "realtime extent size changed from %d to %d\n" -msgstr "rozmiar ekstentu realtime zmieniony z %d na %d\n" +msgid "project quota inode % has bad type 0x%x\n" +msgstr "i-węzeł limitu projektu % ma błędny typ 0x%x\n" -#: .././fsr/xfs_fsr.c:196 +#: .././repair/dinode.c:1620 #, c-format -msgid "%s: cannot read %s\n" -msgstr "%s: nie można odczytać %s\n" +msgid "realtime summary inode % has bad type 0x%x, " +msgstr "i-węzeł opisu realtime % ma błędny typ 0x%x, " -#: .././fsr/xfs_fsr.c:275 -#, c-format -msgid "%s: Stats not yet supported for XFS\n" -msgstr "%s: statystyki nie są jeszcze obsługiwane dla XFS-a\n" +#: .././repair/dinode.c:1623 .././repair/dinode.c:1644 +msgid "resetting to regular file\n" +msgstr "przestawiono na zwykły plik\n" + +#: .././repair/dinode.c:1627 .././repair/dinode.c:1648 +msgid "would reset to regular file\n" +msgstr "zostałby przestawiony na zwykły plik\n" -#: .././fsr/xfs_fsr.c:339 +#: .././repair/dinode.c:1632 #, c-format -msgid "%s: could not stat: %s: %s\n" -msgstr "%s: nie można wykonać stat: %s: %s\n" +msgid "bad # of extents (%u) for realtime summary inode %\n" +msgstr "błędna liczba ekstentów (%u) dla i-węzłą opisu realtime %\n" -#: .././fsr/xfs_fsr.c:358 +#: .././repair/dinode.c:1641 #, c-format -msgid "%s: char special not supported: %s\n" -msgstr "%s: urządzenia znakowe nie są obsługiwane: %s\n" +msgid "realtime bitmap inode % has bad type 0x%x, " +msgstr "i-węzeł bitmapy realtime % ma błędny typ 0x%x, " -#: .././fsr/xfs_fsr.c:364 +#: .././repair/dinode.c:1653 #, c-format -msgid "%s: cannot defragment: %s: Not XFS\n" -msgstr "%s: nie można zdefragmentować: %s: to nie jest XFS\n" +msgid "bad # of extents (%u) for realtime bitmap inode %\n" +msgstr "błędna liczba ekstentów (%u) dla i-węzłą bitmapy realtime %\n" -#: .././fsr/xfs_fsr.c:374 +#: .././repair/dinode.c:1688 #, c-format -msgid "%s: not fsys dev, dir, or reg file, ignoring\n" -msgstr "%s: nie jest urządzeniem z systemem plików, katalogiem ani zwykłym plikiem, zignorowano\n" +msgid "mismatch between format (%d) and size (%) in directory ino %\n" +msgstr "niezgodność między formatem (%d) a rozmiarem (%) w i-węźle katalogu %\n" -#: .././fsr/xfs_fsr.c:389 +#: .././repair/dinode.c:1694 #, c-format -msgid "" -"Usage: %s [-d] [-v] [-n] [-s] [-g] [-t time] [-p passes] [-f leftf] [-m mtab]\n" -" %s [-d] [-v] [-n] [-s] [-g] xfsdev | dir | file ...\n" -"\n" -"Options:\n" -" -n Do nothing, only interesting with -v. Not\n" -" effective with in mtab mode.\n" -" -s\t\tPrint statistics only.\n" -" -g Print to syslog (default if stdout not a tty).\n" -" -t time How long to run in seconds.\n" -" -p passes\tNumber of passes before terminating global re-org.\n" -" -f leftoff Use this instead of %s.\n" -" -m mtab Use something other than /etc/mtab.\n" -" -d Debug, print even more.\n" -" -v\t\tVerbose, more -v's more verbose.\n" -msgstr "" -"Składnia: %s [-d] [-v] [-n] [-s] [-g] [-t czas] [-p przebiegi] [-f leftf] [-m mtab]\n" -" %s [-d] [-v] [-n] [-s] [-g] xfsdev | katalog | plik ...\n" -"\n" -"Opcje:\n" -" -n Nie robienie niczego, przydatne tylko z -v.\n" -" Nieprzydatne w trybie mtab.\n" -" -s Tylko wypisanie statystyk.\n" -" -g Pisanie do sysloga (domyślne jeśli stdout to nie tty).\n" -" -t czas Czas działania w sekundach.\n" -" -p przebiegi Liczba przebiegów przed zakończeniem reorganizacji.\n" -" -f leftoff Użycie tego pliku zamiast %s.\n" -" -m mtab Użycie pliku innego niż /etc/mtab.\n" -" -d Diagnostyka, dużo więcej informacji.\n" -" -v Tym więcej szczegółów, im więcej opcji -v.\n" +msgid "directory inode % has bad size %\n" +msgstr "i-węzeł katalogu % ma błędny rozmiar %\n" -#: .././fsr/xfs_fsr.c:420 +#: .././repair/dinode.c:1702 #, c-format -msgid "could not open mtab file: %s\n" -msgstr "nie udało się otworzyć pliku mtab: %s\n" +msgid "bad data fork in symlink %\n" +msgstr "błędna gałąź danych w dowiązaniu symbolicznym %\n" -#: .././fsr/xfs_fsr.c:426 .././fsr/xfs_fsr.c:458 +#: .././repair/dinode.c:1723 #, c-format -msgid "out of memory: %s\n" -msgstr "brak pamięci: %s\n" +msgid "found inode % claiming to be a real-time file\n" +msgstr "znaleziono i-węzeł % twierdzący, że należy do pliku realtime\n" -#: .././fsr/xfs_fsr.c:449 +#: .././repair/dinode.c:1732 #, c-format -msgid "Skipping %s: not mounted rw\n" -msgstr "Pominięto %s: nie zamontowany rw\n" +msgid "realtime bitmap inode % has bad size % (should be %)\n" +msgstr "i-węzeł bitmapy realtime % ma błędny rozmiar % (powinien być %)\n" -#: .././fsr/xfs_fsr.c:463 +#: .././repair/dinode.c:1743 #, c-format -msgid "out of memory on realloc: %s\n" -msgstr "brak pamięci przy realloc: %s\n" +msgid "realtime summary inode % has bad size % (should be %d)\n" +msgstr "i-węzeł opisu realtime % ma błędny rozmiar % (powinien być %d)\n" -#: .././fsr/xfs_fsr.c:474 +#: .././repair/dinode.c:1771 #, c-format -msgid "strdup(%s) failed\n" -msgstr "strdup(%s) nie powiodło się\n" +msgid "bad attr fork offset %d in dev inode %, should be %d\n" +msgstr "błędny offset gałęzi atrybutów %d w i-węźle urządzenia %, powinien być %d\n" -#: .././fsr/xfs_fsr.c:484 +#: .././repair/dinode.c:1783 #, c-format -msgid "no rw xfs file systems in mtab: %s\n" -msgstr "brak w pliku mtab systemów plików xfs w trybie rw: %s\n" +msgid "bad attr fork offset %d in inode %, max=%d\n" +msgstr "błędny offset gałęzi atrybutów %d w i-węźle %, maksimum=%d\n" -#: .././fsr/xfs_fsr.c:488 +#: .././repair/dinode.c:1790 #, c-format -msgid "Found %d mounted, writable, XFS filesystems\n" -msgstr "Liczba znalezionych zamontowanych, zapisywalnych systemów plików XFS: %d\n" +msgid "unexpected inode format %d\n" +msgstr "nieoczekiwany format i-węzła %d\n" -#: .././fsr/xfs_fsr.c:518 +#: .././repair/dinode.c:1811 #, c-format -msgid "%s: open failed\n" -msgstr "%s: open nie powiodło się\n" +msgid "correcting nblocks for inode %, was %llu - counted %\n" +msgstr "poprawiono nblocks dla i-węzła % - było %llu, naliczono %\n" -#: .././fsr/xfs_fsr.c:533 +#: .././repair/dinode.c:1818 #, c-format -msgid "Can't use %s: mode=0%o own=%d nlink=%d\n" -msgstr "Nie można użyć %s: mode=0%o own=%d nlink=%d\n" +msgid "bad nblocks %llu for inode %, would reset to %\n" +msgstr "błędne nblocks %llu dla i-węzła %, zostałoby przestawione na %\n" -#: .././fsr/xfs_fsr.c:553 +#: .././repair/dinode.c:1826 #, c-format -msgid "could not read %s, starting with %s\n" -msgstr "nie można odczytać %s, rozpoczęcie z %s\n" +msgid "too many data fork extents (%) in inode %\n" +msgstr "zbyt dużo ekstentów gałęzi danych (%) w i-węźle %\n" -#: .././fsr/xfs_fsr.c:590 +#: .././repair/dinode.c:1833 #, c-format -msgid "START: pass=%d ino=%llu %s %s\n" -msgstr "START: przebieg=%d i-węzeł=%llu %s %s\n" +msgid "correcting nextents for inode %, was %d - counted %\n" +msgstr "poprawiono nextents dla i-węzła % - było %d, naliczono %\n" -#: .././fsr/xfs_fsr.c:607 +#: .././repair/dinode.c:1841 #, c-format -msgid "Completed all %d passes\n" -msgstr "Zakończono wszystkie przebiegi w liczbie %d\n" - -#: .././fsr/xfs_fsr.c:617 -msgid "couldn't fork sub process:" -msgstr "nie udało się uruchomić podprocesu:" +msgid "bad nextents %d for inode %, would reset to %\n" +msgstr "błędne nextents %d dla i-węzła %, zostałoby przestawione na %\n" -#: .././fsr/xfs_fsr.c:654 +#: .././repair/dinode.c:1849 #, c-format -msgid "open(%s) failed: %s\n" -msgstr "open(%s) nie powiodło się: %s\n" +msgid "too many attr fork extents (%) in inode %\n" +msgstr "zbyt dużo ekstentów gałęzi atrybutów (%) w i-węźle %\n" -#: .././fsr/xfs_fsr.c:661 +#: .././repair/dinode.c:1856 #, c-format -msgid "write(%s) failed: %s\n" -msgstr "write(%s) nie powiodło się: %s\n" +msgid "correcting anextents for inode %, was %d - counted %\n" +msgstr "poprawiono anextents dla i-węzła % - było %d, naliczono %\n" -#: .././fsr/xfs_fsr.c:668 +#: .././repair/dinode.c:1863 #, c-format -msgid "%s startpass %d, endpass %d, time %d seconds\n" -msgstr "%s pocz. przebieg %d, końc. przebieg %d, czas %d sekund\n" +msgid "bad anextents %d for inode %, would reset to %\n" +msgstr "błędne anextents %d dla i-węzła %, zostałoby przestawione na %\n" -#: .././fsr/xfs_fsr.c:690 +#: .././repair/dinode.c:1875 #, c-format -msgid "%s start inode=%llu\n" -msgstr "%s pocz. i-węzeł=%llu\n" +msgid "nblocks (%) smaller than nextents for inode %\n" +msgstr "nblocks (%) mniejsze niż nextents dla i-węzła %\n" -#: .././fsr/xfs_fsr.c:695 +#: .././repair/dinode.c:1940 .././repair/dinode.c:1978 #, c-format -msgid "unable to get handle: %s: %s\n" -msgstr "nie udało się uzyskać uchwytu: %s: %s\n" +msgid "unknown format %d, ino % (mode = %d)\n" +msgstr "nieznany format %d, i-węzeł % (tryb = %d)\n" -#: .././fsr/xfs_fsr.c:701 +#: .././repair/dinode.c:1945 #, c-format -msgid "unable to open: %s: %s\n" -msgstr "nie udało się otworzyć: %s: %s\n" +msgid "bad data fork in inode %\n" +msgstr "błędna gałąź danych w i-węźle %\n" -#: .././fsr/xfs_fsr.c:707 +#: .././repair/dinode.c:2016 #, c-format -msgid "Skipping %s: could not get XFS geometry\n" -msgstr "Pominięto %s: nie można odczytać geometrii XFS\n" +msgid "bad attribute format %d in inode %, " +msgstr "błędny format atrybutów %d w i-węźle %, " -#: .././fsr/xfs_fsr.c:739 -#, c-format -msgid "could not open: inode %llu\n" -msgstr "nie udało się otworzyć: i-węzeł %llu\n" +#: .././repair/dinode.c:2019 +msgid "resetting value\n" +msgstr "przestawiono wartość\n" -#: .././fsr/xfs_fsr.c:769 -#, c-format -msgid "%s: xfs_bulkstat: %s\n" -msgstr "%s: xfs_bulkstat: %s\n" +#: .././repair/dinode.c:2023 +msgid "would reset value\n" +msgstr "wartość zostałaby przestawiona\n" -#: .././fsr/xfs_fsr.c:795 +#: .././repair/dinode.c:2068 #, c-format -msgid "%s: Directory defragmentation not supported\n" -msgstr "%s: Defragmentacja katalogów nie jest obsługiwana\n" +msgid "bad attribute fork in inode %" +msgstr "błędna gałąź atrybutów w i-węźle %" -#: .././fsr/xfs_fsr.c:814 -#, c-format -msgid "unable to construct sys handle for %s: %s\n" -msgstr "nie udało się utworzyć uchwytu systemowego dla %s: %s\n" +#: .././repair/dinode.c:2072 +msgid ", clearing attr fork\n" +msgstr ", wyczyszczono gałąź atrybutów\n" -#: .././fsr/xfs_fsr.c:825 -#, c-format -msgid "unable to open sys handle for %s: %s\n" -msgstr "nie udało się otworzyć uchwytu systemowego dla %s: %s\n" +#: .././repair/dinode.c:2081 +msgid ", would clear attr fork\n" +msgstr ", gałąź atrybutów zostałaby wyczyszczona\n" -#: .././fsr/xfs_fsr.c:831 +#: .././repair/dinode.c:2109 #, c-format -msgid "unable to get bstat on %s: %s\n" -msgstr "nie udało się uzyskać bstat na %s: %s\n" +msgid "illegal attribute fmt %d, ino %\n" +msgstr "niedozwolony format atrybutów %d, i-węzeł %\n" -#: .././fsr/xfs_fsr.c:839 +#: .././repair/dinode.c:2129 #, c-format -msgid "unable to open handle %s: %s\n" -msgstr "nie udało się otworzyć uchwytu %s: %s\n" +msgid "problem with attribute contents in inode %\n" +msgstr "problem z zawartością atrybutu w i-węźle %\n" -#: .././fsr/xfs_fsr.c:847 -#, c-format -msgid "Unable to get geom on fs for: %s\n" -msgstr "Nie udało się odczytać geometrii systemu plików dla: %s\n" +#: .././repair/dinode.c:2137 +msgid "would clear attr fork\n" +msgstr "gałąź atrybutów zostałaby wyczyszczona\n" -#: .././fsr/xfs_fsr.c:896 +#: .././repair/dinode.c:2180 #, c-format -msgid "sync failed: %s: %s\n" -msgstr "sync nie powiodło się: %s: %s\n" +msgid "version 2 inode % claims > %u links, " +msgstr "i-węzeł % w wersji 2 odwołuje się do > %u dowiązań, " -#: .././fsr/xfs_fsr.c:902 -#, c-format -msgid "%s: zero size, ignoring\n" -msgstr "%s: zerowy rozmiar, zignorowano\n" +#: .././repair/dinode.c:2184 +msgid "updating superblock version number\n" +msgstr "uaktualniono numer wersji superbloku\n" -#: .././fsr/xfs_fsr.c:921 -#, c-format -msgid "locking check failed: %s\n" -msgstr "sprawdzenie blokowania nie powiodło się: %s\n" +#: .././repair/dinode.c:2187 +msgid "would update superblock version number\n" +msgstr "numer wersji superbloku zostałby uaktualniony\n" -#: .././fsr/xfs_fsr.c:928 +#: .././repair/dinode.c:2195 #, c-format -msgid "mandatory lock: %s: ignoring\n" -msgstr "obowiązkowa blokada: %s: zignorowano\n" +msgid "WARNING: version 2 inode % claims > %u links, " +msgstr "UWAGA: i-węzeł % w wersji 2 odwołuje się do > %u dowiązań, " -#: .././fsr/xfs_fsr.c:941 +#: .././repair/dinode.c:2198 #, c-format -msgid "unable to get fs stat on %s: %s\n" -msgstr "nie udało się uzyskać stat fs na %s: %s\n" +msgid "" +"converting back to version 1,\n" +"this may destroy %d links\n" +msgstr "" +"przekształcanie z powrotem do wersji 1,\n" +"może to zniszczyć %d dowiązań\n" -#: .././fsr/xfs_fsr.c:948 +#: .././repair/dinode.c:2208 #, c-format -msgid "insufficient freespace for: %s: size=%lld: ignoring\n" -msgstr "niewystarczająca ilość miejsca dla: %s: rozmiar=%lld: zignorowano\n" +msgid "" +"would convert back to version 1,\n" +"\tthis might destroy %d links\n" +msgstr "" +"zostałby przekształcony z powrotem do wersji 1,\n" +"\tco mogłoby zniszczyć %d dowiązań\n" -#: .././fsr/xfs_fsr.c:955 +#: .././repair/dinode.c:2223 #, c-format -msgid "failed to get inode attrs: %s\n" -msgstr "nie udało się uzyskać atrybutów i-węzła: %s\n" +msgid "found version 2 inode %, " +msgstr "znaleziono i-węzeł % w wersji 2, " -#: .././fsr/xfs_fsr.c:960 -#, c-format -msgid "%s: immutable/append, ignoring\n" -msgstr "%s: niezmienny/tylko do dołączania, zignorowano\n" +#: .././repair/dinode.c:2225 +msgid "converting back to version 1\n" +msgstr "przekształcono z powrotem do wersji 1\n" + +#: .././repair/dinode.c:2231 +msgid "would convert back to version 1\n" +msgstr "zostałby przekształcony z powrotem do wersji 1\n" -#: .././fsr/xfs_fsr.c:965 +#: .././repair/dinode.c:2245 #, c-format -msgid "%s: marked as don't defrag, ignoring\n" -msgstr "%s: oznaczony jako nie do defragmentacji, zignorowano\n" +msgid "clearing obsolete nlink field in version 2 inode %, was %d, now 0\n" +msgstr "wyczyszczono przestarzałe pole nlink w i-węźle % w wersji 2 - było %d, jest 0\n" -#: .././fsr/xfs_fsr.c:971 +#: .././repair/dinode.c:2251 #, c-format -msgid "cannot get realtime geometry for: %s\n" -msgstr "nie można uzyskać geometrii realtime dla: %s\n" +msgid "would clear obsolete nlink field in version 2 inode %, currently %d\n" +msgstr "przestarzałe pole nlink w i-węźle % w wersji 2 zostałoby wyczyszczone, aktualnie %d\n" -#: .././fsr/xfs_fsr.c:976 +#: .././repair/dinode.c:2320 #, c-format -msgid "low on realtime free space: %s: ignoring file\n" -msgstr "mało wolnego miejsca realtime: %s: plik zignorowany\n" +msgid "bad magic number 0x%x on inode %%c" +msgstr "błędna liczba magiczna 0x%x w i-węźle %%c" -#: .././fsr/xfs_fsr.c:983 +#: .././repair/dinode.c:2325 +msgid " resetting magic number\n" +msgstr " przestawiono liczbę magiczną\n" + +#: .././repair/dinode.c:2329 +msgid " would reset magic number\n" +msgstr " liczba magiczna zostałaby przestawiona\n" + +#: .././repair/dinode.c:2338 #, c-format -msgid "cannot open: %s: Permission denied\n" -msgstr "nie można otworzyć: %s: brak uprawnień\n" +msgid "bad version number 0x%x on inode %%c" +msgstr "błędny numer wersji 0x%x w i-węźle %%c" -#: .././fsr/xfs_fsr.c:1040 .././fsr/xfs_fsr.c:1085 .././fsr/xfs_fsr.c:1131 -msgid "could not set ATTR\n" -msgstr "nie udało się ustawić ATTR\n" +#: .././repair/dinode.c:2343 +msgid " resetting version number\n" +msgstr " przestawiono numer wersji\n" + +#: .././repair/dinode.c:2349 +msgid " would reset version number\n" +msgstr " numer wersji zostałby przestawiony\n" -#: .././fsr/xfs_fsr.c:1049 +#: .././repair/dinode.c:2362 #, c-format -msgid "unable to stat temp file: %s\n" -msgstr "nie udało się wykonać stat na pliku tymczasowym: %s\n" +msgid "inode identifier %llu mismatch on inode %\n" +msgstr "niezgodność identyfikatora i-węzła %llu dla i-węzła %\n" -#: .././fsr/xfs_fsr.c:1068 +#: .././repair/dinode.c:2371 #, c-format -msgid "unable to get bstat on temp file: %s\n" -msgstr "nie udało się uzyskać bstat pliku tymczasowego: %s\n" +msgid "UUID mismatch on inode %\n" +msgstr "niezgodność UUID-a dla i-węzła %\n" -#: .././fsr/xfs_fsr.c:1073 +#: .././repair/dinode.c:2384 #, c-format -msgid "orig forkoff %d, temp forkoff %d\n" -msgstr "orig forkoff %d, temp forkoff %d\n" +msgid "bad (negative) size % on inode %\n" +msgstr "błędny (ujemny) rozmiar % w i-węźle %\n" -#: .././fsr/xfs_fsr.c:1105 +#: .././repair/dinode.c:2417 #, c-format -msgid "forkoff diff %d too large!\n" -msgstr "różnica forkoff %d zbyt duża!\n" +msgid "imap claims a free inode % is in use, " +msgstr "imap odwołuje się do wolnego bloku %, który jest w użyciu, " -#: .././fsr/xfs_fsr.c:1139 -msgid "set temp attr\n" -msgstr "ustawianie atrybutów pliku tymczasowego\n" +#: .././repair/dinode.c:2419 +msgid "correcting imap and clearing inode\n" +msgstr "poprawiono imap i wyczyszczono i-węzeł\n" -#: .././fsr/xfs_fsr.c:1178 -#, c-format -msgid "%s already fully defragmented.\n" -msgstr "%s jest już całkowicie zdefragmentowany.\n" +#: .././repair/dinode.c:2423 +msgid "would correct imap and clear inode\n" +msgstr "poprawiono by imap i wyczyszczono by i-węzeł\n" -#: .././fsr/xfs_fsr.c:1183 +#: .././repair/dinode.c:2440 #, c-format -msgid "%s extents=%d can_save=%d tmp=%s\n" -msgstr "%s extents=%d can_save=%d tmp=%s\n" +msgid "bad inode format in inode %\n" +msgstr "błędny format i-węzła w i-węźle %\n" -#: .././fsr/xfs_fsr.c:1189 +#: .././repair/dinode.c:2456 #, c-format -msgid "could not open tmp file: %s: %s\n" -msgstr "nie udało się otworzyć pliku tymczasowego: %s: %s\n" +msgid "Bad flags set in inode %\n" +msgstr "Błędne flagi ustawione w i-węźle %\n" -#: .././fsr/xfs_fsr.c:1197 +#: .././repair/dinode.c:2467 #, c-format -msgid "failed to set ATTR fork on tmp: %s:\n" -msgstr "nie udało się ustawić odgałęzienia ATTR na tmp: %s\n" +msgid "inode % has RT flag set but there is no RT device\n" +msgstr "i-węzeł % ma ustawioną flagę RT, ale nie ma urządzenia RT\n" -#: .././fsr/xfs_fsr.c:1205 +#: .././repair/dinode.c:2479 #, c-format -msgid "could not set inode attrs on tmp: %s\n" -msgstr "nie udało się ustawić atrybutów i-węzła na tmp: %s\n" +msgid "inode % not rt bitmap\n" +msgstr "i-węzeł % nie jest bitmapą rt\n" -#: .././fsr/xfs_fsr.c:1213 +#: .././repair/dinode.c:2493 #, c-format -msgid "could not get DirectIO info on tmp: %s\n" -msgstr "nie udało się uzyskać informacji o bezpośrednim we/wy na tmp: %s\n" +msgid "directory flags set on non-directory inode %\n" +msgstr "flagi katalogu ustawione dla nie będącego katalogiem i-węzła %\n" -#: .././fsr/xfs_fsr.c:1229 +#: .././repair/dinode.c:2507 #, c-format -msgid "DEBUG: fsize=%lld blsz_dio=%d d_min=%d d_max=%d pgsz=%d\n" -msgstr "DEBUG: fsize=%lld blsz_dio=%d d_min=%d d_max=%d pgsz=%d\n" +msgid "file flags set on non-file inode %\n" +msgstr "flagi pliku ustawione dla nie będącego plikiem i-węzła %\n" -#: .././fsr/xfs_fsr.c:1236 -#, c-format -msgid "could not allocate buf: %s\n" -msgstr "nie udało się przydzielić bufora: %s\n" +#: .././repair/dinode.c:2516 +msgid ", fixing bad flags.\n" +msgstr ", poprawiono błędne flagi.\n" -#: .././fsr/xfs_fsr.c:1247 -#, c-format -msgid "could not open fragfile: %s : %s\n" -msgstr "nie udało się otworzyć pliku frag: %s: %s\n" +#: .././repair/dinode.c:2520 +msgid ", would fix bad flags.\n" +msgstr ", poprawionoby błędne flagi.\n" -#: .././fsr/xfs_fsr.c:1264 +#: .././repair/dinode.c:2571 #, c-format -msgid "could not trunc tmp %s\n" -msgstr "nie udało się uciąć tmp %s\n" +msgid "bad inode type %#o inode %\n" +msgstr "błędny typ i-węzła %#o w i-węźle %\n" -#: .././fsr/xfs_fsr.c:1279 +#: .././repair/dinode.c:2595 #, c-format -msgid "could not pre-allocate tmp space: %s\n" -msgstr "nie udało się wstępnie przydzielić miejsca tmp: %s\n" +msgid "bad non-zero extent size %u for non-realtime/extsize inode %, " +msgstr "błędny niezerowy rozmiar ekstentu %u dla extsize i-węzła nie-realtime %, " -#: .././fsr/xfs_fsr.c:1290 -msgid "Couldn't rewind on temporary file\n" -msgstr "Nie udało się przewinąć pliku tymczasowego\n" +#: .././repair/dinode.c:2598 +msgid "resetting to zero\n" +msgstr "przestawiono na zero\n" -#: .././fsr/xfs_fsr.c:1299 -#, c-format -msgid "Temporary file has %d extents (%d in original)\n" -msgstr "Plik tymczasowy ma ekstentów: %d (%d w oryginale)\n" +#: .././repair/dinode.c:2602 +msgid "would reset to zero\n" +msgstr "zostałby przestawiony na zero\n" -#: .././fsr/xfs_fsr.c:1302 +#: .././repair/dinode.c:2655 #, c-format -msgid "No improvement will be made (skipping): %s\n" -msgstr "Nie nastąpi poprawa (pominięto): %s\n" +msgid "problem with directory contents in inode %\n" +msgstr "problem z zawartością katalogu w i-węźle %\n" -#: .././fsr/xfs_fsr.c:1346 +#: .././repair/dinode.c:2663 #, c-format -msgid "bad read of %d bytes from %s: %s\n" -msgstr "błędny odczyt %d bajtów z %s: %s\n" +msgid "problem with symbolic link in inode %\n" +msgstr "problem z dowiązaniem symbolicznym w i-węźle %\n" -#: .././fsr/xfs_fsr.c:1350 .././fsr/xfs_fsr.c:1384 +#: .././repair/dinode.c:2758 #, c-format -msgid "bad write of %d bytes to %s: %s\n" -msgstr "błędny zapis %d bajtów do %s: %s\n" +msgid "processing inode %d/%d\n" +msgstr "analiza i-węzła %d/%d\n" -#: .././fsr/xfs_fsr.c:1367 +#: .././repair/dir2.c:49 #, c-format -msgid "bad write2 of %d bytes to %s: %s\n" -msgstr "błędny zapis 2 %d bajtów do %s: %s\n" +msgid "malloc failed (%zu bytes) dir2_add_badlist:ino %\n" +msgstr "malloc nie powiodło się (%zu bajtów) w dir2_add_badlist:ino %\n" -#: .././fsr/xfs_fsr.c:1372 +#: .././repair/dir2.c:111 .././repair/prefetch.c:238 +msgid "couldn't malloc dir2 buffer list\n" +msgstr "nie można przydzielić listy bufora dir2\n" + +#: .././repair/dir2.c:174 .././repair/dir2.c:541 .././repair/dir2.c:1597 #, c-format -msgid "bad copy to %s\n" -msgstr "błędna kopia do %s\n" - -#: .././fsr/xfs_fsr.c:1407 -#, c-format -msgid "failed to fchown tmpfile %s: %s\n" -msgstr "nie udało się wykonać fchown na pliku tymczasowym %s: %s\n" +msgid "can't read block %u for directory inode %\n" +msgstr "nie można odczytać bloku %u dla i-węzła katalogu %\n" -#: .././fsr/xfs_fsr.c:1418 +#: .././repair/dir2.c:186 #, c-format -msgid "%s: file type not supported\n" -msgstr "%s: tym pliku nie obsługiwany\n" +msgid "found non-root LEAFN node in inode % bno = %u\n" +msgstr "znaleziono niegłówny węzeł LEAFN w i-węźle % bno = %u\n" -#: .././fsr/xfs_fsr.c:1422 +#: .././repair/dir2.c:196 #, c-format -msgid "%s: file modified defrag aborted\n" -msgstr "%s: plik zmodyfikowany, defragmentacja przerwana\n" +msgid "bad dir magic number 0x%x in inode % bno = %u\n" +msgstr "błędna liczba magiczna katalogu 0x%x w i-węźle % bno = %u\n" -#: .././fsr/xfs_fsr.c:1427 +#: .././repair/dir2.c:218 #, c-format -msgid "%s: file busy\n" -msgstr "%s: plik zajęty\n" +msgid "bad header depth for directory inode %\n" +msgstr "błędna głębokość nagłówka dla i-węzła katalogu %\n" -#: .././fsr/xfs_fsr.c:1429 +#: .././repair/dir2.c:278 #, c-format -msgid "XFS_IOC_SWAPEXT failed: %s: %s\n" -msgstr "XFS_IOC_SWAPEXT nie powiodło się: %s: %s\n" +msgid "release_dir2_cursor_int got unexpected non-null bp, dabno = %u\n" +msgstr "release_dir2_cursor_int otrzymał nieoczekiwany niezerowy bp, dabno = %u\n" -#: .././fsr/xfs_fsr.c:1438 +#: .././repair/dir2.c:345 #, c-format -msgid "extents before:%d after:%d %s %s\n" -msgstr "ekstentów przed: %d po: %d %s %s\n" +msgid "directory block used/count inconsistency - %d / %hu\n" +msgstr "niespójność wartości used/count bloku katalogu - %d / %hu\n" -#: .././fsr/xfs_fsr.c:1464 +#: .././repair/dir2.c:367 #, c-format -msgid "tmp file name too long: %s\n" -msgstr "nazwa pliku tymczasowego zbyt długa: %s\n" +msgid "bad directory block in inode %\n" +msgstr "błędny blok katalogu w i-węźle %\n" -#: .././fsr/xfs_fsr.c:1513 +#: .././repair/dir2.c:387 #, c-format -msgid "realloc failed: %s\n" -msgstr "realloc nie powiodło się: %s\n" +msgid "" +"correcting bad hashval in non-leaf dir block\n" +"\tin (level %d) in inode %.\n" +msgstr "" +"poprawiono błędne hashval w bloku katalogu nie będącego liściem\n" +"\tw i-węźle (poziomu %d) %.\n" -#: .././fsr/xfs_fsr.c:1526 +#: .././repair/dir2.c:395 #, c-format -msgid "malloc failed: %s\n" -msgstr "malloc nie powiodło się: %s\n" +msgid "" +"would correct bad hashval in non-leaf dir block\n" +"\tin (level %d) in inode %.\n" +msgstr "" +"błędne hashval w bloku katalogu nie będącego liściem zostałoby poprawione\n" +"\tw i-węźle (poziomu %d) %.\n" -#: .././fsr/xfs_fsr.c:1556 +#: .././repair/dir2.c:557 #, c-format -msgid "failed reading extents: inode %llu" -msgstr "nie udało się odczytać ekstentów: i-węzeł %llu" - -#: .././fsr/xfs_fsr.c:1606 -msgid "failed reading extents" -msgstr "nie udało się odczytać ekstentów" +msgid "bad magic number %x in block %u for directory inode %\n" +msgstr "błędna liczba magiczna %x w bloku %u dla i-węzła katalogu %\n" -#: .././fsr/xfs_fsr.c:1694 .././fsr/xfs_fsr.c:1708 +#: .././repair/dir2.c:564 #, c-format -msgid "tmpdir already exists: %s\n" -msgstr "katalog tymczasowy już istnieje: %s\n" +msgid "bad back pointer in block %u for directory inode %\n" +msgstr "błędny wskaźnik wstecz w bloku %u dla i-węzła katalogu %\n" -#: .././fsr/xfs_fsr.c:1697 +#: .././repair/dir2.c:570 #, c-format -msgid "could not create tmpdir: %s: %s\n" -msgstr "nie udało się utworzyć katalogu tymczasowego: %s: %s\n" +msgid "entry count %d too large in block %u for directory inode %\n" +msgstr "liczba wpisów %d zbyt duża w bloku %u dla i-węzła katalogu %\n" -#: .././fsr/xfs_fsr.c:1710 +#: .././repair/dir2.c:577 #, c-format -msgid "cannot create tmpdir: %s: %s\n" -msgstr "nie można utworzyć katalogu tymczasowego: %s: %s\n" +msgid "bad level %d in block %u for directory inode %\n" +msgstr "błędny poziom %d w bloku %u dla i-węzła katalogu %\n" -#: .././fsr/xfs_fsr.c:1748 .././fsr/xfs_fsr.c:1756 +#: .././repair/dir2.c:624 #, c-format -msgid "could not remove tmpdir: %s: %s\n" -msgstr "nie udało się usunąć katalogu tymczasowego: %s: %s\n" +msgid "" +"correcting bad hashval in interior dir block\n" +"\tin (level %d) in inode %.\n" +msgstr "" +"poprawiono błędne hashval w wewnętrznym bloku katalogu\n" +"\tw i-węźle (poziomu %d) %.\n" -#: .././estimate/xfs_estimate.c:76 +#: .././repair/dir2.c:632 #, c-format msgid "" -"Usage: %s [opts] directory [directory ...]\n" -"\t-b blocksize (fundamental filesystem blocksize)\n" -"\t-i logsize (internal log size)\n" -"\t-e logsize (external log size)\n" -"\t-v prints more verbose messages\n" -"\t-h prints this usage message\n" -"\n" -"Note:\tblocksize may have 'k' appended to indicate x1024\n" -"\tlogsize may also have 'm' appended to indicate (1024 x 1024)\n" +"would correct bad hashval in interior dir block\n" +"\tin (level %d) in inode %.\n" msgstr "" -"Składnia: %s [opcje] katalog [katalog ...]\n" -"\t-b rozmiar_bloku (rozmiar bloku zasadniczego systemu plików)\n" -"\t-i rozmiar_logu (rozmiar logu wewnętrznego)\n" -"\t-e rozmiar_logu (rozmiar logu zewnętrznego)\n" -"\t-v wypisywanie bardziej szczegółowych komunikatów\n" -"\t-h wypisanie tej informacji o sposobie użycia\n" -"\n" +"błędne hashval w wewnętrznym bloku katalogu zostałoby poprawione\n" +"\tw i-węźle (poziomu %d) %.\n" -#: .././estimate/xfs_estimate.c:106 +#: .././repair/dir2.c:667 +msgid "couldn't malloc dir2 shortform copy\n" +msgstr "nie udało się przydzielić krótkiej kopii dir2\n" + +#: .././repair/dir2.c:803 +msgid "current" +msgstr "bieżącego i-węzła" + +#: .././repair/dir2.c:806 .././repair/dir2.c:1328 +msgid "invalid" +msgstr "nieprawidłowego i-węzła" + +#: .././repair/dir2.c:809 .././repair/dir2.c:1330 +msgid "realtime bitmap" +msgstr "i-węzła bitmapy realtime" + +#: .././repair/dir2.c:812 .././repair/dir2.c:1332 +msgid "realtime summary" +msgstr "i-węzła opisu realtime" + +#: .././repair/dir2.c:815 .././repair/dir2.c:1334 +msgid "user quota" +msgstr "i-węzła limitów użytkownika" + +#: .././repair/dir2.c:818 .././repair/dir2.c:1336 +msgid "group quota" +msgstr "i-węzła limitów grupy" + +#: .././repair/dir2.c:821 .././repair/dir2.c:1338 +msgid "project quota" +msgstr "i-węzła limitów projektu" + +#: .././repair/dir2.c:839 .././repair/dir2.c:1368 +msgid "free" +msgstr "free" + +#: .././repair/dir2.c:856 .././repair/dir2.c:1348 +msgid "non-existent" +msgstr "nie istniejącego i-węzła" + +#: .././repair/dir2.c:861 #, c-format -msgid "blocksize %llu too small\n" -msgstr "rozmiar bloku %llu jest zbyt mały\n" +msgid "entry \"%*.*s\" in shortform directory % references %s inode %\n" +msgstr "wpis \"%*.*s\" w krótkim katalogu % odwołuje się do %s %\n" -#: .././estimate/xfs_estimate.c:111 +#: .././repair/dir2.c:881 #, c-format -msgid "blocksize %llu too large\n" -msgstr "rozmiar bloku %llu jest zbyt duży\n" +msgid "zero length entry in shortform dir %, resetting to %d\n" +msgstr "wpis zerowej długości w krótkim katalogu %, przestawiono na %d\n" -#: .././estimate/xfs_estimate.c:118 +#: .././repair/dir2.c:886 #, c-format -msgid "already have external log noted, can't have both\n" -msgstr "już jest przypisany zewnętrzny log, nie mogą istnieć oba\n" +msgid "zero length entry in shortform dir %, would set to %d\n" +msgstr "wpis zerowej długości w krótkim katalogu %, zostałby przestawiony na %d\n" -#: .././estimate/xfs_estimate.c:127 +#: .././repair/dir2.c:891 #, c-format -msgid "already have internal log noted, can't have both\n" -msgstr "już jest przypisany wewnętrzny log, nie mogą istnieć oba\n" +msgid "zero length entry in shortform dir %" +msgstr "wpis zerowej długości w krótkim katalogu %" -#: .././estimate/xfs_estimate.c:157 +#: .././repair/dir2.c:894 #, c-format -msgid "directory bsize blocks megabytes logsize\n" -msgstr "katalog rozmb bloków megabajtów rozm.logu\n" +msgid ", junking %d entries\n" +msgstr ", wyrzucono %d wpisów\n" -#: .././estimate/xfs_estimate.c:171 +#: .././repair/dir2.c:897 #, c-format -msgid "dirsize=%llu\n" -msgstr "dirsize=%llu\n" +msgid ", would junk %d entries\n" +msgstr ", %d wpisów zostałoby wyrzucone\n" -#: .././estimate/xfs_estimate.c:172 +#: .././repair/dir2.c:915 #, c-format -msgid "fullblocks=%llu\n" -msgstr "fullblocks=%llu\n" +msgid "size of last entry overflows space left in in shortform dir %, " +msgstr "rozmiar ostatniego wpisu przekracza miejsce pozostałe w krótkim katalogu %, " -#: .././estimate/xfs_estimate.c:173 +#: .././repair/dir2.c:918 #, c-format -msgid "isize=%llu\n" -msgstr "isize=%llu\n" +msgid "resetting to %d\n" +msgstr "przestawiono na %d\n" -#: .././estimate/xfs_estimate.c:175 +#: .././repair/dir2.c:923 #, c-format -msgid "%llu regular files\n" -msgstr "%llu plików zwykłych\n" +msgid "would reset to %d\n" +msgstr "zostałby przestawiony na %d\n" -#: .././estimate/xfs_estimate.c:176 +#: .././repair/dir2.c:928 #, c-format -msgid "%llu symbolic links\n" -msgstr "%llu dowiązań symbolicznych\n" +msgid "size of entry #%d overflows space left in in shortform dir %\n" +msgstr "rozmiar wpisu #%d przekracza miejsce pozostałe w krótkim katalogu %\n" -#: .././estimate/xfs_estimate.c:177 +#: .././repair/dir2.c:933 #, c-format -msgid "%llu directories\n" -msgstr "%llu katalogów\n" +msgid "junking entry #%d\n" +msgstr "wyrzucono wpis #%d\n" -#: .././estimate/xfs_estimate.c:178 +#: .././repair/dir2.c:937 #, c-format -msgid "%llu special files\n" -msgstr "%llu plików specjalnych\n" +msgid "junking %d entries\n" +msgstr "wyrzucono %d wpisów\n" -#: .././estimate/xfs_estimate.c:191 +#: .././repair/dir2.c:942 #, c-format -msgid "%s will take about %.1f megabytes\n" -msgstr "%s zajmie około %.1f megabajtów\n" +msgid "would junk entry #%d\n" +msgstr "wpis #%d zostałby wyrzucony\n" -#: .././estimate/xfs_estimate.c:198 +#: .././repair/dir2.c:946 #, c-format -msgid "%-39s %5llu %8llu %10.1fMB %10llu\n" -msgstr "%-39s %5llu %8llu %10.1fMB %10llu\n" +msgid "would junk %d entries\n" +msgstr "%d wpisów zostałoby wyrzuconych\n" -#: .././estimate/xfs_estimate.c:204 +#: .././repair/dir2.c:965 #, c-format -msgid "\twith the external log using %llu blocks " -msgstr "\tz zewnętrznym logiem zajmującym %llu bloków " +msgid "entry contains illegal character in shortform dir %\n" +msgstr "wpis zawiera niedozwolony znak w krótkim katalogu %\n" -#: .././estimate/xfs_estimate.c:206 +#: .././repair/dir2.c:972 #, c-format -msgid "or about %.1f megabytes\n" -msgstr "lub około %.1f megabajtów\n" +msgid "entry contains offset out of order in shortform dir %\n" +msgstr "wpis zawiera uszkodzony offset w krótkim katalogu %\n" -#: .././db/convert.c:171 +#: .././repair/dir2.c:1029 #, c-format -msgid "bad argument count %d to convert, expected 3,5,7,9 arguments\n" -msgstr "błędna liczba argumentów %d do konwersji, oczekiwano 3,5,7,9 argumentów\n" +msgid "junking entry \"%s\" in directory inode %\n" +msgstr "wyrzucono wpis \"%s\" w i-węźle katalogu %\n" -#: .././db/convert.c:176 .././db/convert.c:183 +#: .././repair/dir2.c:1033 #, c-format -msgid "unknown conversion type %s\n" -msgstr "nieznany rodzaj konwersji %s\n" +msgid "would have junked entry \"%s\" in directory inode %\n" +msgstr "wpis \"%s\" w i-węźle katalogu % zostałby wyrzucony\n" -#: .././db/convert.c:187 -msgid "result type same as argument\n" -msgstr "typ wyniku taki sam jak argument\n" +#: .././repair/dir2.c:1058 +#, c-format +msgid "would have corrected entry count in directory % from %d to %d\n" +msgstr "liczba wpisów w katalogu % zostałaby poprawiona z %d na %d\n" -#: .././db/convert.c:191 +#: .././repair/dir2.c:1062 #, c-format -msgid "conflicting conversion type %s\n" -msgstr "konflikt typu konwersji %s\n" +msgid "corrected entry count in directory %, was %d, now %d\n" +msgstr "poprawiono liczbę wpisów w katalogu % - było %d, jest %d\n" -#: .././db/convert.c:270 +#: .././repair/dir2.c:1073 #, c-format -msgid "%s is not a number\n" -msgstr "%s nie jest liczbą\n" +msgid "would have corrected i8 count in directory % from %d to %d\n" +msgstr "liczba i8 zostałaby poprawiona w katalogu % z %d na %d\n" -#: .././db/check.c:372 -msgid "free block usage information" -msgstr "informacje o wykorzystaniu wolnych bloków" +#: .././repair/dir2.c:1077 +#, c-format +msgid "corrected i8 count in directory %, was %d, now %d\n" +msgstr "poprawiono liczbę i8 w katalogu % - było %d, jest %d\n" -#: .././db/check.c:375 -msgid "[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..." -msgstr "[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..." +#: .././repair/dir2.c:1091 +#, c-format +msgid "would have corrected directory % size from % to %\n" +msgstr "rozmiar katalogu % zostałby poprawiony z % na %\n" -#: .././db/check.c:376 -msgid "get block usage and check consistency" -msgstr "uzyskanie informacji o wykorzystaniu bloków i sprawdzenie spójności" +#: .././repair/dir2.c:1096 +#, c-format +msgid "corrected directory % size, was %, now %\n" +msgstr "poprawiono rozmiar katalogu % - było %, jest %\n" -#: .././db/check.c:379 -msgid "[-n count] [-x minlen] [-y maxlen] [-s seed] [-0123] [-t type] ..." -msgstr "[-n liczba] [-x minlen] [-y maxlen] [-s seed] [-0123] [-t typ] ..." +#: .././repair/dir2.c:1108 +#, c-format +msgid "directory % offsets too high\n" +msgstr "offsety zbyt duże w katalogu %\n" -#: .././db/check.c:380 -msgid "trash randomly selected block(s)" -msgstr "zaśmiecenie losowo wybranych bloków" +#: .././repair/dir2.c:1114 +#, c-format +msgid "would have corrected entry offsets in directory %\n" +msgstr "offsety wpisów w katalogu % zostałyby poprawione\n" -#: .././db/check.c:383 -msgid "[-n] [-c blockcount]" -msgstr "[-n] [-c liczba-bloków]" +#: .././repair/dir2.c:1118 +#, c-format +msgid "corrected entry offsets in directory %\n" +msgstr "poprawiono offsety wpisów w katalogu %\n" -#: .././db/check.c:384 -msgid "print usage for current block(s)" -msgstr "wypisanie wykorzystania bieżących bloków" +#: .././repair/dir2.c:1137 +#, c-format +msgid "bogus .. inode number (%) in directory inode %, " +msgstr "błędny numer i-węzła .. (%) w i-węźle katalogu %, " -#: .././db/check.c:387 -msgid "[-s] [-i ino] ..." -msgstr "[-s] [-i ino] ..." +#: .././repair/dir2.c:1141 .././repair/dir2.c:1176 +msgid "clearing inode number\n" +msgstr "wyczyszczono numer i-węzła\n" -#: .././db/check.c:388 -msgid "print inode-name pairs" -msgstr "wypisanie par i-węzeł - nazwa" - -#: .././db/check.c:408 -#, c-format -msgid "-i %lld bad inode number\n" -msgstr "-i %lld - błędny numer i-węzła\n" +#: .././repair/dir2.c:1147 .././repair/dir2.c:1182 +msgid "would clear inode number\n" +msgstr "numer i-węzła zostałby wyczyszczony\n" -#: .././db/check.c:420 +#: .././repair/dir2.c:1155 #, c-format -msgid "inode %lld add link, now %u\n" -msgstr "i-węzeł %lld - dodano dowiązanie, teraz %u\n" +msgid "corrected root directory % .. entry, was %, now %\n" +msgstr "poprawiono wpis .. głównego katalogu % - było %, jest %\n" -#: .././db/check.c:447 +#: .././repair/dir2.c:1163 #, c-format -msgid "inode %lld parent %lld\n" -msgstr "i-węzeł %lld - rodzic %lld\n" - -#: .././db/check.c:760 -msgid "block usage information not allocated\n" -msgstr "informacja o wykorzystaniu bloków nie przydzielona\n" - -#: .././db/check.c:798 -msgid "already have block usage information\n" -msgstr "już istnieje informacja o wykorzystaniu bloków\n" - -#: .././db/check.c:814 .././db/check.c:922 -msgid "WARNING: this may be a newer XFS filesystem.\n" -msgstr "UWAGA: to może być nowszy system plików XFS.\n" +msgid "would have corrected root directory % .. entry from % to %\n" +msgstr "wpis .. głównego katalogu % zostałby poprawiony z % na %\n" -#: .././db/check.c:850 +#: .././repair/dir2.c:1173 #, c-format -msgid "sb_icount %lld, counted %lld\n" -msgstr "sb_icount %lld, naliczono %lld\n" +msgid "bad .. entry in directory inode %, points to self, " +msgstr "błędny wpis .. w i-węźle katalogu %, wskazuje na siebie, " -#: .././db/check.c:856 +#: .././repair/dir2.c:1286 #, c-format -msgid "sb_ifree %lld, counted %lld\n" -msgstr "sb_ifree %lld, naliczono %lld\n" +msgid "corrupt block %u in directory inode %\n" +msgstr "uszkodzony blok %u w i-węźle katalogu %\n" -#: .././db/check.c:862 -#, c-format -msgid "sb_fdblocks %lld, counted %lld\n" -msgstr "sb_fdblocks %lld, naliczono %lld\n" +#: .././repair/dir2.c:1289 +msgid "\twill junk block\n" +msgstr "\tblok zostanie wyrzucony\n" -#: .././db/check.c:868 -#, c-format -msgid "sb_fdblocks %lld, aggregate AGF count %lld\n" -msgstr "sb_fdblocks %lld, łączny licznik AGF %lld\n" +#: .././repair/dir2.c:1291 +msgid "\twould junk block\n" +msgstr "\tblok zostałby wyrzucony\n" -#: .././db/check.c:874 +#: .././repair/dir2.c:1377 #, c-format -msgid "sb_frextents %lld, counted %lld\n" -msgstr "sb_frextents %lld, naliczono %lld\n" +msgid "entry \"%*.*s\" at block %d offset % in directory inode % references %s inode %\n" +msgstr "wpis \"%*.*s\" w bloku %d offsecie % w i-węźle katalogu % odwołuje się do %s %\n" -#: .././db/check.c:881 +#: .././repair/dir2.c:1388 #, c-format -msgid "sb_features2 (0x%x) not same as sb_bad_features2 (0x%x)\n" -msgstr "sb_features2 (0x%x) różni się od sb_bad_features2 (0x%x)\n" +msgid "entry at block %u offset % in directory inode %has 0 namelength\n" +msgstr "wpis w bloku %u offsecie % w i-węźle katalogu % ma zerową długość nazwy\n" -#: .././db/check.c:890 +#: .././repair/dir2.c:1401 #, c-format -msgid "sb versionnum missing attr bit %x\n" -msgstr "sb versionnum - brak bitu atrybutu %x\n" +msgid "\tclearing inode number in entry at offset %...\n" +msgstr "\twyczyszczono numer i-węzła we wpisie o offsecie %...\n" -#: .././db/check.c:897 +#: .././repair/dir2.c:1407 #, c-format -msgid "sb versionnum missing nlink bit %x\n" -msgstr "sb versionnum - brak bitu nlink %x\n" +msgid "\twould clear inode number in entry at offset %...\n" +msgstr "\tnumer i-węzła we wpisie o offsecie % zostałby wyczyszczony...\n" -#: .././db/check.c:904 +#: .././repair/dir2.c:1420 #, c-format -msgid "sb versionnum missing quota bit %x\n" -msgstr "sb versionnum - brak bitu quota %x\n" +msgid "entry at block %u offset % in directory inode % has illegal name \"%*.*s\": " +msgstr "wpis w bloku %u offsecie % w i-węźle katalogu % ma niedozwoloną nazwę \"%*.*s\": " -#: .././db/check.c:911 +#: .././repair/dir2.c:1451 #, c-format -msgid "sb versionnum extra align bit %x\n" -msgstr "sb versionnum - nadmiarowy bit align %x\n" - -#: .././db/check.c:951 -msgid "zeroed" -msgstr "wyzerowano" - -#: .././db/check.c:951 -msgid "set" -msgstr "ustawiono" - -#: .././db/check.c:951 -msgid "flipped" -msgstr "przełączono" - -#: .././db/check.c:951 -msgid "randomized" -msgstr "ulosowiono" +msgid "bad .. entry in directory inode %, points to self: " +msgstr "błędny wpis .. w i-węźle katalogu %, wskazuje na siebie: " -#: .././db/check.c:961 +#: .././repair/dir2.c:1462 #, c-format -msgid "can't read block %u/%u for trashing\n" -msgstr "nie można odczytać bloku %u/%u w celu zaśmiecenia\n" +msgid "bad .. entry in root directory inode %, was %: " +msgstr "błędny wpis w i-węźle głównego katalogu %, było %: " -#: .././db/check.c:991 -#, c-format -msgid "blocktrash: %u/%u %s block %d bit%s starting %d:%d %s\n" -msgstr "blocktrash: %u/%u %s blok %d bit%s początek %d:%d %s\n" +#: .././repair/dir2.c:1465 .././repair/dir2.c:1497 .././repair/phase2.c:184 +#: .././repair/phase2.c:193 .././repair/phase2.c:202 +msgid "correcting\n" +msgstr "poprawiono\n" -#: .././db/check.c:1023 .././db/check.c:1180 -msgid "must run blockget first\n" -msgstr "najpierw trzeba wykonać blockget\n" +#: .././repair/dir2.c:1469 .././repair/dir2.c:1501 .././repair/phase2.c:186 +#: .././repair/phase2.c:195 .././repair/phase2.c:204 +msgid "would correct\n" +msgstr "zostałby poprawiony\n" -#: .././db/check.c:1067 +#: .././repair/dir2.c:1481 #, c-format -msgid "bad blocktrash count %s\n" -msgstr "błędna liczba bloków do zaśmiecenia %s\n" +msgid "multiple .. entries in directory inode %: " +msgstr "wiele wpisów .. w i-węźle katalogu %: " -#: .././db/check.c:1081 +#: .././repair/dir2.c:1494 #, c-format -msgid "bad blocktrash type %s\n" -msgstr "błędny typ zaśmiecania %s\n" +msgid "bad . entry in directory inode %, was %: " +msgstr "błędny wpis . w i-węźle katalogu %, było %: " -#: .././db/check.c:1090 +#: .././repair/dir2.c:1506 #, c-format -msgid "bad blocktrash min %s\n" -msgstr "błędny początek zaśmiecania %s\n" +msgid "multiple . entries in directory inode %: " +msgstr "wiele wpisów . w i-węźle katalogu %: " -#: .././db/check.c:1098 +#: .././repair/dir2.c:1516 #, c-format -msgid "bad blocktrash max %s\n" -msgstr "błędny koniec zaśmiecania %s\n" - -#: .././db/check.c:1103 -msgid "bad option for blocktrash command\n" -msgstr "błędna opcja polecenia blocktrash\n" - -#: .././db/check.c:1108 -msgid "bad min/max for blocktrash command\n" -msgstr "błędny początek/koniec polecenia blocktrash\n" +msgid "entry \"%*.*s\" in directory inode % points to self: " +msgstr "wpis \"%*.*s\" w i-węźle katalogu % wskazuje na siebie: " -#: .././db/check.c:1134 -msgid "blocktrash: no matching blocks\n" -msgstr "blocktrash: brak pasujących bloków\n" +#: .././repair/dir2.c:1527 +msgid "clearing entry\n" +msgstr "wyczyszczono wpis\n" -#: .././db/check.c:1138 -#, c-format -msgid "blocktrash: seed %u\n" -msgstr "blocktash: zarodek %u\n" +#: .././repair/dir2.c:1529 +msgid "would clear entry\n" +msgstr "wpis zostałby wyczyszczony\n" -#: .././db/check.c:1196 +#: .././repair/dir2.c:1542 #, c-format -msgid "bad blockuse count %s\n" -msgstr "błędna liczba bloków dla blockuse: %s\n" +msgid "bad bestfree table in block %u in directory inode %: " +msgstr "błędna tablica bestfree w bloku %u w i-węźle katalogu %: " -#: .././db/check.c:1202 .././db/check.c:1887 -msgid "must run blockget -n first\n" -msgstr "najpierw trzeba wykonać blockget -n\n" +#: .././repair/dir2.c:1545 +msgid "repairing table\n" +msgstr "naprawiono tablicę\n" -#: .././db/check.c:1208 -msgid "bad option for blockuse command\n" -msgstr "błędna opcja dla polecenia blockuse\n" +#: .././repair/dir2.c:1549 +msgid "would repair table\n" +msgstr "tablica zostałaby naprawiona\n" -#: .././db/check.c:1215 +#: .././repair/dir2.c:1588 #, c-format -msgid "block %llu (%u/%u) type %s" -msgstr "blok %llu (%u/%u) typu %s" +msgid "block %u for directory inode % is missing\n" +msgstr "brak bloku %u dla i-węzła katalogu %\n" -#: .././db/check.c:1219 +#: .././repair/dir2.c:1608 #, c-format -msgid " inode %lld" -msgstr " i-węzeł %lld" +msgid "bad directory block magic # %#x in block %u for directory inode %\n" +msgstr "błędna liczba magiczna bloku katalogu %#x w bloku %u dla i-węzła katalogu %\n" -#: .././db/check.c:1257 +#: .././repair/dir2.c:1660 #, c-format -msgid "block %u/%u expected type %s got %s\n" -msgstr "blok %u/%u: oczekiwano typu %s, otrzymano %s\n" +msgid "bad entry count in block %u of directory inode %\n" +msgstr "błędna liczba wpisów w bloku %u i-węzła katalogu %\n" -#: .././db/check.c:1289 +#: .././repair/dir2.c:1668 #, c-format -msgid "blocks %u/%u..%u claimed by inode %lld\n" -msgstr "blok %u/%u..%u przypisany do i-węzła %lld\n" +msgid "bad hash ordering in block %u of directory inode %\n" +msgstr "błędna kolejność hasza w bloku %u i-węzła katalogu %\n" -#: .././db/check.c:1297 +#: .././repair/dir2.c:1676 #, c-format -msgid "block %u/%u claimed by inode %lld, previous inum %lld\n" -msgstr "blok %u/%u przypisany do i-węzła %lld, poprzedni inum %lld\n" +msgid "bad stale count in block %u of directory inode %\n" +msgstr "błędna liczba stale %u i-węzła katalogu %\n" -#: .././db/check.c:1326 +#: .././repair/dir2.c:1725 #, c-format -msgid "link count mismatch for inode %lld (name %s), nlink %d, counted %d\n" -msgstr "niezgodność liczby dowiązań dla i-węzła %lld (nazwa %s), nlink %d, naliczono %d\n" +msgid "can't map block %u for directory inode %\n" +msgstr "nie można odwzorować bloku %u dla i-węzła katalogu %\n" -#: .././db/check.c:1334 +#: .././repair/dir2.c:1735 #, c-format -msgid "disconnected inode %lld, nlink %d\n" -msgstr "odłączony i-węzeł %lld, nlink %d\n" +msgid "can't read file block %u for directory inode %\n" +msgstr "nie można odczytać bloku pliku %u dla i-węzła katalogu %\n" -#: .././db/check.c:1338 +#: .././repair/dir2.c:1747 #, c-format -msgid "allocated inode %lld has 0 link count\n" -msgstr "przydzielony i-węzeł %lld ma zerową liczbę dowiązań\n" +msgid "bad directory leaf magic # %#x for directory inode % block %u\n" +msgstr "błędna liczba magiczna liścia katalogu %#x dla i-węzła katalogu % bloku %u\n" -#: .././db/check.c:1348 +#: .././repair/dir2.c:1775 #, c-format -msgid "inode %lld name %s\n" -msgstr "i-węzeł %lld o nazwie %s\n" +msgid "bad sibling back pointer for block %u in directory inode %\n" +msgstr "błędny wskaźnik wstecz dla bloku %u w i-węźle katalogu %\n" -#: .././db/check.c:1382 .././db/check.c:1397 +#: .././repair/dir2.c:1806 #, c-format -msgid "block %u/%u out of range\n" -msgstr "blok %u/%u poza zakresem\n" +msgid "bad hash path in directory %\n" +msgstr "błędna ścieżka hasza w katalogu %\n" -#: .././db/check.c:1385 .././db/check.c:1400 +#: .././repair/dir2.c:1916 #, c-format -msgid "blocks %u/%u..%u out of range\n" -msgstr "bloki %u/%u..%u poza zakresem\n" +msgid "block % for directory inode % is missing\n" +msgstr "brak bloku % dla i-węzła katalogu %\n" -#: .././db/check.c:1423 +#: .././repair/dir2.c:1925 #, c-format -msgid "rtblock %llu expected type %s got %s\n" -msgstr "rtblok %llu - oczekiwano typu %s, otrzymano %s\n" +msgid "can't read block % for directory inode %\n" +msgstr "nie można odczytać bloku % dla i-węzła katalogu %\n" -#: .././db/check.c:1443 +#: .././repair/dir2.c:1933 #, c-format -msgid "rtblocks %llu..%llu claimed by inode %lld\n" -msgstr "rtbloki %llu..%llu przypisane do i-węzła %lld\n" +msgid "bad directory block magic # %#x in block % for directory inode %\n" +msgstr "błędna liczba magiczna bloku katalogu %#x w bloku % dla i-węzła katalogu %\n" -#: .././db/check.c:1452 +#: .././repair/dir2.c:2014 #, c-format -msgid "rtblock %llu claimed by inode %lld, previous inum %lld\n" -msgstr "rtblok %llu przypisany do i-węzłą %lld, poprzedni inum %lld\n" +msgid "bad size/format for directory %\n" +msgstr "błędny rozmiar/format dla katalogu %\n" -#: .././db/check.c:1470 +#: .././repair/dir2.c:2021 #, c-format -msgid "root inode %lld is missing\n" -msgstr "brak głównego i-węzła %lld\n" +msgid "no . entry for directory %\n" +msgstr "brak wpisu . dla katalogu %\n" -#: .././db/check.c:1475 +#: .././repair/dir2.c:2031 #, c-format -msgid "root inode %lld is not a directory\n" -msgstr "główny i-węzeł %lld nie jest katalogiem\n" +msgid "no .. entry for directory %\n" +msgstr "brak wpisu .. dla katalogu %\n" -#: .././db/check.c:1491 +#: .././repair/dir2.c:2033 #, c-format -msgid "rtblock %llu out of range\n" -msgstr "rtblok %llu poza zakresem\n" +msgid "no .. entry for root directory %\n" +msgstr "brak wpisu .. dla katalogu głównego %\n" -#: .././db/check.c:1515 +#: .././repair/incore.c:230 #, c-format -msgid "blocks %u/%u..%u claimed by block %u/%u\n" -msgstr "bloki %u/%u..%u przypisane do bloku %u/%u\n" +msgid "couldn't allocate realtime block map, size = %\n" +msgstr "nie udało się przydzielić mapy bloków realtime, size = %\n" -#: .././db/check.c:1524 -#, c-format -msgid "setting block %u/%u to %s\n" -msgstr "ustawianie bloku %u/%u na %s\n" +#: .././repair/incore.c:295 +msgid "couldn't allocate block map btree roots\n" +msgstr "nie udało się przydzielić korzeni b-drzewa mapy bloków\n" -#: .././db/check.c:1547 -#, c-format -msgid "setting rtblock %llu to %s\n" -msgstr "ustawianie rtbloku %llu na %s\n" +#: .././repair/incore.c:299 +msgid "couldn't allocate block map locks\n" +msgstr "nie udało się przydzielić blokad mapy bloków\n" -#: .././db/check.c:1593 -#, c-format -msgid "block %u/%u type %s not expected\n" -msgstr "blok %u/%u typu %s nie oczekiwany\n" +#: .././repair/incore_ext.c:135 .././repair/incore_ext.c:562 +msgid "couldn't allocate new extent descriptor.\n" +msgstr "nie udało się przydzielić nowego deskryptora ekstentu.\n" -#: .././db/check.c:1614 -#, c-format -msgid "rtblock %llu type %s not expected\n" -msgstr "rtblok %llu typu %s nie oczekiwany\n" +#: .././repair/incore_ext.c:232 +msgid "duplicate bno extent range\n" +msgstr "powtórzony przedział ekstentów bno\n" -#: .././db/check.c:1651 -#, c-format -msgid "dir ino %lld missing leaf entry for %x/%x\n" -msgstr "i-węzeł katalogu %lld - brak wpisu liścia dla %x/%x\n" +#: .././repair/incore_ext.c:369 +msgid ": duplicate bno extent range\n" +msgstr ": powtórzony przedział ekstentów bno\n" -#: .././db/check.c:1770 -#, c-format -msgid "bad superblock magic number %x, giving up\n" -msgstr "błędna liczba magiczna superbloku %x, poddaję się\n" +#: .././repair/incore_ext.c:644 .././repair/incore_ext.c:699 +msgid "duplicate extent range\n" +msgstr "powtórzony przedział ekstentów\n" -#: .././db/check.c:1824 -msgid "bad option for blockget command\n" -msgstr "błędna opcja dla polecenia blockget\n" +#: .././repair/incore_ext.c:752 .././repair/incore_ext.c:756 +msgid "couldn't malloc dup extent tree descriptor table\n" +msgstr "nie udało się przydzielić tablicy deskryptorów drzewa powtórzonych ekstentów\n" -#: .././db/check.c:1904 -#, c-format -msgid "bad option -%c for ncheck command\n" -msgstr "błędna opcja -%c dla polecenia ncheck\n" +#: .././repair/incore_ext.c:761 +msgid "couldn't malloc free by-bno extent tree descriptor table\n" +msgstr "nie udało się przydzielić tablicy deskryptorów drzewa wolnych ekstentów wg bno\n" -#: .././db/check.c:1977 .././db/check.c:2946 -#, c-format -msgid "block 0 for directory inode %lld is missing\n" -msgstr "brak bloku 0 dla i-węzła katalogu %lld\n" +#: .././repair/incore_ext.c:766 +msgid "couldn't malloc free by-bcnt extent tree descriptor table\n" +msgstr "nie udało się przydzielić tablicy deskryptorów drzewa wolnych ekstentów wg bcnt\n" -#: .././db/check.c:1997 .././db/check.c:2957 -#, c-format -msgid "can't read block 0 for directory inode %lld\n" -msgstr "nie można odczytać bloku 0 dla i-węzła katalogu %lld\n" +#: .././repair/incore_ext.c:772 +msgid "couldn't malloc bno extent tree descriptor\n" +msgstr "nie udało się przydzielić deskryptora drzewa ekstentów wg bno\n" -#: .././db/check.c:2043 -#, c-format -msgid "inode %lld extent [%lld,%lld,%lld,%d]\n" -msgstr "ekstent i-węzła %lld [%lld,%lld,%lld,%d]\n" +#: .././repair/incore_ext.c:776 +msgid "couldn't malloc bcnt extent tree descriptor\n" +msgstr "nie udało się przydzielić deskryptora drzewa ekstentów wg bcnt\n" -#: .././db/check.c:2046 -#, c-format -msgid "bmap rec out of order, inode %lld entry %d\n" -msgstr "błędna kolejność bmap rec - i-węzeł %lld, wpis %d\n" +#: .././repair/incore_ext.c:787 +msgid "couldn't malloc dup rt extent tree descriptor\n" +msgstr "nie udało się przydzielić deskryptora drzewa powtórzonych ekstentów rt\n" -#: .././db/check.c:2052 -#, c-format -msgid "inode %lld bad rt block number %lld, offset %lld\n" -msgstr "i-węzeł %lld - błędny numer bloku rt %lld, offset %lld\n" +#: .././repair/incore_ino.c:47 +msgid "could not allocate nlink array\n" +msgstr "Nie udało się przydzielić tablicy nlink\n" -#: .././db/check.c:2062 .././db/check.c:2068 -#, c-format -msgid "inode %lld bad block number %lld [%d,%d], offset %lld\n" -msgstr "i-węzeł %lld - błędny numer bloku %lld [%d,%d], offset %lld\n" +#: .././repair/incore_ino.c:225 +msgid "could not allocate ftypes array\n" +msgstr "nie udało się przydzielić tablicy ftypes\n" -#: .././db/check.c:2086 .././db/check.c:2100 -#, c-format -msgid "inode %lld block %lld at offset %lld\n" -msgstr "i-węzeł %lld: blok %lld pod offsetem %lld\n" +#: .././repair/incore_ino.c:251 +msgid "inode map malloc failed\n" +msgstr "przydzielenie mapy i-węzłów nie powiodło się\n" -#: .././db/check.c:2127 -#, c-format -msgid "level for ino %lld %s fork bmap root too large (%u)\n" -msgstr "i-węzeł %lld: poziom bmap root odgałęzienia %s zbyt duży (%u)\n" +#: .././repair/incore_ino.c:364 +msgid "add_aginode_uncertain - duplicate inode range\n" +msgstr "add_aginode_uncertain - powtórzony przedział i-węzłów\n" -#: .././db/check.c:2139 -#, c-format -msgid "numrecs for ino %lld %s fork bmap root too large (%u)\n" -msgstr "i-węzeł %lld: liczba rekordów bmap root odgałęzienia %s zbyt duża (%u)\n" +#: .././repair/incore_ino.c:459 +msgid "add_inode - duplicate inode range\n" +msgstr "add_inode - powtórzony przedział i-węzłów\n" -#: .././db/check.c:2166 +#: .././repair/incore_ino.c:553 #, c-format -msgid "extent count for ino %lld %s fork too low (%d) for file format\n" -msgstr "i-węzeł %lld: liczba ekstentów dla odgałęzienia %s zbyt mała (%d) dla formatu pliku\n" +msgid "good inode list is --\n" +msgstr "lista dobrych i-węzłów to:\n" -#: .././db/check.c:2216 .././db/check.c:3297 +#: .././repair/incore_ino.c:556 #, c-format -msgid "bad directory data magic # %#x for dir ino %lld block %d\n" -msgstr "błędna liczba magiczna danych katalogu %#x dla i-węzła katalogu %lld, blok %d\n" +msgid "uncertain inode list is --\n" +msgstr "lista niepewnych i-węzłów to:\n" -#: .././db/check.c:2233 +#: .././repair/incore_ino.c:561 #, c-format -msgid "bad block directory tail for dir ino %lld\n" -msgstr "błędny koniec katalogu bloku dla i-węzła katalogu %lld\n" +msgid "agno %d -- no inodes\n" +msgstr "agno %d - brak i-węzłów\n" -#: .././db/check.c:2278 +#: .././repair/incore_ino.c:565 #, c-format -msgid "dir %lld block %d bad free entry at %d\n" -msgstr "katalog %lld, blok %d: błędny wolny wpis pod %d\n" +msgid "agno %d\n" +msgstr "agno %d\n" -#: .././db/check.c:2302 +#: .././repair/incore_ino.c:569 #, c-format -msgid "dir %lld block %d zero length entry at %d\n" -msgstr "katalog %lld, blok %d: wpis zerowej długości pod %d\n" +msgid "\tptr = %lx, start = 0x%x, free = 0x%llx, confirmed = 0x%llx\n" +msgstr "\tptr = %lx, start = 0x%x, wolne = 0x%llx, potwierdzone = 0x%llx\n" -#: .././db/check.c:2311 -#, c-format -msgid "dir %lld block %d bad entry at %d\n" -msgstr "katalog %lld, blok %d: błędny wpis pod %d\n" +#: .././repair/incore_ino.c:620 +msgid "couldn't malloc parent list table\n" +msgstr "nie udało się przydzielić tablicy listy rodziców\n" -#: .././db/check.c:2329 -#, c-format -msgid "dir %lld block %d entry %*.*s %lld\n" -msgstr "katalog %lld, blok %d, wpis %*.*s %lld\n" +#: .././repair/incore_ino.c:631 .././repair/incore_ino.c:677 +msgid "couldn't memalign pentries table\n" +msgstr "nie udało się memalign na tablicy pentries\n" -#: .././db/check.c:2336 -#, c-format -msgid "dir %lld block %d entry %*.*s bad inode number %lld\n" -msgstr "katalog %lld, blokd %d, epis %*.*s: błędny number i-węzła %lld\n" +#: .././repair/incore_ino.c:735 +msgid "could not malloc inode extra data\n" +msgstr "nie udało się przydzielić dodatkowych danych i-węzła\n" -#: .././db/check.c:2346 .././db/check.c:3020 -#, c-format -msgid "multiple .. entries in dir %lld (%lld, %lld)\n" -msgstr "wiele wpisów .. w katalogu %lld (%lld, %lld)\n" +#: .././repair/incore_ino.c:801 +msgid "couldn't malloc inode tree descriptor table\n" +msgstr "nie udało się przydzielić tablicy deskryptorów drzewa i-węzłów\n" -#: .././db/check.c:2363 .././db/check.c:3037 -#, c-format -msgid "dir %lld entry . inode number mismatch (%lld)\n" -msgstr "katalog %lld, wpis .: niezgodność numeru i-węzła (%lld)\n" +#: .././repair/incore_ino.c:805 +msgid "couldn't malloc uncertain ino tree descriptor table\n" +msgstr "nie udało się przydzielić tablicy deskryptorów drzewa i-węzłów niepewnych\n" -#: .././db/check.c:2376 -#, c-format -msgid "dir %lld block %d bad count %u\n" -msgstr "katalog %lld, blok %d: błędny licznik %u\n" +#: .././repair/incore_ino.c:810 +msgid "couldn't malloc inode tree descriptor\n" +msgstr "nie udało się przydzielić deskryptora drzewa i-węzłów\n" -#: .././db/check.c:2387 .././db/check.c:3311 -#, c-format -msgid "dir %lld block %d extra leaf entry %x %x\n" -msgstr "katalog %lld, blok %d: nadmiarowy wpis liścia %x %x\n" +#: .././repair/incore_ino.c:814 +msgid "couldn't malloc uncertain ino tree descriptor\n" +msgstr "nie udało się przydzielić deskryptora drzewa i-węzłów niepewnych\n" -#: .././db/check.c:2399 -#, c-format -msgid "dir %lld block %d bad bestfree data\n" -msgstr "katalog %lld, blok %d: błędne dane bestfree\n" +#: .././repair/incore_ino.c:822 +msgid "couldn't malloc uncertain inode cache area\n" +msgstr "nie udało się przydzielić obszaru pamięci podręcznej i-węzłów niepewnych\n" -#: .././db/check.c:2407 +#: .././repair/init.c:46 #, c-format -msgid "dir %lld block %d bad block tail count %d (stale %d)\n" -msgstr "katalog %lld, blok %d: błędny licznik końca bloku %d (stale %d)\n" +msgid "getrlimit(RLIMIT_FSIZE) failed!\n" +msgstr "getrlimit(RLIMIT_FSIZE) nie powiodło się!\n" -#: .././db/check.c:2416 +#: .././repair/init.c:54 #, c-format -msgid "dir %lld block %d bad stale tail count %d\n" -msgstr "katalog %lld, blok %d: błędny licznik końca stale %d\n" +msgid "setrlimit failed - current: %lld, max: %lld\n" +msgstr "setrlimit nie powiodło się - bieżący: %lld, max: %lld\n" -#: .././db/check.c:2422 +#: .././repair/init.c:107 #, c-format -msgid "dir %lld block %d consecutive free entries\n" -msgstr "katalog %lld, blok %d: kolejne wolne wpisy\n" +msgid "Unmount or use the dangerous (-d) option to repair a read-only mounted filesystem\n" +msgstr "Aby naprawić system plików zamontowany do odczytu, trzeba go odmontować lub użyć opcji niebezpiecznej (-d).\n" -#: .././db/check.c:2428 -#, c-format -msgid "dir %lld block %d entry/unused tag mismatch\n" -msgstr "katalog %lld, blok %d: niezgodność znacznika wpis/nieużywany\n" +#: .././repair/init.c:109 +msgid "couldn't initialize XFS library\n" +msgstr "nie udało się zainicjować biblioteki XFS\n" -#: .././db/check.c:2481 -#, c-format -msgid "no . entry for directory %lld\n" -msgstr "brak wpisu . dla katalogu %lld\n" +#: .././repair/phase1.c:28 +msgid "Sorry, could not find valid secondary superblock\n" +msgstr "Niestety nie znaleziono poprawnego zapasowego superbloku\n" -#: .././db/check.c:2486 -#, c-format -msgid "no .. entry for directory %lld\n" -msgstr "brak wpisu .. dla katalogu %lld\n" +#: .././repair/phase1.c:29 +msgid "Exiting now.\n" +msgstr "Zakończono.\n" -#: .././db/check.c:2490 +#: .././repair/phase1.c:40 #, c-format -msgid ". and .. same for non-root directory %lld\n" -msgstr ". i .. są takie same dla katalogu %lld (nie będącego głównym)\n" +msgid "could not allocate ag header buffer (%d bytes)\n" +msgstr "nie udało się przydzielić bufora nagłówka ag (%d bajtów)\n" -#: .././db/check.c:2495 -#, c-format -msgid "root directory %lld has .. %lld\n" -msgstr "główny katalog %lld ma .. %lld\n" +#: .././repair/phase1.c:58 +msgid "Phase 1 - find and verify superblock...\n" +msgstr "Faza 1 - szukanie i sprawdzanie superbloku...\n" -#: .././db/check.c:2525 .././db/check.c:2560 -#, c-format -msgid "bad size (%lld) or format (%d) for directory inode %lld\n" -msgstr "błędny rozmiar (%lld) lub format (%d) dla i-węzła katalogu %lld\n" +#: .././repair/phase1.c:75 +msgid "error reading primary superblock\n" +msgstr "błąd podczas odczytu głównego superbloku\n" -#: .././db/check.c:2588 +#: .././repair/phase1.c:81 #, c-format -msgid "bad number of extents %d for inode %lld\n" -msgstr "błędna liczba ekstentów %d dla i-węzła %lld\n" +msgid "bad primary superblock - %s !!!\n" +msgstr "błędny główny superblok - %s!!!\n" -#: .././db/check.c:2660 +#: .././repair/phase1.c:88 #, c-format -msgid "bad magic number %#x for inode %lld\n" -msgstr "błędna liczba magiczna %#x dla i-węzła %lld\n" +msgid "couldn't verify primary superblock - %s !!!\n" +msgstr "nie udało się sprawdzić głównego superbloku - %s!!!\n" -#: .././db/check.c:2667 -#, c-format -msgid "bad version number %#x for inode %lld\n" -msgstr "błędny numer wersji %#x dla i-węzła %lld\n" +#: .././repair/phase1.c:106 +msgid "superblock has a features2 mismatch, correcting\n" +msgstr "superblok ma niepasujące features2, poprawianie\n" -#: .././db/check.c:2675 +#: .././repair/phase1.c:123 #, c-format -msgid "bad nblocks %lld for free inode %lld\n" -msgstr "błędna liczba bloków %lld dla wolnego i-węzła %lld\n" +msgid "Enabling lazy-counters\n" +msgstr "Włączanie leniwych liczników\n" -#: .././db/check.c:2686 +#: .././repair/phase1.c:128 #, c-format -msgid "bad nlink %d for free inode %lld\n" -msgstr "błądna liczba dowiązań %d dla wolnego i-węzła %lld\n" +msgid "Disabling lazy-counters\n" +msgstr "Wyłączanie leniwych liczników\n" -#: .././db/check.c:2692 +#: .././repair/phase1.c:131 #, c-format -msgid "bad mode %#o for free inode %lld\n" -msgstr "błędne uprawnienia %#o dla wolnego i-węzła %lld\n" +msgid "Lazy-counters are already %s\n" +msgstr "Leniwe liczniki już są %s\n" -#: .././db/check.c:2701 -#, c-format -msgid "bad next unlinked %#x for inode %lld\n" -msgstr "błędny następny niedowiązany %#x dla i-węzła %lld\n" +#: .././repair/phase1.c:132 +msgid "enabled" +msgstr "włączone" -#: .././db/check.c:2711 -#, c-format -msgid "bad format %d for inode %lld type %#o\n" -msgstr "błędny format %d dla i-węzła %lld typu %#o\n" +#: .././repair/phase1.c:132 +msgid "disabled" +msgstr "wyłączone" -#: .././db/check.c:2718 -#, c-format -msgid "bad fork offset %d for inode %lld\n" -msgstr "błędny offset odgałęzienia %d dla i-węzła %lld\n" +#: .././repair/phase1.c:139 +msgid "writing modified primary superblock\n" +msgstr "zapisano zmodyfikowany główny superblok\n" -#: .././db/check.c:2725 -#, c-format -msgid "bad attribute format %d for inode %lld\n" -msgstr "błędny format atrybutu %d dla i-węzła %lld\n" +#: .././repair/phase1.c:142 +msgid "would write modified primary superblock\n" +msgstr "zmodyfikowany główny superblok zostałby zapisany\n" -#: .././db/check.c:2731 +#: .././repair/phase2.c:69 #, c-format -msgid "inode %lld mode %#o fmt %s afmt %s nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n" -msgstr "i-węzeł %lld mode %#o fmt %s afmt %s nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n" +msgid "zero_log: cannot find log head/tail (xlog_find_tail=%d), zeroing it anyway\n" +msgstr "zero_log: nie znaleziono początku/końca logu (xlog_find_tail=%d), wyzerowano go\n" -#: .././db/check.c:2851 +#: .././repair/phase2.c:75 #, c-format -msgid "bad nblocks %lld for inode %lld, counted %lld\n" -msgstr "błędna liczba bloków %lld dla i-węzła %lld, naliczono %lld\n" +msgid "zero_log: head block % tail block %\n" +msgstr "zero_log: blok początku % blok końca %\n" -#: .././db/check.c:2858 -#, c-format -msgid "bad nextents %d for inode %lld, counted %d\n" -msgstr "błędna liczba ekstentów %d dla i-węzła %lld, naliczono %d\n" +#: .././repair/phase2.c:81 +msgid "" +"ALERT: The filesystem has valuable metadata changes in a log which is being\n" +"destroyed because the -L option was used.\n" +msgstr "" +"UWAGA: system plików zawiera wartościowe zmiany metadanych w logu, który jest\n" +"niszczony, ponieważ użyto opcji -L.\n" -#: .././db/check.c:2864 -#, c-format -msgid "bad anextents %d for inode %lld, counted %d\n" -msgstr "błędne anextents %d dla i-węzła %lld, naliczono %d\n" +#: .././repair/phase2.c:85 +msgid "" +"ERROR: The filesystem has valuable metadata changes in a log which needs to\n" +"be replayed. Mount the filesystem to replay the log, and unmount it before\n" +"re-running xfs_repair. If you are unable to mount the filesystem, then use\n" +"the -L option to destroy the log and attempt a repair.\n" +"Note that destroying the log may cause corruption -- please attempt a mount\n" +"of the filesystem before doing this.\n" +msgstr "" +"BŁĄD: system plików zawiera wartościowe zmiany metadanych w logu, który\n" +"musi być odtworzony. Należy podmontować system plików, aby odtworzyć log,\n" +"a następnie odmontować go przed ponownym uruchomieniem xfs_repair. Jeśli\n" +"systemu plików nie da się podmontować, można użyć opcji -L, aby zniszczyć\n" +"log i spróbować naprawić system plików.\n" +"Należy zauważyć, że zniszczenie logu może spowodować uszkodzenia danych -\n" +"proszę najpierw spróbować podmontować system plików.\n" -#: .././db/check.c:2916 -#, c-format -msgid "local inode %lld data is too large (size %lld)\n" -msgstr "dane lokalnego i-węzła %lld zbyt duże (rozmiar %lld)\n" +#: .././repair/phase2.c:127 +msgid "This filesystem has an external log. Specify log device with the -l option.\n" +msgstr "Ten system plików ma zewnętrzny log. Należy podać urządzenie logu przy użyciu opcji -l.\n" -#: .././db/check.c:2925 +#: .././repair/phase2.c:130 #, c-format -msgid "local inode %lld attr is too large (size %d)\n" -msgstr "atrybuty lokalnego i-węzła %lld zbyt duże (rozmiar %d)\n" +msgid "Phase 2 - using external log on %s\n" +msgstr "Faza 2 - użycie zewnętrznego logu na %s\n" -#: .././db/check.c:2990 -#, c-format -msgid "bad directory leaf magic # %#x for dir ino %lld\n" -msgstr "błędna liczba magiczna liścia katalogu %#x dla i-węzła katalogu %lld\n" +#: .././repair/phase2.c:132 +msgid "Phase 2 - using internal log\n" +msgstr "Faza 2 - użycie wewnętrznego logu\n" -#: .././db/check.c:3003 .././db/check.c:3768 -#, c-format -msgid "dir %lld entry %*.*s %lld\n" -msgstr "katalog %lld wpis %*.*s %lld\n" +#: .././repair/phase2.c:136 +msgid " - zero log...\n" +msgstr " - zerowanie logu...\n" -#: .././db/check.c:3010 .././db/check.c:3664 .././db/check.c:3756 -#, c-format -msgid "dir %lld entry %*.*s bad inode number %lld\n" -msgstr "katalog %lld wpis %*.*s: błędny numer i-węzła %lld\n" +#: .././repair/phase2.c:140 +msgid " - scan filesystem freespace and inode maps...\n" +msgstr " - przeszukiwanie wolnego miejsca i map i-węzłów w systemie plików...\n" -#: .././db/check.c:3089 .././db/check.c:3358 -#, c-format -msgid "dir inode %lld block %u=%llu\n" -msgstr "i-węzeł katalogu %lld, blok %u=%llu\n" +#: .././repair/phase2.c:156 +msgid "root inode chunk not found\n" +msgstr "nie znaleziono danych głównego i-węzła\n" -#: .././db/check.c:3101 .././db/check.c:3368 -#, c-format -msgid "can't read block %u for directory inode %lld\n" -msgstr "nie można odczytać bloku %u dla i-węzła katalogu %lld\n" +#: .././repair/phase2.c:175 +msgid " - found root inode chunk\n" +msgstr " - znaleziono dane głównego i-węzła\n" -#: .././db/check.c:3115 .././db/check.c:3381 -#, c-format -msgid "multiple .. entries in dir %lld\n" -msgstr "wiele wpisów .. w katalogu %lld\n" +#: .././repair/phase2.c:181 +msgid "root inode marked free, " +msgstr "główny i-węzeł oznaczony jako wolny, " -#: .././db/check.c:3137 -#, c-format -msgid "missing free index for data block %d in dir ino %lld\n" -msgstr "brak indeksu wolnego miejsca dla bloku danych %d w i-węźle katalogu %lld\n" +#: .././repair/phase2.c:190 +msgid "realtime bitmap inode marked free, " +msgstr "i-węzeł bitmapy realtime oznaczony jako wolny, " -#: .././db/check.c:3163 -#, c-format -msgid "bad free block magic # %#x for dir ino %lld block %d\n" -msgstr "błędna liczba magiczna wolnego bloku %#x dla i-węzła katalogu %lld, blok %d\n" +#: .././repair/phase2.c:199 +msgid "realtime summary inode marked free, " +msgstr "i-węzeł opisu realtime oznaczony jako wolny, " -#: .././db/check.c:3173 +#: .././repair/phase3.c:45 #, c-format -msgid "bad free block firstdb %d for dir ino %lld block %d\n" -msgstr "błędne firstdb wolnego bloku %d dla i-węzła katalogu %lld, blok %d\n" +msgid "cannot read agi block % for ag %u\n" +msgstr "nie można odczytać bloku agi % dla ag %u\n" -#: .././db/check.c:3186 +#: .././repair/phase3.c:76 .././repair/phase4.c:139 .././repair/phase5.c:1525 +#: .././repair/phase6.c:3059 #, c-format -msgid "bad free block nvalid/nused %d/%d for dir ino %lld block %d\n" -msgstr "błędne liczby nvalid/nused (%d/%d) wolnych bloków w i-węźle katalogu %lld, blok %d\n" +msgid " - agno = %d\n" +msgstr " - agno = %d\n" -#: .././db/check.c:3200 -#, c-format -msgid "bad free block ent %d is %d should be %d for dir ino %lld block %d\n" -msgstr "błędna liczba ent %d (równa %d, powinna być %d) wolnego bloku w i-węźle katalogu %lld, blok %d\n" +#: .././repair/phase3.c:93 +msgid "Phase 3 - for each AG...\n" +msgstr "Faza 3 - dla każdej AG...\n" -#: .././db/check.c:3214 -#, c-format -msgid "bad free block nused %d should be %d for dir ino %lld block %d\n" -msgstr "błędna liczba nused (%d, powinna być %d) wolnego bloku w i-węźle katalogu %lld, blok %d\n" +#: .././repair/phase3.c:95 +msgid " - scan and clear agi unlinked lists...\n" +msgstr " - przeszukiwanie i czyszczenie odłączonych list agi...\n" -#: .././db/check.c:3243 -#, c-format -msgid "bad leaf block forw/back pointers %d/%d for dir ino %lld block %d\n" -msgstr "błędne wskaźniki przód/tył (%d/%d) bloku liścia w i-węźle katalogu %lld, blok %d\n" +#: .././repair/phase3.c:97 +msgid " - scan (but don't clear) agi unlinked lists...\n" +msgstr " - przeszukiwanie (ale nie czyszczenie) odłączonych list agi...\n" -#: .././db/check.c:3252 -#, c-format -msgid "single leaf block for dir ino %lld block %d should be at block %d\n" -msgstr "blok pojedynczego liścia dla i-węzłu katalogu %lld, blok %d powinien być w bloku %d\n" +#: .././repair/phase3.c:117 +msgid " - process known inodes and perform inode discovery...\n" +msgstr " - przetwarzanie znanych i-węzłów i rozpoznawanie i-węzłów...\n" -#: .././db/check.c:3264 -#, c-format -msgid "bestfree %d for dir ino %lld block %d doesn't match table value %d\n" -msgstr "bestfree %d dla i-węzła katalogu %lld, blok %d nie zgadza się z wartością w tablicy %d\n" +#: .././repair/phase3.c:128 +msgid " - process newly discovered inodes...\n" +msgstr " - przetwarzanie nowo rozpoznanych i-węzłów...\n" -#: .././db/check.c:3288 -#, c-format -msgid "bad node block level %d for dir ino %lld block %d\n" -msgstr "błędny poziom bloku węzła %d dla i-węzła katalogu %lld, blok %d\n" +#: .././repair/phase4.c:174 +msgid "Phase 4 - check for duplicate blocks...\n" +msgstr "Faza 4 - sprawdzanie powtórzonych bloków...\n" -#: .././db/check.c:3320 -#, c-format -msgid "dir %lld block %d stale mismatch %d/%d\n" -msgstr "katalog %lld, blok %d: niezgodność liczby stale %d/%d\n" +#: .././repair/phase4.c:175 +msgid " - setting up duplicate extent list...\n" +msgstr " - tworzenie listy powtórzonych ekstentów...\n" -#: .././db/check.c:3352 -#, c-format -msgid "can't read root block for directory inode %lld\n" -msgstr "nie można odczytać głównego bloku dla i-węzła katalogu %lld\n" +#: .././repair/phase4.c:189 +msgid "root inode would be lost\n" +msgstr "główny i-węzeł zostałby utracony\n" -#: .././db/check.c:3441 -#, c-format -msgid "can't read block %lld for %s quota inode (fsblock %lld)\n" -msgstr "nie można odczytać bloku %lld i-węzła limitów %s (blok fs %lld)\n" +#: .././repair/phase4.c:191 +msgid "root inode lost\n" +msgstr "główny i-węzeł utracony\n" -#: .././db/check.c:3451 +#: .././repair/phase4.c:208 #, c-format -msgid "%s dqblk %lld entry %d id %u bc %lld ic %lld rc %lld\n" -msgstr "%s dqblk %lld wpis %d id %u bc %lld ic %lld rc %lld\n" +msgid "unknown block state, ag %d, block %d\n" +msgstr "nieznany stan bloku, ag %d, blok %d\n" -#: .././db/check.c:3459 +#: .././repair/phase4.c:241 #, c-format -msgid "bad magic number %#x for %s dqblk %lld entry %d id %u\n" -msgstr "błędna liczba magiczna %#x dla dqblk %s %lld, wpis %d, id %u\n" +msgid "unknown rt extent state, extent %\n" +msgstr "nieznany stan ekstentu rt, ekstent %\n" -#: .././db/check.c:3468 -#, c-format -msgid "bad version number %#x for %s dqblk %lld entry %d id %u\n" -msgstr "błędny numer wersji %#x dla dqblk %s %lld, wpis %d, id %u\n" +#: .././repair/phase4.c:290 +msgid " - check for inodes claiming duplicate blocks...\n" +msgstr " - szukanie i-węzłów odwołujących się do powtórzonych bloków...\n" -#: .././db/check.c:3478 -#, c-format -msgid "bad flags %#x for %s dqblk %lld entry %d id %u\n" -msgstr "błędne flagi %#x dla dqblk %s %lld, wpis %d, id %u\n" +#: .././repair/phase5.c:219 +msgid "could not set up btree block array\n" +msgstr "nie udało się utworzyć tablicy bloków b-drzewa\n" -#: .././db/check.c:3487 -#, c-format -msgid "bad id %u for %s dqblk %lld entry %d id %u\n" -msgstr "błędne id %u dla dqblk %s %lld, wpis %d, id %u\n" +#: .././repair/phase5.c:231 +msgid "error - not enough free space in filesystem\n" +msgstr "błąd - za mało wolnego miejsca w systemie plików\n" -#: .././db/check.c:3533 +#: .././repair/phase5.c:445 #, c-format -msgid "block %lld for rtbitmap inode is missing\n" -msgstr "brak bloku %lld dla i-węzła rtbitmapy\n" +msgid "can't rebuild fs trees -- not enough free space on ag %u\n" +msgstr "nie można przebudować drzew systemu plików - za mało wolnego miejsca w ag %u\n" -#: .././db/check.c:3544 +#: .././repair/phase5.c:468 #, c-format -msgid "can't read block %lld for rtbitmap inode\n" -msgstr "nie można odczytać bloku %lld dla i-węzła rtbitmapy\n" +msgid "ag %u - not enough free space to build freespace btrees\n" +msgstr "ag %u - za mało wolnego miejsca na przebudowanie b-drzew wolnego miejsca\n" -#: .././db/check.c:3600 +#: .././repair/phase5.c:503 #, c-format -msgid "block %lld for rtsummary inode is missing\n" -msgstr "brak bloku %lld dla i-węzła rtsummary\n" +msgid "not enough free blocks left to describe all free blocks in AG %u\n" +msgstr "za mało wolnych bloków na opisanie wszystkich wolnych bloków w AG %u\n" -#: .././db/check.c:3611 +#: .././repair/phase5.c:1399 #, c-format -msgid "can't read block %lld for rtsummary inode\n" -msgstr "nie można odczytać bloku %lld dla i-węzła rtsummary\n" +msgid "lost %d blocks in ag %u\n" +msgstr "utracono %d bloków w ag %u\n" -#: .././db/check.c:3644 .././db/check.c:3748 +#: .././repair/phase5.c:1402 #, c-format -msgid "dir %lld entry . %lld\n" -msgstr "katalog %lld, wpis . %lld\n" +msgid "thought we were going to lose %d blocks in ag %u, actually lost %d\n" +msgstr "przewidywano utracenie %d bloków w ag %u, a utracono %d\n" -#: .././db/check.c:3652 -#, c-format -msgid "dir %llu bad size in entry at %d\n" -msgstr "katalog %llu: błędny rozmiar we wpisie przy %d\n" +#: .././repair/phase5.c:1471 .././repair/xfs_repair.c:891 +msgid "couldn't get superblock\n" +msgstr "nie udało się pobrać superbloku\n" -#: .././db/check.c:3676 +#: .././repair/phase5.c:1548 #, c-format -msgid "dir %lld entry %*.*s offset %d %lld\n" -msgstr "katalog %lld wpis %*.*s offset %d %lld\n" +msgid "unable to rebuild AG %u. Not enough free space in on-disk AG.\n" +msgstr "nie udało się przebudować AG %u. Za mało wolnego miejsca w AG na dysku.\n" -#: .././db/check.c:3681 +#: .././repair/phase5.c:1588 #, c-format -msgid "dir %lld entry %*.*s bad offset %d\n" -msgstr "katalog %lld wpis %*.*s błędny offset %d\n" +msgid "unable to rebuild AG %u. No free space.\n" +msgstr "nie udało się przebudować AG %u. Brak wolnego miejsca.\n" -#: .././db/check.c:3694 +#: .././repair/phase5.c:1615 #, c-format -msgid "dir %llu size is %lld, should be %u\n" -msgstr "katalog %llu: rozmiar %lld, powinien być %u\n" +msgid "lost %d blocks in agno %d, sorry.\n" +msgstr "niestety utracono %d bloków w agno %d.\n" -#: .././db/check.c:3702 -#, c-format -msgid "dir %llu offsets too high\n" -msgstr "katalog %llu: offsety zbyt duże\n" +#: .././repair/phase5.c:1704 +msgid "Phase 5 - rebuild AG headers and trees...\n" +msgstr "Faza 5 - przebudowywanie nagłówków i drzew AG...\n" -#: .././db/check.c:3713 .././db/check.c:3782 -#, c-format -msgid "dir %lld entry .. bad inode number %lld\n" -msgstr "katalog %lld wpis .. - błędny numer i-węzła %lld\n" +#: .././repair/phase5.c:1734 +msgid "cannot alloc sb_icount_ag buffers\n" +msgstr "nie można przydzielić buforów sb_icount_ag\n" -#: .././db/check.c:3718 .././db/check.c:3787 -#, c-format -msgid "dir %lld entry .. %lld\n" -msgstr "katalog %lld wpis .. %lld\n" +#: .././repair/phase5.c:1738 +msgid "cannot alloc sb_ifree_ag buffers\n" +msgstr "nie można przydzielić buforów sb_ifree_ag\n" -#: .././db/check.c:3721 -#, c-format -msgid "dir %lld i8count mismatch is %d should be %d\n" -msgstr "katalog %lld: niezgodność i8count: jest %d, powinno być %d\n" +#: .././repair/phase5.c:1742 +msgid "cannot alloc sb_fdblocks_ag buffers\n" +msgstr "nie można przydzielić buforów sb_fdblocks_ag\n" -#: .././db/check.c:3773 -#, c-format -msgid "dir %llu size is %lld, should be %d\n" -msgstr "katalog %llu: rozmiar wynosi %lld, powinien być %d\n" +#: .././repair/phase5.c:1761 +msgid " - generate realtime summary info and bitmap...\n" +msgstr " - generowanie opisu i bitmapy realtime...\n" -#: .././db/check.c:3864 -#, c-format -msgid "%s quota id %u, have/exp" -msgstr "limit %s id %u: jest/exp" +#: .././repair/phase5.c:1766 +msgid " - reset superblock...\n" +msgstr " - przestawianie superbloku...\n" -#: .././db/check.c:3867 +#: .././repair/phase6.c:64 #, c-format -msgid " bc %lld/%lld" -msgstr " bc %lld/%lld" +msgid "malloc failed add_dotdot_update (%zu bytes)\n" +msgstr "malloc nie powiodło się w add_dotdot_update (%zu bajtów)\n" -#: .././db/check.c:3871 +#: .././repair/phase6.c:216 #, c-format -msgid " ic %lld/%lld" -msgstr " ic %lld/%lld" +msgid "malloc failed in dir_hash_add (%zu bytes)\n" +msgstr "malloc nie powiodło się w dir_hash_add (%zu bajtów)\n" -#: .././db/check.c:3875 -#, c-format -msgid " rc %lld/%lld" -msgstr " rc %lld/%lld" +#: .././repair/phase6.c:270 +msgid "ok" +msgstr "ok" -#: .././db/check.c:3931 -#, c-format -msgid "can't read superblock for ag %u\n" -msgstr "nie można odczytać superbloku dla ag %u\n" +#: .././repair/phase6.c:271 +msgid "duplicate leaf" +msgstr "powtórzony liść" -#: .././db/check.c:3940 -#, c-format -msgid "bad sb magic # %#x in ag %u\n" -msgstr "błędna liczba magiczna %#x superbloku w ag %u\n" +#: .././repair/phase6.c:272 +msgid "hash value mismatch" +msgstr "niezgodność wartości hasza" -#: .././db/check.c:3946 -#, c-format -msgid "bad sb version # %#x in ag %u\n" -msgstr "błędny numer wersji %#x superbloku w ag %u\n" +#: .././repair/phase6.c:273 +msgid "no data entry" +msgstr "brak wpisu danych" -#: .././db/check.c:3956 .././db/sb.c:201 -msgid "mkfs not completed successfully\n" -msgstr "mkfs nie zakończony pomyślnie\n" +#: .././repair/phase6.c:274 +msgid "no leaf entry" +msgstr "brak wpisu liścia" -#: .././db/check.c:3968 .././db/frag.c:365 -#, c-format -msgid "can't read agf block for ag %u\n" -msgstr "nie można odczytać bloku agf dla ag %u\n" +#: .././repair/phase6.c:275 +msgid "bad stale count" +msgstr "błędna liczba stale" -#: .././db/check.c:3974 +#: .././repair/phase6.c:283 #, c-format -msgid "bad agf magic # %#x in ag %u\n" -msgstr "błędna liczba magiczna agf %#x w ag %u\n" +msgid "bad hash table for directory inode % (%s): " +msgstr "błędna tablica haszująca dla i-węzła katalogu % (%s): " -#: .././db/check.c:3980 -#, c-format -msgid "bad agf version # %#x in ag %u\n" -msgstr "błędny numer wersji agf %#x w ag %u\n" +#: .././repair/phase6.c:286 +msgid "rebuilding\n" +msgstr "przebudowano\n" -#: .././db/check.c:3996 .././db/frag.c:374 -#, c-format -msgid "can't read agi block for ag %u\n" -msgstr "nie można odczytać bloku agi w ag %u\n" +#: .././repair/phase6.c:288 +msgid "would rebuild\n" +msgstr "zostałaby przebudowana\n" -#: .././db/check.c:4002 -#, c-format -msgid "bad agi magic # %#x in ag %u\n" -msgstr "błędna liczba magiczna agi %#x w ag %u\n" +#: .././repair/phase6.c:324 +msgid "calloc failed in dir_hash_init\n" +msgstr "calloc nie powiodło się w dir_hash_init\n" -#: .././db/check.c:4008 -#, c-format -msgid "bad agi version # %#x in ag %u\n" -msgstr "błędny numer wersji agi # %#x w ag %u\n" +#: .././repair/phase6.c:471 +msgid "ran out of disk space!\n" +msgstr "brak miejsca na dysku!\n" -#: .././db/check.c:4048 +#: .././repair/phase6.c:473 #, c-format -msgid "agf_btreeblks %u, counted %u in ag %u\n" -msgstr "agf_btreeblks %u, naliczono %u w ag %u\n" +msgid "xfs_trans_reserve returned %d\n" +msgstr "xfs_trans_reserve zwróciło %d\n" -#: .././db/check.c:4072 +#: .././repair/phase6.c:506 .././repair/phase6.c:615 #, c-format -msgid "agi unlinked bucket %d is %u in ag %u (inode=%lld)\n" -msgstr "agi unlinked bucket %d is %u in ag %u (inode=%lld)\n" +msgid "couldn't iget realtime bitmap inode -- error - %d\n" +msgstr "nie udało się wykonać iget dla i-węzła bitmapy realtime - błąd %d\n" -#: .././db/check.c:4109 +#: .././repair/phase6.c:570 #, c-format -msgid "can't read agfl block for ag %u\n" -msgstr "nie można odczytać bloku agfl dla ag %u\n" +msgid "couldn't allocate realtime bitmap, error = %d\n" +msgstr "nie udało się przydzielić bitmapy realtime, błąd = %d\n" -#: .././db/check.c:4128 +#: .././repair/phase6.c:583 #, c-format -msgid "freeblk count %u != flcount %u in ag %u\n" -msgstr "liczba freeblk %u != flcount %u w ag %u\n" +msgid "allocation of the realtime bitmap failed, error = %d\n" +msgstr "przydzielenie bitmapy realtime nie powiodło się, błąd = %d\n" -#: .././db/check.c:4157 .././db/check.c:4185 .././db/frag.c:397 -#: .././db/frag.c:420 .././db/freesp.c:270 +#: .././repair/phase6.c:629 #, c-format -msgid "can't read btree block %u/%u\n" -msgstr "nie można odczytać bloku b-drzewa %u/%u\n" +msgid "couldn't map realtime bitmap block %, error = %d\n" +msgstr "nie udało się odwzorować bloku bitmapy realtime %, błąd = %d\n" -#: .././db/check.c:4218 +#: .././repair/phase6.c:642 #, c-format -msgid "bad magic # %#x in inode %lld bmbt block %u/%u\n" -msgstr "błędna liczba magiczna %#x w i-węźle %lld, blok bmbt %u/%u\n" +msgid "can't access block % (fsbno %) of realtime bitmap inode %\n" +msgstr "brak dostępu do bloku % (fsbno %) i-węzła bitmapy realtime %\n" -#: .././db/check.c:4225 +#: .././repair/phase6.c:687 .././repair/phase6.c:762 #, c-format -msgid "expected level %d got %d in inode %lld bmbt block %u/%u\n" -msgstr "oczekiwano poziomu %d, a uzyskano %d w i-węźle %lld, blok bmbt %u/%u\n" +msgid "couldn't iget realtime summary inode -- error - %d\n" +msgstr "nie udało się wykonać iget dla i-węzła opisu realtime - błąd %d\n" -#: .././db/check.c:4237 .././db/check.c:4254 +#: .././repair/phase6.c:701 #, c-format -msgid "bad btree nrecs (%u, min=%u, max=%u) in inode %lld bmap block %lld\n" -msgstr "błędna liczba rekordów b-drzewa (%u, min=%u, max=%u) w i-węźle %lld, blok bitmapy %lld\n" +msgid "couldn't map realtime summary inode block %, error = %d\n" +msgstr "nie udało się odwzorować bloku i-węzła opisu realtime %, błąd = %d\n" -#: .././db/check.c:4282 +#: .././repair/phase6.c:714 #, c-format -msgid "bad magic # %#x in btbno block %u/%u\n" -msgstr "błędna liczba magiczna %#x w bloku btbno %u/%u\n" +msgid "can't access block % (fsbno %) of realtime summary inode %\n" +msgstr "brak dostępu do bloku % (fsbno %) i-węzła opisu realtime %\n" -#: .././db/check.c:4291 +#: .././repair/phase6.c:831 #, c-format -msgid "expected level %d got %d in btbno block %u/%u\n" -msgstr "oczekiwano poziomu %d, a uzyskano %d w bloku btbno %u/%u\n" +msgid "couldn't allocate realtime summary inode, error = %d\n" +msgstr "nie udało się przydzielić i-węzła opisu realtime, błąd = %d\n" -#: .././db/check.c:4300 .././db/check.c:4328 .././db/check.c:4373 -#: .././db/check.c:4404 +#: .././repair/phase6.c:844 #, c-format -msgid "bad btree nrecs (%u, min=%u, max=%u) in btbno block %u/%u\n" -msgstr "błędna liczba rekordów b-drzewa (%u, min=%u, max=%u) w bloku btbno %u/%u\n" +msgid "allocation of the realtime summary ino failed, error = %d\n" +msgstr "przydzielenie i-węzła opisu realtime nie powiodło się, błąd = %d\n" -#: .././db/check.c:4355 +#: .././repair/phase6.c:876 #, c-format -msgid "bad magic # %#x in btcnt block %u/%u\n" -msgstr "błędna liczba magiczna %#x w bloku btcbt %u/%u\n" +msgid "could not iget root inode -- error - %d\n" +msgstr "nie udało się wykonać iget dla głównego i-węzła - błąd %d\n" -#: .././db/check.c:4364 +#: .././repair/phase6.c:958 #, c-format -msgid "expected level %d got %d in btcnt block %u/%u\n" -msgstr "oczekiwano poziomu %d, a uzyskano %d w bloku btcnt %u/%u\n" +msgid "%d - couldn't iget root inode to obtain %s\n" +msgstr "%d - nie udało się wykonać iget dla głównego węzła, aby uzyskać %s\n" -#: .././db/check.c:4435 +#: .././repair/phase6.c:991 #, c-format -msgid "bad magic # %#x in inobt block %u/%u\n" -msgstr "błędna liczba magiczna %#x w bloku inobt %u/%u\n" +msgid "%s inode allocation failed %d\n" +msgstr "przydzielenie i-węzłą %s nie powiodło się - %d\n" -#: .././db/check.c:4442 +#: .././repair/phase6.c:1038 #, c-format -msgid "expected level %d got %d in inobt block %u/%u\n" -msgstr "oczekiwano poziomu %d, a uzyskano %d w bloku inobt %u/%u\n" +msgid "can't make %s, createname error %d\n" +msgstr "nie można zrobić %s, błąd createname %d\n" -#: .././db/check.c:4451 .././db/check.c:4517 +#: .././repair/phase6.c:1058 #, c-format -msgid "bad btree nrecs (%u, min=%u, max=%u) in inobt block %u/%u\n" -msgstr "błędna liczba rekordów b-drzewa (%u, min=%u, max=%u) w bloku inobt %u/%u\n" +msgid "%s directory creation failed -- bmapf error %d\n" +msgstr "tworzenie katalogu %s nie powiodło się - błąd bmapf %d\n" -#: .././db/check.c:4486 .././db/frag.c:489 +#: .././repair/phase6.c:1105 #, c-format -msgid "can't read inode block %u/%u\n" -msgstr "nie można odczytać bloku i-węzła %u/%u\n" +msgid "%d - couldn't iget orphanage inode\n" +msgstr "%d - nie udało się wykonać iget dla i-węzła sierocińca\n" -#: .././db/check.c:4504 +#: .././repair/phase6.c:1118 #, c-format -msgid "ir_freecount/free mismatch, inode chunk %u/%u, freecount %d nfree %d\n" -msgstr "niezgodność ir_freecount/free, porcja i-węzłów %u/%u, freecount %d nfree %d\n" +msgid "%d - couldn't iget disconnected inode\n" +msgstr "%d - nie udało się wykonać iget dla odłączonego i-węzła\n" -#: .././db/check.c:4559 +#: .././repair/phase6.c:1137 .././repair/phase6.c:1180 +#: .././repair/phase6.c:1237 #, c-format -msgid "setting inode to %lld for block %u/%u\n" -msgstr "ustawianie i-węzła na %lld dla bloku %u/%u\n" +msgid "space reservation failed (%d), filesystem may be out of space\n" +msgstr "nie udało się zarezerwować miejsca (%d), może brakować miejsca w systemie plików\n" -#: .././db/check.c:4591 +#: .././repair/phase6.c:1148 .././repair/phase6.c:1192 +#: .././repair/phase6.c:1248 #, c-format -msgid "setting inode to %lld for rtblock %llu\n" -msgstr "ustawianie i-węzła na %lld dla rtbloku %llu\n" +msgid "name create failed in %s (%d), filesystem may be out of space\n" +msgstr "tworzenie nazwy nie powiodło się w %s (%d), może brakować miejsca w systemie plików\n" -#: .././db/check.c:4607 +#: .././repair/phase6.c:1161 #, c-format -msgid "inode %lld nlink %u %s dir\n" -msgstr "i-węzeł %lld nlink %u katalog %s\n" +msgid "creation of .. entry failed (%d), filesystem may be out of space\n" +msgstr "tworzenie wpisu .. nie powiodło się (%d), może brakować miejsca w systemie plików\n" -#: .././db/attrset.c:38 -msgid "[-r|-s|-p|-u] [-n] [-R|-C] [-v n] name" -msgstr "[-r|-s|-p|-u] [-n] [-R|-C] [-v n] nazwa" +#: .././repair/phase6.c:1170 +#, c-format +msgid "bmap finish failed (err - %d), filesystem may be out of space\n" +msgstr "zakończenie bmap nie powiodło się (błąd %d), może brakować miejsca w systemie plików\n" -#: .././db/attrset.c:39 -msgid "set the named attribute on the current inode" -msgstr "ustawienie atrybutu o podanej nazwie w bieżącym i-węźle" +#: .././repair/phase6.c:1211 +#, c-format +msgid "name replace op failed (%d), filesystem may be out of space\n" +msgstr "operacja zastąpienia nazwy nie powiodła się (%d), może brakować miejsca w systemie plików\n" -#: .././db/attrset.c:42 -msgid "[-r|-s|-p|-u] [-n] name" -msgstr "[-r|-s|-p|-u] [-n] nazwa" +#: .././repair/phase6.c:1218 .././repair/phase6.c:1258 +#: .././repair/phase6.c:1388 +#, c-format +msgid "bmap finish failed (%d), filesystem may be out of space\n" +msgstr "zakończenie bmap nie powiodło się (%d), może brakować miejsca w systemie plików\n" -#: .././db/attrset.c:43 -msgid "remove the named attribute from the current inode" -msgstr "usunięcie atrybutu o podanej nazwie z bieżącego i-węzła" +#: .././repair/phase6.c:1277 +msgid ", marking entry to be junked\n" +msgstr ", zaznaczono wpis do wyrzucenia\n" -#: .././db/attrset.c:49 -msgid "" -"\n" -" The 'attr_set' and 'attr_remove' commands provide interfaces for debugging\n" -" the extended attribute allocation and removal code.\n" -" Both commands require an attribute name to be specified, and the attr_set\n" -" command allows an optional value length (-v) to be provided as well.\n" -" There are 4 namespace flags:\n" -" -r -- 'root'\n" -" -u -- 'user'\t\t(default)\n" -" -s -- 'secure'\n" -"\n" -" For attr_set, these options further define the type of set operation:\n" -" -C -- 'create' - create attribute, fail if it already exists\n" -" -R -- 'replace' - replace attribute, fail if it does not exist\n" -" The backward compatibility mode 'noattr2' can be emulated (-n) also.\n" -"\n" -msgstr "" -"\n" -" Polecenia 'attr_set' i 'attr_remove' udostępniają interfejsy do diagnostyki\n" -" kodu przydzielania i usuwania rozszerzonych atrybutów.\n" -" Oba polecenia wymagają podania nazwy atrybutu, a polecenie attr_set\n" -" pozwala dodatkowo podać opcjonalną długość wartości (-v).\n" -" Są 4 flagi przestrzeni nazw:\n" -" -r - 'root'\n" -" -u - 'user' (domyślna)\n" -" -s - 'secure'\n" -"\n" -" Dla attr_set poniższe opcje określają rodzaj operacji ustawiania:\n" -" -C - 'create' - utworzenie atrybutu; nie powiedzie się, jeśli już istnieje\n" -" -R - 'replace' - zastąpienie atrybutu; nie powiedzie się, jeśli nie istnieje\n" -" Możliwa jest także emulacja trybu kompatybilności wstecznej 'noattr2' (-n).\n" -"\n" +#: .././repair/phase6.c:1281 +msgid ", would junk entry\n" +msgstr ", wpis zostałby wyrzucony\n" -#: .././db/attrset.c:86 .././db/attrset.c:189 .././db/addr.c:72 -#: .././db/print.c:74 .././db/type.c:102 .././db/write.c:101 -msgid "no current type\n" -msgstr "brak bieżącego typu\n" +#: .././repair/phase6.c:1315 +#, c-format +msgid "rebuilding directory inode %\n" +msgstr "przebudowywanie i-węzła katalogu %\n" -#: .././db/attrset.c:90 .././db/attrset.c:193 -msgid "current type is not inode\n" -msgstr "bieżący typ nie jest i-węzłem\n" +#: .././repair/phase6.c:1338 +#, c-format +msgid "xfs_bmap_last_offset failed -- error - %d\n" +msgstr "xfs_bmap_last_offset nie powiodło się - błąd %d\n" -#: .././db/attrset.c:125 +#: .././repair/phase6.c:1345 #, c-format -msgid "bad attr_set valuelen %s\n" -msgstr "błędna długość wartości %s dla attr_set\n" +msgid "xfs_bunmapi failed -- error - %d\n" +msgstr "xfs_bunmapi nie powiodło się - błąd %d\n" -#: .././db/attrset.c:131 -msgid "bad option for attr_set command\n" -msgstr "błędna opcja dla polecenia attr_set\n" +#: .././repair/phase6.c:1380 +#, c-format +msgid "name create failed in ino % (%d), filesystem may be out of space\n" +msgstr "tworzenie nazwy nie powiodło się w i-węźle % (%d), może brakować miejsca w systemie plików\n" -#: .././db/attrset.c:137 -msgid "too few options for attr_set (no name given)\n" -msgstr "za mało opcji dla attr_set (nie podano nazwy)\n" +#: .././repair/phase6.c:1445 +#, c-format +msgid "shrink_inode failed inode % block %u\n" +msgstr "shrink_inode nie powiodło się dla i-węzła % bloku %u\n" -#: .././db/attrset.c:146 +#: .././repair/phase6.c:1532 .././repair/phase6.c:2227 #, c-format -msgid "cannot allocate buffer (%d)\n" -msgstr "nie udało się przydzielić bufora (%d)\n" +msgid "realloc failed in %s (%zu bytes)\n" +msgstr "realloc nie powiodło się w %s (bajtów: %zu)\n" -#: .././db/attrset.c:155 .././db/attrset.c:230 +#: .././repair/phase6.c:1589 #, c-format -msgid "failed to iget inode %llu\n" -msgstr "operacja iget na i-węźle %llu nie powiodła się\n" +msgid "empty data block %u in directory inode %: " +msgstr "pusty blok danych %u w i-węźle katalogu %: " -#: .././db/attrset.c:162 +#: .././repair/phase6.c:1593 #, c-format -msgid "failed to set attr %s on inode %llu\n" -msgstr "ustawianie atrybutu %s w i-węźle %llu nie powiodło się\n" +msgid "corrupt block %u in directory inode %: " +msgstr "uszkodzony blok %u w i-węźle katalogu %: " -#: .././db/attrset.c:217 -msgid "bad option for attr_remove command\n" -msgstr "błędna opcja dla polecenia attr_remove\n" +#: .././repair/phase6.c:1597 +msgid "junking block\n" +msgstr "wyrzucono blok\n" -#: .././db/attrset.c:223 -msgid "too few options for attr_remove (no name given)\n" -msgstr "za mało opcji dla attr_remove (nie podano nazwy)\n" +#: .././repair/phase6.c:1600 +msgid "would junk block\n" +msgstr "blok zostałby wyrzucony\n" -#: .././db/attrset.c:236 +#: .././repair/phase6.c:1622 #, c-format -msgid "failed to remove attr %s from inode %llu\n" -msgstr "usunięcie atrybutu %s z i-węzła %llu nie powiodło się\n" +msgid "bad directory block magic # %#x for directory inode % block %d: " +msgstr "błędna liczba magiczna bloku katalogu %#x dla i-węzła katalogu % bloku %d: " -#: .././db/bmap.c:39 -msgid "[-ad] [block [len]]" -msgstr "[-ad] [blok [długość]]" +#: .././repair/phase6.c:1625 +#, c-format +msgid "fixing magic # to %#x\n" +msgstr "poprawiono liczbę magiczną na %#x\n" -#: .././db/bmap.c:40 -msgid "show block map for current file" -msgstr "pokazanie mapy bloków dla bieżącego pliku" +#: .././repair/phase6.c:1629 +#, c-format +msgid "would fix magic # to %#x\n" +msgstr "liczba magiczna zostałaby poprawiona na %#x\n" -#: .././db/bmap.c:153 .././db/inode.c:390 -msgid "no current inode\n" -msgstr "brak bieżącego i-węzła\n" +#: .././repair/phase6.c:1650 +#, c-format +msgid "directory inode % block %u has consecutive free entries: " +msgstr "i-węzeł katalogu % blok %u ma kolejne wolne wpisy: " -#: .././db/bmap.c:166 -msgid "bad option for bmap command\n" -msgstr "błędna opcja dla polecenia bmap\n" +#: .././repair/phase6.c:1653 +msgid "joining together\n" +msgstr "połączono\n" -#: .././db/bmap.c:183 -#, c-format -msgid "bad block number for bmap %s\n" -msgstr "błędny numer bloku dla bmap %s\n" +#: .././repair/phase6.c:1662 +msgid "would join together\n" +msgstr "zostałyby połączone\n" -#: .././db/bmap.c:191 +#: .././repair/phase6.c:1694 #, c-format -msgid "bad len for bmap %s\n" -msgstr "błędna długość dla bmap %s\n" +msgid "entry \"%s\" in directory inode % points to non-existent inode %" +msgstr "wpis \"%s\" w i-węźle katalogu % wskazuje na nie istniejący i-węzeł %" -#: .././db/bmap.c:214 +#: .././repair/phase6.c:1711 #, c-format -msgid "%s offset %lld startblock %llu (%u/%u) count %llu flag %u\n" -msgstr "%s oofset %lld blok-pocz %llu (%u/%u) liczba %llu flaga %u\n" +msgid "entry \"%s\" in directory inode % points to free inode %" +msgstr "wpis \"%s\" w i-węźle katalogu % wskazuje na wolny i-węzeł %" -#: .././db/addr.c:35 -msgid "[field-expression]" -msgstr "[wyrażenie-pól]" +#: .././repair/phase6.c:1729 .././repair/phase6.c:2541 +#, c-format +msgid "%s (ino %) in root (%) is not a directory" +msgstr "%s (i-węzeł %) w katalogu głównym (%) nie jest katalogiem" -#: .././db/addr.c:36 -msgid "set current address" -msgstr "ustawienie bieżącego adresu" +#: .././repair/phase6.c:1751 .././repair/phase6.c:2563 +#, c-format +msgid "entry \"%s\" (ino %) in dir % is a duplicate name" +msgstr "wpis \"%s\" (i-węzeł %) w katalogu % jest powtórzoną nazwą" -#: .././db/addr.c:42 -msgid "" -"\n" -" 'addr' uses the given field to set the filesystem address and type\n" -"\n" -" Examples:\n" -"\n" -" sb\n" -" a rootino - set the type to inode and set position to the root inode\n" -" a u.bmx[0].startblock (for inode with blockmap)\n" -"\n" -msgstr "" -"\n" -" 'addr' wykorzystuje podane pole do ustawienia adresu w systemie plików i typu\n" -"\n" -" Przykłady:\n" -"\n" -" sb\n" -" a rootino - ustawienie typu na i-węzeł i pozycji na i-węzeł główny\n" -" a u.bmx[0].startblock (dla i-węzła z mapą bloków)\n" -"\n" +#: .././repair/phase6.c:1782 +#, c-format +msgid "entry \"%s\" (ino %) in dir % is not in the the first block" +msgstr "wpis \"%s\" (i-węzeł %) w katalogu % nie jest w pierwszym bloku" -#: .././db/addr.c:82 +#: .././repair/phase6.c:1808 #, c-format -msgid "no fields for type %s\n" -msgstr "brak pól dla typu %s\n" +msgid "entry \"%s\" in dir % is not the first entry" +msgstr "wpis \"%s\" w katalogu % nie jest pierwszym wpisem" -#: .././db/addr.c:95 -msgid "array not allowed for addr command\n" -msgstr "tablica nie jest dozwolona dla polecenia addr\n" +#: .././repair/phase6.c:1834 .././repair/phase6.c:2632 +#, c-format +msgid "would fix ftype mismatch (%d/%d) in directory/child inode %/%\n" +msgstr "niezgodność ftype (%d/%d) w i-węźle katalogu/potomnym %/% zostałaby poprawiona\n" -#: .././db/addr.c:105 +#: .././repair/phase6.c:1839 .././repair/phase6.c:2637 #, c-format -msgid "no next type for field %s\n" -msgstr "brak następnego typu dla pola %s\n" +msgid "fixing ftype mismatch (%d/%d) in directory/child inode %/%\n" +msgstr "niezgodność ftype (%d/%d) w i-węźle katalogu/potomnym %/% zostanie poprawiona\n" -#: .././db/addr.c:112 +#: .././repair/phase6.c:1872 #, c-format -msgid "no addr function for field %s (type %s)\n" -msgstr "brak funkcji addr dla pola %s (typu %s)\n" - -#: .././db/agf.c:35 .././db/agfl.c:36 .././db/agi.c:35 .././db/sb.c:42 -msgid "[agno]" -msgstr "[agno]" +msgid "entry \"%s\" in dir % points to an already connected directory inode %\n" +msgstr "wpis \"%s\" w katalogu % wskazuje na już podłączony i-węzeł katalogu %\n" -#: .././db/agf.c:36 -msgid "set address to agf header" -msgstr "ustawienie adresu na nagłówek agf" +#: .././repair/phase6.c:1881 .././repair/phase6.c:2601 +#, c-format +msgid "entry \"%s\" in dir ino % doesn't have a .. entry, will set it in ino %.\n" +msgstr "wpis \"%s\" w i-węźle katalogu % nie ma wpisu .., zostanie ustawiony w i-węźle %.\n" -#: .././db/agf.c:79 -msgid "" -"\n" -" set allocation group free block list\n" -"\n" -" Example:\n" -"\n" -" agf 2 - move location to AGF in 2nd filesystem allocation group\n" -"\n" -" Located in the second sector of each allocation group, the AGF\n" -" contains the root of two different freespace btrees:\n" -" The 'cnt' btree keeps track freespace indexed on section size.\n" -" The 'bno' btree tracks sections of freespace indexed on block number.\n" -msgstr "" -"\n" -" ustawienie listy wolnych bloków grupy alokacji\n" -"\n" -" Przykład:\n" -"\n" -" agf 2 - zmiana pozycji na AGF w 2. grupie alokacji systemu plików\n" -"\n" -" Położony w drugim sektorze każdej grupy alokacji AGF zawiera korzeń\n" -" dwóch różnych b-drzew wolnej przestrzeni:\n" -" b-drzewo 'cnt' śledzi wolne miejsce indeksowane rozmiarem sekcji\n" -" b-drzewo 'bno' śledzi sekcje wolnego miejsca indeksowane numerem bloku.\n" +#: .././repair/phase6.c:1891 +#, c-format +msgid "entry \"%s\" in dir inode % inconsistent with .. value (%) in ino %\n" +msgstr "wpis \"%s\" w i-węźle katalogu % niespójny z wartością .. (%) w i-węźle %\n" -#: .././db/agf.c:104 .././db/agfl.c:90 .././db/agi.c:89 .././db/sb.c:151 +#: .././repair/phase6.c:1903 #, c-format -msgid "bad allocation group number %s\n" -msgstr "błędny numer grupy alokacji %s\n" +msgid "\twill clear entry \"%s\"\n" +msgstr "\twpis \"%s\" zostanie wyczyszczony\n" -#: .././db/agfl.c:37 -msgid "set address to agfl block" -msgstr "ustawienie adresu na blok agfl" +#: .././repair/phase6.c:1906 +#, c-format +msgid "\twould clear entry \"%s\"\n" +msgstr "\twpis \"%s\" zostałby wyczyszczony\n" -#: .././db/agfl.c:63 -msgid "" -"\n" -" set allocation group freelist\n" -"\n" -" Example:\n" -"\n" -" agfl 5\n" -" Located in the fourth sector of each allocation group,\n" -" the agfl freelist for internal btree space allocation is maintained\n" -" for each allocation group. This acts as a reserved pool of space\n" -" separate from the general filesystem freespace (not used for user data).\n" -"\n" -msgstr "" -"\n" -" ustawienie listy wolnego miejsca grupy alokacji\n" -"\n" -" Przykład:\n" -"\n" -" agfl 5\n" -" Położona w 4. sektorze każdej grupy alokacji lista wolnego miejsca agfl\n" -" służąca do wewnętrznego przydzielania miejsca dla b-drzew jest utrzymywana\n" -" dla każdej grupy alokacji. Działa jako zarezerwowana pula miejsca oddzielona\n" -" od ogólnego wolnego miejsca w systemie plików (nie używana dla danych\n" -" użytkownika).\n" -"\n" +#: .././repair/phase6.c:1953 +#, c-format +msgid "can't read block %u for directory inode %, error %d\n" +msgstr "nie można odczytać bloku %u dla i-węzła katalogu %, błąd %d\n" -#: .././db/agi.c:36 -msgid "set address to agi header" -msgstr "ustawienie adresu na nagłówek agi" +#: .././repair/phase6.c:1971 .././repair/phase6.c:2071 +#, c-format +msgid "leaf block %u for directory inode % bad header\n" +msgstr "błędny nagłówek bloku liścia %u dla i-węzła katalogu %\n" -#: .././db/agi.c:64 -msgid "" -"\n" -" set allocation group inode btree\n" -"\n" -" Example:\n" -"\n" -" agi 3 (set location to 3rd allocation group inode btree and type to 'agi')\n" -"\n" -" Located in the 3rd 512 byte block of each allocation group,\n" -" the agi inode btree tracks all used/free inodes in the allocation group.\n" -" Inodes are allocated in 16k 'chunks', each btree entry tracks a 'chunk'.\n" -"\n" -msgstr "" -"\n" -" ustawienie b-drzewa i-węzła grupy alokacji\n" -"\n" -" Przykład:\n" -"\n" -" agi 3 (ustawienie położenia na b-drzewo i-węzła 3. grupy alokacji i typu na 'agi')\n" -"\n" -" Położone w 3. 512-bajtowym bloku każdej grupy alokacji, b-drzewo i-węzła agi\n" -" śledzi wszystkie używane i wolne i-węzły w grupie alokacji.\n" -" I-węzły są przydzielane w 16k porcjach (chunk), każdy wpis b-drzewa śledzi\n" -" jedną.\n" -"\n" +#: .././repair/phase6.c:1988 +#, c-format +msgid "leaf block %u for directory inode % bad tail\n" +msgstr "błędna końcówka bloku liścia %u dla i-węzła katalogu %\n" -#: .././db/block.c:43 .././db/block.c:49 -msgid "filoff" -msgstr "filoff" +#: .././repair/phase6.c:2042 +#, c-format +msgid "can't read leaf block %u for directory inode %, error %d\n" +msgstr "nie można odczytać bloku liścia %u dla i-węzła katalogu %, błąd %d\n" -#: .././db/block.c:44 -msgid "set address to file offset (attr fork)" -msgstr "ustawienie adresu na offset w pliku (gałąź atrybutów)" +#: .././repair/phase6.c:2057 +#, c-format +msgid "unknown magic number %#x for block %u in directory inode %\n" +msgstr "nieznana liczba magiczna %#x dla bloku %u w i-węźle katalogu %\n" -#: .././db/block.c:46 -msgid "[d]" -msgstr "[d]" +#: .././repair/phase6.c:2096 +#, c-format +msgid "can't read freespace block %u for directory inode %, error %d\n" +msgstr "nie można odczytać bloku wolnego miejsca %u dla i-węzła katalogu %, błąd %d\n" -#: .././db/block.c:47 -msgid "set address to daddr value" -msgstr "ustawienie adresu na wartość daddr" +#: .././repair/phase6.c:2111 +#, c-format +msgid "free block %u for directory inode % bad header\n" +msgstr "błędny nagłówek wolnego bloku %u dla i-węzła katalogu %\n" -#: .././db/block.c:50 -msgid "set address to file offset (data fork)" -msgstr "ustawienie adresu na offset w pliku (gałąź danych)" +#: .././repair/phase6.c:2121 +#, c-format +msgid "free block %u entry %i for directory ino % bad\n" +msgstr "błędny wpis wolnego bloku %u numer %i dla i-węzła katalogu %\n" -#: .././db/block.c:52 -msgid "[fsb]" -msgstr "[fsb]" +#: .././repair/phase6.c:2131 +#, c-format +msgid "free block %u for directory inode % bad nused\n" +msgstr "błędna liczba nused w wolnym bloku %u dla i-węzła katalogu %\n" -#: .././db/block.c:53 -msgid "set address to fsblock value" -msgstr "ustawienie adresu na wartość fsblock" +#: .././repair/phase6.c:2142 +#, c-format +msgid "missing freetab entry %u for directory inode %\n" +msgstr "brak wpisu freetab %u dla i-węzła katalogu %\n" -#: .././db/block.c:59 -msgid "" -"\n" -" Example:\n" -"\n" -" 'ablock 23' - sets the file position to the 23rd filesystem block in\n" -" the inode's attribute fork. The filesystem block size is specified in\n" -" the superblock.\n" -"\n" -msgstr "" -"\n" -" Przykład:\n" -"\n" -" 'ablock 23' ustawia pozycję w pliku na 23. blok systemu plików w gałęzi\n" -" atrybutów i-węzła. Rozmiar bloku systemu plików jest określony w superbloku.\n" -"\n" +#: .././repair/phase6.c:2180 +#, c-format +msgid "malloc failed in %s (% bytes)\n" +msgstr "malloc nie powiodło się w %s (bajtów: %)\n" -#: .././db/block.c:82 .././db/block.c:177 +#: .././repair/phase6.c:2194 #, c-format -msgid "bad block number %s\n" -msgstr "błędny numer bloku %s\n" +msgid "calloc failed in %s (%zu bytes)\n" +msgstr "calloc nie powiodło się w %s (bajtów: %zu)\n" -#: .././db/block.c:90 -msgid "no attribute data for file\n" -msgstr "brak danych atrybutów dla pliku\n" +#: .././repair/phase6.c:2240 +#, c-format +msgid "can't read data block %u for directory inode % error %d\n" +msgstr "nie można odczytać bloku danych %u dla i-węzła katalogu %, błąd %d\n" -#: .././db/block.c:96 -msgid "file attr block is unmapped\n" -msgstr "blok atrybutów pliku nie ma odwzorowania\n" +#: .././repair/phase6.c:2333 +msgid "would junk entry\n" +msgstr "wpis zostałby wyrzucony\n" -#: .././db/block.c:119 -msgid "" -"\n" -" Example:\n" -"\n" -" 'daddr 102' - sets position to the 102nd absolute disk block\n" -" (512 byte block).\n" -msgstr "" -"\n" -" Przykład:\n" -"\n" -" 'daddr 102' ustawia pozycję na 102. (bezwzględnie) blok dysku\n" -" (blok 512-bajtowy).\n" +#: .././repair/phase6.c:2357 +msgid "junking entry\n" +msgstr "wyrzucono wpis\n" -#: .././db/block.c:135 +#: .././repair/phase6.c:2403 #, c-format -msgid "current daddr is %lld\n" -msgstr "bieżący daddr to %lld\n" +msgid "would set .. in sf dir inode % to %\n" +msgstr "wpis .. w i-węźle katalogu sf % zostałby ustawiony na %\n" -#: .././db/block.c:141 +#: .././repair/phase6.c:2407 #, c-format -msgid "bad daddr %s\n" -msgstr "błędny daddr %s\n" +msgid "setting .. in sf dir inode % to %\n" +msgstr "ustawiono wpis .. w i-węźle katalogu sf % na %\n" -#: .././db/block.c:153 -msgid "" -"\n" -" Example:\n" -"\n" -" 'dblock 23' - sets the file position to the 23rd filesystem block in\n" -" the inode's data fork. The filesystem block size is specified in the\n" -" superblock.\n" -"\n" -msgstr "" -"\n" -" Przykład:\n" -"\n" -" 'dblock 23' ustawia pozycję w pliku na 23. blok systemu plików w gałęzi\n" -" danych i-węzła. Rozmiar bloku systemu plików jest określony w superbloku.\n" -"\n" +#: .././repair/phase6.c:2508 +#, c-format +msgid "entry \"%s\" in shortform directory % references non-existent inode %\n" +msgstr "wpis \"%s\" w krótkim katalogu % odwołuje się do nie istniejącego i-węzła %\n" -#: .././db/block.c:185 -msgid "no type for file data\n" -msgstr "brak typu dla danych pliku\n" +#: .././repair/phase6.c:2525 +#, c-format +msgid "entry \"%s\" in shortform directory inode % points to free inode %\n" +msgstr "wpis \"%s\" w i-węźle krótkiego katalogu % wskazuje na wolny i-węzeł %\n" -#: .././db/block.c:192 -msgid "file data block is unmapped\n" -msgstr "blok danych plików nie ma odwzorowania\n" +#: .././repair/phase6.c:2587 +#, c-format +msgid "entry \"%s\" in directory inode % references already connected inode %.\n" +msgstr "wpis \"%s\" w i-węźle katalogu % odwołuje się do już podłączonego i-węzła %.\n" -#: .././db/block.c:210 -msgid "" -"\n" -" Example:\n" -"\n" -" 'fsblock 1023' - sets the file position to the 1023rd filesystem block.\n" -" The filesystem block size is specified in the superblock and set during\n" -" mkfs time. Offset is absolute (not AG relative).\n" -"\n" -msgstr "" -"\n" -" Przykład:\n" -"\n" -" 'fsblock 1023' ustawia pozycję w pliku na 1023. blok systemu plików.\n" -" Rozmiar bloku systemu plików jest określony w superbloku i ustawiany w\n" -" trakcie wykonywania mkfs. Offset jest bezwzględny (nie względem AG).\n" -"\n" +#: .././repair/phase6.c:2610 +#, c-format +msgid "entry \"%s\" in directory inode % not consistent with .. value (%) in inode %,\n" +msgstr "wpis \"%s\" w i-węźle katalogu % niespójny z wartością .. (%) w i-węźle %,\n" -#: .././db/block.c:229 +#: .././repair/phase6.c:2667 #, c-format -msgid "current fsblock is %lld\n" -msgstr "bieżący fsblock to %lld\n" - -#: .././db/block.c:235 .././db/block.c:241 -#, c-format -msgid "bad fsblock %s\n" -msgstr "błędny fsblock %s\n" +msgid "would fix i8count in inode %\n" +msgstr "i8count w i-węźle % zostałoby poprawione\n" -#: .././db/command.c:86 +#: .././repair/phase6.c:2682 #, c-format -msgid "bad argument count %d to %s, expected " -msgstr "błędny argument liczby %d dla %s, oczekiwano " +msgid "fixing i8count in inode %\n" +msgstr "poprawiono i8count w i-węźle %\n" -#: .././db/command.c:88 +#: .././repair/phase6.c:2702 #, c-format -msgid "at least %d" -msgstr "przynajmniej %d" +msgid "setting size to % bytes to reflect junked entries\n" +msgstr "ustawiono rozmiar na %, aby odzwierciedlał wyrzucone wpisy\n" -#: .././db/command.c:92 +#: .././repair/phase6.c:2741 .././repair/phase6.c:2745 .././repair/phase7.c:84 #, c-format -msgid "between %d and %d" -msgstr "od %d do %d" - -#: .././db/command.c:93 -msgid " arguments\n" -msgstr " argumentów\n" - -#: .././db/debug.c:27 -msgid "[flagbits]" -msgstr "[bity flag]" +msgid "couldn't map inode %, err = %d\n" +msgstr "nie udało się odwzorować i-węzła %, błąd = %d\n" -#: .././db/debug.c:28 -msgid "set debug option bits" -msgstr "ustawienie bitów opcji diagnostycznych" +#: .././repair/phase6.c:2850 +msgid "recreating root directory .. entry\n" +msgstr "ponowne tworzenie wpisu .. głównego katalogu\n" -#: .././db/debug.c:42 +#: .././repair/phase6.c:2868 #, c-format -msgid "bad value for debug %s\n" -msgstr "błędna wartość diagnostyki %s\n" - -#: .././db/dquot.c:37 -msgid "[projid|gid|uid]" -msgstr "[projid|gid|uid]" - -#: .././db/dquot.c:38 -msgid "set current address to project, group or user quota block" -msgstr "ustawienie bieżącego adresu na blok limitu projektu, grupy lub użytkownika" +msgid "can't make \"..\" entry in root inode %, createname error %d\n" +msgstr "nie można utworzyć wpisu \"..\" w i-węźle głównego katalogu %, błąd createname %d\n" -#: .././db/dquot.c:124 -msgid "bad option for dquot command\n" -msgstr "błędna opcja dla polecenia dquot\n" +#: .././repair/phase6.c:2879 +msgid "would recreate root directory .. entry\n" +msgstr "wpis .. głównego katalogu zostałby ponownie utworzony\n" -#: .././db/dquot.c:128 -msgid "project" -msgstr "projekt" +#: .././repair/phase6.c:2903 +#, c-format +msgid "would create missing \".\" entry in dir ino %\n" +msgstr "brakujący wpis \".\" w i-węźle katalogu % zostałby utworzony\n" -#: .././db/dquot.c:128 -msgid "group" -msgstr "grupę" +#: .././repair/phase6.c:2910 +#, c-format +msgid "creating missing \".\" entry in dir ino %\n" +msgstr "tworzenie brakującego wpisu \".\" w i-węźle katalogu %\n" -#: .././db/dquot.c:128 -msgid "user" -msgstr "użytkownika" +#: .././repair/phase6.c:2929 +#, c-format +msgid "can't make \".\" entry in dir ino %, createname error %d\n" +msgstr "nie można utworzyć wpisu \".\" w i-węźle katalogu %, błąd createname %d\n" -#: .././db/dquot.c:130 +#: .././repair/phase6.c:3026 #, c-format -msgid "dquot command requires one %s id argument\n" -msgstr "polecenie dquot wymaga jednego argumentu identyfikującego %s\n" +msgid "disconnected dir inode %, " +msgstr "odłączony i-węzeł katalogu %, " -#: .././db/dquot.c:137 +#: .././repair/phase6.c:3028 #, c-format -msgid "no %s quota inode present\n" -msgstr "i-węzeł limitów na %s nie jest dostępny\n" +msgid "disconnected inode %, " +msgstr "odłączony i-węzeł %, " -#: .././db/dquot.c:142 +#: .././repair/phase6.c:3032 #, c-format -msgid "bad %s id for dquot %s\n" -msgstr "błędna liczba identyfikująca %s dla dquot %s\n" +msgid "moving to %s\n" +msgstr "przeniesiono do %s\n" -#: .././db/dquot.c:154 +#: .././repair/phase6.c:3035 #, c-format -msgid "no %s quota data for id %d\n" -msgstr "brak danych limitów na %s dla id %d\n" +msgid "would move to %s\n" +msgstr "zostałby przeniesiony do %s\n" -#: .././db/echo.c:27 -msgid "[args]..." -msgstr "[argumenty]..." +#: .././repair/phase6.c:3120 +msgid "Phase 6 - check inode connectivity...\n" +msgstr "Faza 6 - sprawdzanie łączności i-węzłów...\n" -#: .././db/echo.c:28 -msgid "echo arguments" -msgstr "wypisanie argumentów" +#: .././repair/phase6.c:3134 +msgid "reinitializing root directory\n" +msgstr "ponowne inicjowanie głównego katalogu\n" -#: .././db/faddr.c:40 .././db/faddr.c:63 -msgid "no current allocation group, cannot set new addr\n" -msgstr "brak bieżącej grupy alokacji, nie można ustawić nowego adresu\n" +#: .././repair/phase6.c:3139 +msgid "would reinitialize root directory\n" +msgstr "główny katalog zostałby ponownie zainicjowany\n" -#: .././db/faddr.c:45 .././db/faddr.c:117 .././db/faddr.c:148 -#: .././db/faddr.c:180 .././db/faddr.c:202 .././db/faddr.c:232 -#: .././db/faddr.c:262 .././db/faddr.c:316 .././db/faddr.c:335 -msgid "null block number, cannot set new addr\n" -msgstr "pusty numer bloku, nie można ustawić nowego adresu\n" +#: .././repair/phase6.c:3145 +msgid "reinitializing realtime bitmap inode\n" +msgstr "ponowne inicjowanie i-węzła bitmapy realtime\n" -#: .././db/faddr.c:68 .././db/faddr.c:353 .././db/faddr.c:371 -#: .././db/faddr.c:389 -msgid "null inode number, cannot set new addr\n" -msgstr "pusty numer i-węzła, nie można ustawić nowego adresu\n" +#: .././repair/phase6.c:3149 +msgid "would reinitialize realtime bitmap inode\n" +msgstr "i-węzeł bitmapy realtime zostałby ponownie zainicjowany\n" -#: .././db/faddr.c:88 -msgid "null attribute block number, cannot set new addr\n" -msgstr "pusty number bloku atrybutów, nie można ustawić nowego adresu\n" +#: .././repair/phase6.c:3155 +msgid "reinitializing realtime summary inode\n" +msgstr "ponowne inicjowanie i-węzła opisu realtime\n" -#: .././db/faddr.c:94 -msgid "attribute block is unmapped\n" -msgstr "blok atrybutów jest nieodwzorowany\n" +#: .././repair/phase6.c:3159 +msgid "would reinitialize realtime summary inode\n" +msgstr "i-węzeł opisu realtime zostałby ponownie zainicjowany\n" -#: .././db/faddr.c:123 .././db/faddr.c:155 .././db/faddr.c:208 -#: .././db/faddr.c:239 -msgid "file block is unmapped\n" -msgstr "blok pliku jest nieodwzorowany\n" +#: .././repair/phase6.c:3165 +msgid " - resetting contents of realtime bitmap and summary inodes\n" +msgstr " - przestawianie zawartości i-węzłów bitmapy i opisu realtime\n" -#: .././db/faddr.c:285 -msgid "null directory block number, cannot set new addr\n" -msgstr "pusty numer bloku katalogu, nie można ustawić nowego adresu\n" +#: .././repair/phase6.c:3168 .././repair/phase6.c:3173 +msgid "Warning: realtime bitmap may be inconsistent\n" +msgstr "Uwaga: bitmapa realtime może być niespójna\n" -#: .././db/faddr.c:292 -msgid "directory block is unmapped\n" -msgstr "blok katalogu jest nieodwzorowany\n" +#: .././repair/phase6.c:3179 +msgid " - traversing filesystem ...\n" +msgstr " - przechodzenie systemu plików...\n" -#: .././db/flist.c:149 -#, c-format -msgid "field %s not found\n" -msgstr "nie znaleziono pola %s\n" +#: .././repair/phase6.c:3202 +msgid " - traversal finished ...\n" +msgstr " - przechodzenie zakończone...\n" -#: .././db/flist.c:159 +#: .././repair/phase6.c:3203 #, c-format -msgid "no elements in %s\n" -msgstr "brak elementów w %s\n" +msgid " - moving disconnected inodes to %s ...\n" +msgstr " - przenoszenie odłączonych i-węzłów do %s...\n" -#: .././db/flist.c:165 +#: .././repair/phase7.c:43 #, c-format -msgid "indices %d-%d for field %s out of range %d-%d\n" -msgstr "indeksy %d-%d dla pola %s są poza zakresem %d-%d\n" +msgid "resetting inode % nlinks from %u to %u\n" +msgstr "przestawiono nlinks i-węzła % z %u na %u\n" -#: .././db/flist.c:173 +#: .././repair/phase7.c:49 #, c-format -msgid "index %d for field %s out of range %d-%d\n" -msgstr "indeks %d dla pola %s jest poza zakresem %d-%d\n" +msgid "nlinks %u will overflow v1 ino, ino % will be converted to version 2\n" +msgstr "nlinks %u przepełni i-węzeł v1, i-węzeł % będzie skonwertowany do wersji 2\n" -#: .././db/flist.c:187 +#: .././repair/phase7.c:56 #, c-format -msgid "field %s is not an array\n" -msgstr "pole %s nie jest tablicą\n" +msgid "would have reset inode % nlinks from %u to %u\n" +msgstr "nlinks i-węzła % zostałoby przestawione z %u na %u\n" -#: .././db/flist.c:200 +#: .././repair/phase7.c:88 #, c-format -msgid "field %s has no subfields\n" -msgstr "pole %s nie ma podpól\n" +msgid "couldn't map inode %, err = %d, can't compare link counts\n" +msgstr "nie udało się odwzorować i-węzła %, błąd %d, nie można porównać liczby dowiązań\n" -#: .././db/flist.c:220 -#, c-format -msgid "fl@%p:\n" -msgstr "fl@%p:\n" +#: .././repair/phase7.c:127 +msgid "Phase 7 - verify and correct link counts...\n" +msgstr "Faza 7 - sprawdzanie i poprawianie liczby dowiązań...\n" -#: .././db/flist.c:221 -#, c-format -msgid "\tname=%s, fld=%p, child=%p, sibling=%p\n" -msgstr "\tnazwa=%s, fld=%p, child=%p, sibling=%p\n" +#: .././repair/phase7.c:129 +msgid "Phase 7 - verify link counts...\n" +msgstr "Faza 7 - sprawdzanie liczby dowiązań...\n" -#: .././db/flist.c:223 +#: .././repair/prefetch.c:532 +msgid "prefetch corruption\n" +msgstr "uszkodzenie prefetch\n" + +#: .././repair/prefetch.c:692 .././repair/prefetch.c:795 #, c-format -msgid "\tlow=%d, high=%d, flags=%d (%s%s), offset=%d\n" -msgstr "\tlow=%d, high=%d, flagi=%d (%s%s), offset=%d\n" +msgid "failed to create prefetch thread: %s\n" +msgstr "nie udało się utworzyć wątku prefetch: %s\n" -#: .././db/flist.c:225 -msgid "oklow " -msgstr "oklow " +#: .././repair/prefetch.c:832 +msgid "failed to initialize prefetch mutex\n" +msgstr "nie udało się zainicjować muteksu prefetch\n" -#: .././db/flist.c:226 -msgid "okhigh" -msgstr "okhigh" +#: .././repair/prefetch.c:834 .././repair/prefetch.c:836 +msgid "failed to initialize prefetch cond var\n" +msgstr "nie udało się zainicjować zmiennej warunkowej prefetch\n" -#: .././db/flist.c:227 -#, c-format -msgid "\tfld->name=%s, fld->ftyp=%d (%s)\n" -msgstr "\tfld->name=%s, fld->ftyp=%d (%s)\n" +#: .././repair/progress.c:16 +msgid "inodes" +msgstr "i-węzłów" -#: .././db/flist.c:230 -#, c-format -msgid "\tfld->flags=%d (%s%s%s%s%s)\n" -msgstr "\tfld->flags=%d (%s%s%s%s%s)\n" +#: .././repair/progress.c:20 +msgid "directories" +msgstr "katalogów" -#: .././db/flist.c:322 -#, c-format -msgid "bad syntax in field name %s\n" -msgstr "błędna składnia w nazwie pola %s\n" +#: .././repair/progress.c:22 +msgid "allocation groups" +msgstr "grup alokacji" -#: .././db/flist.c:378 +#: .././repair/progress.c:24 +msgid "AGI unlinked buckets" +msgstr "odłączonych kubełków AGI" + +#: .././repair/progress.c:28 +msgid "realtime extents" +msgstr "ekstentów realtime" + +#: .././repair/progress.c:30 +msgid "unlinked lists" +msgstr "odłączonych list" + +#: .././repair/progress.c:37 #, c-format -msgid "missing closing quote %s\n" -msgstr "brak cudzysłowu zamykającego %s\n" +msgid " - %02d:%02d:%02d: %s - %llu of %llu %s done\n" +msgstr " - %02d:%02d:%02d: %s - sprawdzono %llu z %llu %s\n" -#: .././db/flist.c:395 +#: .././repair/progress.c:39 #, c-format -msgid "bad character in field %s\n" -msgstr "błędny znak w polu %s\n" +msgid " - %02d:%02d:%02d: %s - %llu %s done\n" +msgstr " - %02d:%02d:%02d: %s - sprawdzono %llu %s\n" -#: .././db/fprint.c:98 -msgid "null" -msgstr "nic" +#: .././repair/progress.c:51 +msgid "scanning filesystem freespace" +msgstr "przeszukiwanie wolnego miejsca w systemie plików" -#: .././db/hash.c:30 -msgid "string" -msgstr "łańcuch" +#: .././repair/progress.c:53 +msgid "scanning agi unlinked lists" +msgstr "przeszukiwanie odłączonych list agi" -#: .././db/hash.c:31 -msgid "calculate hash value" -msgstr "obliczenie wartości skrótu" +#: .././repair/progress.c:55 +msgid "check uncertain AG inodes" +msgstr "sprawdzanie niepewnych i-węzłów AG" -#: .././db/hash.c:37 -msgid "" -"\n" -" 'hash' prints out the calculated hash value for a string using the\n" -"directory/attribute code hash function.\n" -"\n" -" Usage: \"hash \"\n" -"\n" -msgstr "" -"\n" -" 'hash' wypisuje wartość skrótu dla łańcucha obliczoną przy użyciu funkcji\n" -" haszującej dla katalogów/atrybutów.\n" -"\n" -" Składnia: \"hash <łańcuch>\"\n" -"\n" +#: .././repair/progress.c:57 +msgid "process known inodes and inode discovery" +msgstr "przetwarzanie znanych i-węzłów i rozpoznawanie i-węzłów" -#: .././db/help.c:89 -#, c-format -msgid "(or %s) " -msgstr "(lub %s) " +#: .././repair/progress.c:59 +msgid "process newly discovered inodes" +msgstr "przetwarzanie nowo rozpoznanych i-węzłów" -#: .././db/init.c:46 -#, c-format -msgid "Usage: %s [-fFrxV] [-p prog] [-l logdev] [-c cmd]... device\n" -msgstr "Składnia: %s [-fFrxV] [-p prog] [-l urz-log] [-c polecenie]... urządzenie\n" +#: .././repair/progress.c:61 +msgid "setting up duplicate extent list" +msgstr "tworzenie listy powtórzonych ekstentów" -#: .././db/init.c:112 -msgid "" -"\n" -"fatal error -- couldn't initialize XFS library\n" -msgstr "" -"\n" -"błąd krytyczny - nie udało się zainicjować biblioteki XFS\n" +#: .././repair/progress.c:63 +msgid "initialize realtime bitmap" +msgstr "inicjowanie bitmapy realtime" -#: .././db/init.c:118 -#, c-format -msgid "%s: %s is invalid (cannot read first 512 bytes)\n" -msgstr "%s: %s jest nieprawidłowy (nie można odczytać pierwszych 512 bajtów)\n" +#: .././repair/progress.c:65 +msgid "reset realtime bitmaps" +msgstr "ponowne tworzenie bitmapy realtime" -#: .././db/init.c:129 -#, c-format -msgid "%s: %s is not a valid XFS filesystem (unexpected SB magic number 0x%08x)\n" -msgstr "%s: %s nie jest poprawnym systemem plików XFS (nieoczekiwana liczba magiczna SB 0x%08x)\n" +#: .././repair/progress.c:67 +msgid "check for inodes claiming duplicate blocks" +msgstr "szukanie i-węzłów odwołujących się do powtórzonych bloków" -#: .././db/init.c:141 -#, c-format -msgid "%s: device %s unusable (not an XFS filesystem?)\n" -msgstr "%s: urządzenie %s nie nadaje się do użycia (to nie jest system plików XFS?)\n" +#: .././repair/progress.c:69 +msgid "rebuild AG headers and trees" +msgstr "przebudowywanie nagłówków i drzew AG" -#: .././db/input.c:43 -msgid "source-file" -msgstr "plik-źródłowy" +#: .././repair/progress.c:71 +msgid "traversing filesystem" +msgstr "przechodzenie systemu plików" -#: .././db/input.c:44 -msgid "get commands from source-file" -msgstr "odczyt poleceń z pliku-źródłowego" +#: .././repair/progress.c:73 +msgid "traversing all unattached subtrees" +msgstr "przechodzenie wszystkich odłączonych poddrzew" -#: .././db/input.c:320 -#, c-format -msgid "can't open %s\n" -msgstr "nie można otworzyć %s\n" +#: .././repair/progress.c:75 +msgid "moving disconnected inodes to lost+found" +msgstr "przenoszenie odłączonych i-węzłów do lost+found" -#: .././db/io.c:46 -msgid "pop location from the stack" -msgstr "odtworzenie pozycji ze stosu" +#: .././repair/progress.c:77 +msgid "verify and correct link counts" +msgstr "sprawdzanie i poprawianie liczby dowiązań" -#: .././db/io.c:49 -msgid "push location to the stack" -msgstr "zapisanie pozycji na stos" +#: .././repair/progress.c:79 +msgid "verify link counts" +msgstr "sprawdzanie liczby dowiązań" -#: .././db/io.c:52 -msgid "view the location stack" -msgstr "podejrzenie stosu pozycji" +#: .././repair/progress.c:118 +msgid "cannot malloc pointer to done vector\n" +msgstr "nie udało się przydzielić wskaźnika do wektora wykonania\n" -#: .././db/io.c:55 -msgid "move forward to next entry in the position ring" -msgstr "przejście na następną pozycję w kręgu" +#: .././repair/progress.c:135 +msgid "unable to create progress report thread\n" +msgstr "nie udało się utworzyć wątku raportowania postępu\n" -#: .././db/io.c:58 -msgid "move to the previous location in the position ring" -msgstr "przejście na poprzednią pozycję w kręgu" +#: .././repair/progress.c:178 +msgid "progress_rpt: cannot malloc progress msg buffer\n" +msgstr "progress_rpt: nie udało się przydzielić bufora komunikatów postępu\n" -#: .././db/io.c:61 -msgid "show position ring or move to a specific entry" -msgstr "pokazanie kręgu pozycji lub przejście do określonego wpisu" +#: .././repair/progress.c:192 +msgid "progress_rpt: cannot create timer\n" +msgstr "progress_rpt: nie można utworzyć zegara\n" -#: .././db/io.c:91 +#: .././repair/progress.c:195 +msgid "progress_rpt: cannot set timer\n" +msgstr "progress_rpt: nie można ustawić zegara\n" + +#: .././repair/progress.c:219 +msgid "progress_rpt: cannot lock progress mutex\n" +msgstr "progress_rpt: nie można zablokować muteksu\n" + +#: .././repair/progress.c:256 .././repair/progress.c:359 #, c-format -msgid "can't set block offset to %d\n" -msgstr "nie można ustawić offsetu bloku na %d\n" +msgid "%s" +msgstr "%s" -#: .././db/io.c:104 -msgid "can't pop anything from I/O stack\n" -msgstr "nie można pobrać nic ze stosu we/wy\n" +#: .././repair/progress.c:264 +#, c-format +msgid "\t- %02d:%02d:%02d: Phase %d: elapsed time %s - processed %d %s per minute\n" +msgstr "\t- %02d:%02d:%02d: Faza %d: miniony czas %s - przetworzono %d %s na minutę\n" -#: .././db/io.c:132 -msgid "" -"\n" -" Changes the address and data type to the first entry on the stack.\n" -"\n" -msgstr "" -"\n" -" Zmiana adresu i typu danych na pierwszy wpis ze stosu.\n" -"\n" +#: .././repair/progress.c:269 +#, c-format +msgid "\t- %02d:%02d:%02d: Phase %d: %%% done - estimated remaining time %s\n" +msgstr "\t- %02d:%02d:%02d: Faza %d: %%% zrobione - przewidywany pozostały czas %s\n" + +#: .././repair/progress.c:277 +msgid "progress_rpt: error unlock msg mutex\n" +msgstr "progress_rpt: błąd odblokowywania muteksu komunikatów\n" + +#: .././repair/progress.c:283 +msgid "cannot delete timer\n" +msgstr "nie można usunąć zegara\n" + +#: .././repair/progress.c:297 +msgid "set_progress_msg: cannot lock progress mutex\n" +msgstr "set_progress_msg: nie można zablokować mutekstu postępu\n" + +#: .././repair/progress.c:307 +msgid "set_progress_msg: cannot unlock progress mutex\n" +msgstr "set_progress_msg: nie można odblokować mutekstu postępu\n" -#: .././db/io.c:146 +#: .././repair/progress.c:327 +msgid "print_final_rpt: cannot lock progress mutex\n" +msgstr "print_final_rpt: nie można zablokować mutekstu postępu\n" + +#: .././repair/progress.c:363 +msgid "print_final_rpt: cannot unlock progress mutex\n" +msgstr "print_final_rpt: nie można odblokować muteksu postępu\n" + +#: .././repair/progress.c:412 #, c-format -msgid "\tbyte offset %lld, length %d\n" -msgstr "\toffset w bajtach %lld, długość %d\n" +msgid "%02d:%02d:%02d" +msgstr "%02d:%02d:%02d" -#: .././db/io.c:147 +#: .././repair/progress.c:434 #, c-format -msgid "\tbuffer block %lld (fsbno %lld), %d bb%s\n" -msgstr "\tblok bufora %lld (fsbno %lld), %d bb%s\n" +msgid "%d week" +msgstr "%d tygodni" -#: .././db/io.c:151 -msgid "\tblock map" -msgstr "\tmapa bloków" +#: .././repair/progress.c:435 .././repair/progress.c:445 +#: .././repair/progress.c:461 .././repair/progress.c:479 +#: .././repair/progress.c:494 +msgid "s" +msgstr " " -#: .././db/io.c:156 +# XXX: ngettext() +#: .././repair/progress.c:444 #, c-format -msgid "\tinode %lld, dir inode %lld, type %s\n" -msgstr "\ti-węzeł %lld, i-węzeł katalogu %lld, typ %s\n" +msgid "%d day" +msgstr "%d dni" -#: .././db/io.c:167 -msgid "no entries in location ring.\n" -msgstr "brak wpisów w kręgu pozycji.\n" +#: .././repair/progress.c:451 .././repair/progress.c:468 +#: .././repair/progress.c:486 .././repair/progress.c:496 +msgid ", " +msgstr ", " -#: .././db/io.c:171 -msgid " type bblock bblen fsbno inode\n" -msgstr " typ bblok bblen fsbno i-węzeł\n" +#: .././repair/progress.c:460 +#, c-format +msgid "%d hour" +msgstr "%d godzin" -#: .././db/io.c:225 +#: .././repair/progress.c:478 #, c-format -msgid "no such command %s\n" -msgstr "nieznane polecenie %s\n" +msgid "%d minute" +msgstr "%d minut" -#: .././db/io.c:229 +#: .././repair/progress.c:493 #, c-format -msgid "no push form allowed for %s\n" -msgstr "forma push niedozwolona dla %s\n" +msgid "%d second" +msgstr "%d sekund" -#: .././db/io.c:253 +#: .././repair/progress.c:514 +#, c-format msgid "" "\n" -" Allows you to push the current address and data type on the stack for\n" -" later return. 'push' also accepts an additional command to execute after\n" -" storing the current address (ex: 'push a rootino' from the superblock).\n" -"\n" +" XFS_REPAIR Summary %s\n" msgstr "" "\n" -" Pozwala zapisać bieżący adres i typ danych na stos w celu późniejszego\n" -" powrotu. 'push' akceptuje także dodatkowe polecenie do wykonania po zapisaniu\n" -" bieżącego adresu (np. 'push a rootino' z superbloku).\n" -"\n" - -#: .././db/io.c:269 .././db/io.c:310 -msgid "ring is empty\n" -msgstr "krąg jest pusty\n" +" Podsumowanie XFS_REPAIR %s\n" -#: .././db/io.c:273 -msgid "no further entries\n" -msgstr "brak dalszych wpisów\n" +#: .././repair/progress.c:516 +msgid "Phase\t\tStart\t\tEnd\t\tDuration\n" +msgstr "Faza\t\tPoczątek\tKoniec\t\tCzas trwania\n" -#: .././db/io.c:293 -msgid "" -"\n" -" The 'forward' ('f') command moves to the next location in the position\n" -" ring, updating the current position and data type. If the current location\n" -" is the top entry in the ring, then the 'forward' command will have\n" -" no effect.\n" -"\n" -msgstr "" -"\n" -" Polecenie 'forward' ('f') przechodzi do następnej pozycji w kręgu,\n" -" uaktualniając bieżącą pozycję i typ danych. Jeśli bieżąca pozycja\n" -" jest szczytowym wpisem w kręgu, polecenie nie przyniesie efektu.\n" -"\n" +#: .././repair/progress.c:521 .././repair/progress.c:524 +#, c-format +msgid "Phase %d:\tSkipped\n" +msgstr "Faza %d:\tPominięta\n" -#: .././db/io.c:314 -msgid "no previous entries\n" -msgstr "brak poprzednich wpisów\n" +#: .././repair/progress.c:528 +#, c-format +msgid "Phase %d:\t%02d/%02d %02d:%02d:%02d\t%02d/%02d %02d:%02d:%02d\t%s\n" +msgstr "Faza %d:\t%02d.%02d %02d:%02d:%02d\t%02d.%02d %02d:%02d:%02d\t%s\n" -#: .././db/io.c:334 +#: .././repair/progress.c:534 +#, c-format msgid "" "\n" -" The 'back' ('b') command moves to the previous location in the position\n" -" ring, updating the current position and data type. If the current location\n" -" is the last entry in the ring, then the 'back' command will have no effect.\n" -"\n" +"Total run time: %s\n" msgstr "" "\n" -" Polecenie 'back' ('b') przechodzi do poprzedniej pozycji w kręgu,\n" -" uaktualniając bieżącą pozycję i typ danych. Jeśli bieżąca pozycja\n" -" jest ostatnim wpisem w kręgu, polecenie nie przyniesie efektu.\n" -"\n" +"Całkowity czas trwania: %s\n" -#: .././db/io.c:357 -#, c-format -msgid "invalid entry: %d\n" -msgstr "błędny wpis: %d\n" +#: .././repair/rt.c:47 +msgid "couldn't allocate memory for incore realtime bitmap.\n" +msgstr "nie udało się przydzielić pamięci dla bitmapy realtime.\n" -#: .././db/io.c:374 +#: .././repair/rt.c:51 +msgid "couldn't allocate memory for incore realtime summary info.\n" +msgstr "nie udało się przydzielić pamięci dla opisu realtime.\n" + +#: .././repair/rt.c:203 +#, c-format +msgid "can't find block %d for rtbitmap inode\n" +msgstr "nie można odnaleźć bloku %d dla i-węzła bitmapy realtime\n" + +#: .././repair/rt.c:211 +#, c-format +msgid "can't read block %d for rtbitmap inode\n" +msgstr "nie można odczytać bloku %d dla i-węzła bitmapy realtime\n" + +#: .././repair/rt.c:265 +#, c-format +msgid "block %d for rtsummary inode is missing\n" +msgstr "brak bloku %d dla i-węzła opisu realtime\n" + +#: .././repair/rt.c:273 #, c-format +msgid "can't read block %d for rtsummary inode\n" +msgstr "nie można odczytać bloku %d dla i-węzła opisu realtime\n" + +#: .././repair/sb.c:103 msgid "" "\n" -" The position ring automatically keeps track of each disk location and\n" -" structure type for each change of position you make during your xfs_db\n" -" session. The last %d most recent entries are kept in the ring.\n" -"\n" -" To display the current list of ring entries type 'ring' by itself on\n" -" the command line. The entry highlighted by an asterisk ('*') is the\n" -" current entry.\n" -"\n" -" To move to another entry in the ring type 'ring ' where is\n" -" your desired entry from the ring position list.\n" -"\n" -" You may also use the 'forward' ('f') or 'back' ('b') commands to move\n" -" to the previous or next entry in the ring, respectively.\n" -"\n" -" Note: Unlike the 'stack', 'push' and 'pop' commands, the ring tracks your\n" -" location implicitly. Use the 'push' and 'pop' commands if you wish to\n" -" store a specific location explicitly for later return.\n" -"\n" +"attempting to find secondary superblock...\n" msgstr "" "\n" -" Krąg pozycji automatycznie śledzi każde położenie na dysku i typ struktury\n" -" dla każdej zmiany pozycji wykonywanej podczas sesji xfs_db. Ostatenie %d\n" -" pozycji jest trzymane w kręgu.\n" -"\n" -" Aby wyświetlić bieżącą listę wpisów w kręgu należy napisać w linii poleceń\n" -" po prostu 'ring'. Wpis oznaczony gwiazdką ('*') jest wpisem bieżącym.\n" -"\n" -" Aby przejść do innego wpisu w kręgu, należy wpisać 'ring ', gdzie\n" -" jest numerem pożądanego wpisu na liście pozycji.\n" -"\n" -" Można także używać poleceń 'forward' ('f') i 'back' ('b'), aby przenieść\n" -" się odpowiednio na poprzedni lub następny wpis w kręgu.\n" -"\n" -" Uwaga: w przeciwieństwie do poleceń 'stack', 'push' i 'pop', krąg śledzi\n" -" pozycje niejawnie. Aby zapisać jawnie dane położenie w celu późniejszego\n" -" powrotu, należy użyć poleceń 'push' i 'pop'.\n" -"\n" +"próba odnalezienia zapasowego superbloku...\n" -#: .././db/io.c:438 .././db/io.c:481 -#, c-format -msgid "can't seek in filesystem at bb %lld\n" -msgstr "nie można wykonać seek w systemie plików na bb %lld\n" +#: .././repair/sb.c:108 +msgid "error finding secondary superblock -- failed to memalign buffer\n" +msgstr "błąd podczas szukania zapasowego superbloku - nie udało się memalign bufora\n" -#: .././db/io.c:515 -msgid "nothing to write\n" -msgstr "nie ma nic do zapisania\n" +#: .././repair/sb.c:146 +msgid "found candidate secondary superblock...\n" +msgstr "znaleziono potencjalny zapasowy superblok...\n" -#: .././db/io.c:521 -#, c-format -msgid "incomplete write, block: %lld\n" -msgstr "zapis niekompletny, blok: %lld\n" +#: .././repair/sb.c:158 +msgid "verified secondary superblock...\n" +msgstr "sprawdzono zapasowy superblok...\n" + +#: .././repair/sb.c:163 +msgid "unable to verify superblock, continuing...\n" +msgstr "nie udało się sprawdzić superbloku, kontynuacja...\n" + +#: .././repair/sb.c:482 +msgid "failed to memalign superblock buffer\n" +msgstr "nie udało się wykonać memalign dla bufora superbloku\n" + +#: .././repair/sb.c:489 +msgid "couldn't seek to offset 0 in filesystem\n" +msgstr "nie udało się wykonać seek na offset 0 w systemie plików\n" + +#: .././repair/sb.c:499 +msgid "primary superblock write failed!\n" +msgstr "zapis głównego superbloku nie powiódł się!\n" -#: .././db/io.c:524 +#: .././repair/sb.c:517 #, c-format -msgid "write error: %s\n" -msgstr "błąd zapisu: %s\n" +msgid "error reading superblock %u -- failed to memalign buffer\n" +msgstr "błąd podczas odczytu superbloku %u - nie udało się wykonać memalign dla bufora\n" -#: .././db/io.c:529 +#: .././repair/sb.c:528 #, c-format -msgid "incomplete read, block: %lld\n" -msgstr "odczyt niekompletny, blok: %lld\n" +msgid "error reading superblock %u -- seek to offset % failed\n" +msgstr "błąd podczas odczytu superbloku %u - seek na offset % nie powiódł się\n" -#: .././db/io.c:532 +#: .././repair/sb.c:537 #, c-format -msgid "read error: %s\n" -msgstr "błąd odczytu: %s\n" +msgid "superblock read failed, offset %, size %d, ag %u, rval %d\n" +msgstr "odczyt superbloku nie powiódł się, offset %, rozmiar %d, ag %u, rval %d\n" -#: .././db/io.c:548 -msgid "set_cur no stack element to set\n" -msgstr "set_cur: brak elementu stosu do ustawienia\n" +#: .././repair/sb.c:585 +msgid "couldn't malloc geometry structure\n" +msgstr "nie udało się przydzielić struktury geometrii\n" -#: .././db/io.c:554 -#, c-format -msgid "xfs_db got a bbmap for %lld\n" -msgstr "xfs_db ma bbmap dla %lld\n" +#: .././repair/sb.c:735 +msgid "calloc failed in verify_set_primary_sb\n" +msgstr "calloc nie powiodło się w verify_set_primary_sb\n" -#: .././db/io.c:585 +#: .././repair/sb.c:806 msgid "" -"\n" -" The stack is used to explicitly store your location and data type\n" -" for later return. The 'push' operation stores the current address\n" -" and type on the stack, the 'pop' operation returns you to the\n" -" position and datatype of the top entry on the stack.\n" -"\n" -" The 'stack' allows explicit location saves, see 'ring' for implicit\n" -" position tracking.\n" -"\n" +"Only two AGs detected and they do not match - cannot validate filesystem geometry.\n" +"Use the -o force_geometry option to proceed.\n" msgstr "" -"\n" -" Stos służy do jawnego zapisania pozycji i typu danych w celu późniejszego\n" -" powrotu. Operacja 'push' zapisuje bieżący adres i typ na stosie, a operacja\n" -" 'pop' odtwarza bieżący adres i typ danych z wierzchu stosu.\n" -"\n" -" Stos ('stack') pozwala na jawne zapisywanie pozycji; domyślnie pozycje są\n" -" śledzone poprzez krąg (p. 'ring').\n" -"\n" +"Wykryto tylko dwie AG i nie zgadzają się - nie można sprawdzić poprawności geometrii systemu plików.\n" +"Proszę użyć opcji -o force_geometry, aby kontynuować.\n" -#: .././db/malloc.c:27 -#, c-format -msgid "%s: out of memory\n" -msgstr "%s: brak pamięci\n" +#: .././repair/sb.c:822 +msgid "" +"Only one AG detected - cannot validate filesystem geometry.\n" +"Use the -o force_geometry option to proceed.\n" +msgstr "" +"Wykryto tylko dwie AG - nie można sprawdzić poprawności geometrii systemu plików.\n" +"Proszę użyć opcji -o force_geometry, aby kontynuować.\n" -#: .././db/output.c:30 -msgid "[stop|start ]" -msgstr "[stop|start ]" +#: .././repair/sb.c:837 +msgid "Not enough matching superblocks - cannot proceed.\n" +msgstr "Za mało pasujących superbloków - nie można kontynuować.\n" -#: .././db/output.c:31 -msgid "start or stop logging to a file" -msgstr "rozpoczęcie lub zakończenie logowania do pliku" +#: .././repair/sb.c:852 +msgid "could not read superblock\n" +msgstr "nie udało się odczytać superbloku\n" -#: .././db/output.c:68 +#: .././repair/scan.c:83 .././repair/scan.c:138 #, c-format -msgid "logging to %s\n" -msgstr "logowanie do %s\n" +msgid "can't read btree block %d/%d\n" +msgstr "nie można odczytać bloku b-drzewa %d/%d\n" -#: .././db/output.c:70 .././db/output.c:77 -msgid "no log file\n" -msgstr "brak pliku logu\n" +#: .././repair/scan.c:87 .././repair/scan.c:150 +#, c-format +msgid "btree block %d/%d is suspect, error %d\n" +msgstr "blok b-drzewa %d/%d jest podejrzany, błąd %d\n" -#: .././db/output.c:80 +#: .././repair/scan.c:210 #, c-format -msgid "already logging to %s\n" -msgstr "już ustawiono logowanie do %s\n" +msgid "bad magic # %#x in inode % (%s fork) bmbt block %\n" +msgstr "błędna liczba magiczna %#x w i-węźle % (gałąź %s) blok bmbt %\n" -#: .././db/output.c:84 +#: .././repair/scan.c:216 #, c-format -msgid "can't open %s for writing\n" -msgstr "nie można otworzyć %s do zapisu\n" +msgid "expected level %d got %d in inode %, (%s fork) bmbt block %\n" +msgstr "oczekiwano poziomu %d, a uzyskano %d w i-węźle %, (gałęzi %s) blok bmbt %\n" -#: .././db/output.c:90 -msgid "bad log command, ignored\n" -msgstr "błędne polecenie logowania, zignorowano\n" +#: .././repair/scan.c:226 +#, c-format +msgid "expected owner inode %, got %llu, bmbt block %\n" +msgstr "oczekiwano i-węzła właściciela %, napotkano %llu, blok bmbt %\n" -#: .././db/print.c:41 -msgid "[value]..." -msgstr "[wartość]..." +#: .././repair/scan.c:246 +#, c-format +msgid "" +"bad fwd (right) sibling pointer (saw % parent block says %)\n" +"\tin inode % (%s fork) bmap btree block %\n" +msgstr "" +"błędny wskaźnik w przód (prawy) (widziano %, blok nadrzędny mówi %)\n" +"\tw i-węźle % (gałęzi %s) bloku bmap btree %\n" -#: .././db/print.c:42 -msgid "print field values" -msgstr "wypisanie wartości pól" +#: .././repair/scan.c:256 +#, c-format +msgid "" +"bad back (left) sibling pointer (saw %llu parent block says %)\n" +"\tin inode % (%s fork) bmap btree block %\n" +msgstr "" +"błędny wskaźnik wstecz (lewy) (widziano %llu, blok nadrzędny mówi %)\n" +"\tw i-węźle % (gałęzi %s) bloku bmap btree %\n" -#: .././db/print.c:79 +#: .././repair/scan.c:271 #, c-format -msgid "no print function for type %s\n" -msgstr "brak funkcji wypisującej dla typu %s\n" +msgid "" +"bad back (left) sibling pointer (saw %llu should be NULL (0))\n" +"\tin inode % (%s fork) bmap btree block %\n" +msgstr "" +"błędny wskaźnik wstecz (lewy) (widziano %llu, powinien być NULL (0))\n" +"\tw i-węźle % (gałęzi %s) bloku bmap btree %\n" -#: .././db/print.c:153 -msgid "(empty)\n" -msgstr "(puste)\n" +#: .././repair/scan.c:312 +#, c-format +msgid "inode 0x%bmap block 0x% claimed, state is %d\n" +msgstr "i-węzeł 0x% blok bmap 0x% przypisany, stan to %d\n" -#: .././db/print.c:215 -msgid "(empty)" -msgstr "(puste)" +#: .././repair/scan.c:319 +#, c-format +msgid "inode 0x% bmap block 0x% claimed, state is %d\n" +msgstr "i-węzeł 0x% blok bmap 0x% przypisany, stan to %d\n" -#: .././db/print.c:275 -msgid "no arguments allowed\n" -msgstr "argumenty nie są dozwolone\n" +#: .././repair/scan.c:334 +#, c-format +msgid "bad state %d, inode % bmap block 0x%\n" +msgstr "błędny stan %d, i-węzeł % blok bmap 0x%\n" -#: .././db/quit.c:27 -msgid "exit xfs_db" -msgstr "zakończenie xfs_db" +#: .././repair/scan.c:361 .././repair/scan.c:412 +#, c-format +msgid "inode % bad # of bmap records (%u, min - %u, max - %u)\n" +msgstr "błędna liczba rekordów bmap w i-węźle % (%u, minimum - %u, maksimum - %u)\n" -#: .././db/type.c:50 -msgid "[newtype]" -msgstr "[nowy-typ]" +#: .././repair/scan.c:391 +#, c-format +msgid "out-of-order bmap key (file offset) in inode %, %s fork, fsbno %\n" +msgstr "uszkodzony klucz bmap (offset pliku) w i-węźle %, gałęzi %s, fsbno %\n" -#: .././db/type.c:51 -msgid "set/show current data type" -msgstr "ustawienie/wyświetlenie bieżącego typu danych" +#: .././repair/scan.c:457 +#, c-format +msgid "" +"correcting bt key (was %llu, now %) in inode %\n" +"\t\t%s fork, btree block %\n" +msgstr "" +"poprawiono klucz bt (było %llu, jest %) w i-węźle %\n" +"\t\tgałąź %s, blok b-drzewa %\n" -#: .././db/type.c:104 +#: .././repair/scan.c:469 #, c-format -msgid "current type is \"%s\"\n" -msgstr "bieżący typ to \"%s\"\n" +msgid "" +"bad btree key (is %llu, should be %) in inode %\n" +"\t\t%s fork, btree block %\n" +msgstr "" +"błędny klucz b-drzewa (jest %llu, powinno być %) w i-węźle %\n" +"\t\tgałąź %s, blok b-drzewa %\n" -#: .././db/type.c:106 +#: .././repair/scan.c:487 +#, c-format msgid "" -"\n" -" supported types are:\n" -" " +"bad fwd (right) sibling pointer (saw % should be NULLDFSBNO)\n" +"\tin inode % (%s fork) bmap btree block %\n" msgstr "" -"\n" -" obsługiwane typy to:\n" -" " +"błędny wskaźnik w przód (prawy) (widziano %, powinien być NULLDFSBNO)\n" +"\tw i-węźle % (gałęzi %s) bloku bmap btree %\n" -#: .././db/type.c:121 +#: .././repair/scan.c:545 #, c-format -msgid "no such type %s\n" -msgstr "nie ma typu %s\n" +msgid "bad magic # %#x in bt%s block %d/%d\n" +msgstr "błędna liczba magiczna %#x w bloku bt%s %d/%d\n" -#: .././db/type.c:124 -msgid "no current object\n" -msgstr "brak bieżącego obiektu\n" +#: .././repair/scan.c:563 +#, c-format +msgid "expected level %d got %d in bt%s block %d/%d\n" +msgstr "oczekiwano poziomu %d, a uzyskano %d w bloku bt%s %d/%d\n" -#: .././db/write.c:41 -msgid "[field or value]..." -msgstr "[pole lub wartość]..." +#: .././repair/scan.c:577 +#, c-format +msgid "%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n" +msgstr "blok b-drzewa wolnego miejsca %s przypisany (stan %d), agno %d, bno %d, podejrzany %d\n" -#: .././db/write.c:42 -msgid "write value to disk" -msgstr "zapis wartości na dysk" +#: .././repair/scan.c:597 .././repair/scan.c:698 +#, c-format +msgid "bad btree nrecs (%u, min=%u, max=%u) in bt%s block %u/%u\n" +msgstr "błędna liczba rekordów b-drzewa (%u, min=%u, max=%u) w bt%s, blok %u/%u\n" -#: .././db/write.c:58 -msgid "" -"\n" -" The 'write' command takes on different personalities depending on the\n" -" type of object being worked with.\n" -"\n" -" Write has 3 modes:\n" -" 'struct mode' - is active anytime you're looking at a filesystem object\n" -" which contains individual fields (ex: an inode).\n" -" 'data mode' - is active anytime you set a disk address directly or set\n" -" the type to 'data'.\n" -" 'string mode' - only used for writing symlink blocks.\n" -"\n" -" Examples:\n" -" Struct mode: 'write core.uid 23' - set an inode uid field to 23.\n" -" 'write fname \"hello\\000\"' - write superblock fname.\n" -" (note: in struct mode strings are not null terminated)\n" -" 'write fname #6669736800' - write superblock fname with hex.\n" -" 'write uuid 00112233-4455-6677-8899-aabbccddeeff'\n" -" - write superblock uuid.\n" -" Data mode: 'write fill 0xff' - fill the entire block with 0xff's\n" -" 'write lshift 3' - shift the block 3 bytes to the left\n" -" 'write sequence 1 5' - write a cycle of number [1-5] through\n" -" the entire block.\n" -" String mode: 'write \"This_is_a_filename\" - write null terminated string.\n" -"\n" -" In data mode type 'write' by itself for a list of specific commands.\n" -"\n" -msgstr "" -"\n" -" Polecenie 'write' ma różne osobowości w zależności od rodzaju obiektu,\n" -" na jakim pracuje.\n" -"\n" -" Zapis ma trzy tryby:\n" -" 'struct' (strukturalny) - aktywny w przypadku oglądania obiektu systemu\n" -" plików zawierającego poszczególne pola (np. i-węzeł).\n" -" 'data' (danych) - aktywny w przypadku bezpośredniego ustawienia adresu\n" -" na dysku lub ustawienia typu na 'data'.\n" -" 'string' (znakowy) - używany tylko przy zapisie bloków dowiązań\n" -" symbolicznych.\n" -"\n" -" Przykłady:\n" -" Tryb strukturalny: 'write core.uid 23' - ustawienie pola uid i-węzła na 23\n" -" 'write fname \"hello\\000\"' - zapis nazwy pliku sb\n" -" (uwaga: w trybie strukturalnym łańcuchy nie są zakańczane)\n" -" 'write fname #6669736800' - zapis nazwy pliku sb w hex.\n" -" 'write uuid 00112233-4455-6677-8899-aabbccddeeff'\n" -" - zapis UUID-a superbloku.\n" -" Tryb danych: 'write fill 0xff' - wypełnienie bloku bajtam 0xff\n" -" 'write lshift 3' - przesunięcie bloku o 3 bajty w lewo\n" -" 'write sequence 1 5' zapis cyklicznie liczb [1-5] przez\n" -" cały blok.\n" -" Tryb znakowy: 'write \"To_jest_nazwa_pliku\" - zapis łańcucha\n" -" zakończonego znakiem NUL.\n" -"\n" -" W trybie danych samo 'write' wypisze listę bardziej specyficznych poleceń.\n" -"\n" +#: .././repair/scan.c:615 +#, c-format +msgid "invalid start block %u in record %u of %s btree block %u/%u\n" +msgstr "błędny blok początkowy %u w rekordzie %u bloku b-drzewa %s %u/%u\n" -#: .././db/write.c:95 +#: .././repair/scan.c:621 #, c-format -msgid "%s started in read only mode, writing disabled\n" -msgstr "%s uruchomiono w trybie tylko do odczytu, zapis wyłączony\n" +msgid "invalid length %u in record %u of %s btree block %u/%u\n" +msgstr "błędna długość %u w rekordzie %u bloku b-drzewa %s %u/%u\n" -#: .././db/write.c:107 +#: .././repair/scan.c:668 #, c-format -msgid "no handler function for type %s, write unsupported.\n" -msgstr "brak funkcji obsługującej dla typu %s, zapis nie obsługiwany.\n" +msgid "block (%d,%d-%d) multiply claimed by %s space tree, state - %d\n" +msgstr "blok (%d,%d-%d) wielokrotnie przypisany do drzewa miejsca %s, stan - %d\n" -#: .././db/write.c:167 .././db/write.c:196 .././db/write.c:226 -#: .././db/write.c:258 .././db/write.c:293 .././db/write.c:342 -#: .././db/write.c:371 +#: .././repair/scan.c:775 #, c-format -msgid "length (%d) too large for data block size (%d)" -msgstr "długość (%d) zbyt duża dla rozmiaru bloku danych (%d)" +msgid "badly aligned inode rec (starting inode = %)\n" +msgstr "błędnie wyrównany rekord i-węzła (początkowy i-węzeł = %)\n" -#: .././db/write.c:559 -msgid "usage: write fieldname value\n" -msgstr "składnia: write nazwa-pola wartość\n" +#: .././repair/scan.c:791 +#, c-format +msgid "bad starting inode # (% (0x%x 0x%x)) in ino rec, skipping rec\n" +msgstr "błędny numer początkowego i-węzła (% (0x%x 0x%x)) w rekordzie i-węzła, pominięto rekord\n" -#: .././db/write.c:565 +#: .././repair/scan.c:799 #, c-format -msgid "unable to parse '%s'.\n" -msgstr "nie można przeanalizować '%s'.\n" +msgid "bad ending inode # (% (0x%x 0x%zx)) in ino rec, skipping rec\n" +msgstr "błędny numer końcowego i-węzła (% (0x%x 0x%zx)) w rekordzie i-węzła, pominięto rekord\n" -#: .././db/write.c:579 -msgid "parsing error\n" -msgstr "błąd składni\n" +#: .././repair/scan.c:824 +#, c-format +msgid "inode chunk claims used block, inobt block - agno %d, bno %d, inopb %d\n" +msgstr "część i-węzła odwołuje się do używanego bloku, blok inobt - agno %d, bno %d, inopb %d\n" -#: .././db/write.c:598 +#: .././repair/scan.c:846 #, c-format -msgid "unable to convert value '%s'.\n" -msgstr "nie można przekonwertować wartości '%s'.\n" +msgid "inode rec for ino % (%d/%d) overlaps existing rec (start %d/%d)\n" +msgstr "rekord i-węzła dla i-węzła % (%d/%d) nachodzi na istniejący rekord (początek %d/%d)\n" -#: .././db/write.c:621 -msgid "usage (in string mode): write \"string...\"\n" -msgstr "składnia (w trybie znakowym): write \"łańcuch...\"\n" +#: .././repair/scan.c:893 +#, c-format +msgid "ir_freecount/free mismatch, inode chunk %d/%u, freecount %d nfree %d\n" +msgstr "niezgodność ir_freecount/free, porcja i-węzłów %d/%u, freecount %d nfree %d\n" -#: .././db/write.c:663 -msgid "write: invalid subcommand\n" -msgstr "write: błędne podpolecenie\n" +#: .././repair/scan.c:934 +#, c-format +msgid "badly aligned finobt inode rec (starting inode = %)\n" +msgstr "błędnie wyrównany rekord i-węzła finobt (początkowy i-węzeł = %)\n" -#: .././db/write.c:668 +#: .././repair/scan.c:948 #, c-format -msgid "write %s: invalid number of arguments\n" -msgstr "write %s: błędna liczba argumentów\n" +msgid "bad starting inode # (% (0x%x 0x%x)) in finobt rec, skipping rec\n" +msgstr "błędny numer początkowego i-węzła (% (0x%x 0x%x)) w rekordzie finobt, pominięto rekord\n" -#: .././db/write.c:692 -msgid "usage: write (in data mode)\n" -msgstr "składnia: write (w trybie danych)\n" +#: .././repair/scan.c:956 +#, c-format +msgid "bad ending inode # (% (0x%x 0x%zx)) in finobt rec, skipping rec\n" +msgstr "błędny numer końcowego i-węzła (% (0x%x 0x%zx)) w rekordzie finobt, pominięto rekord\n" -#: .././db/frag.c:173 +#: .././repair/scan.c:981 #, c-format -msgid "actual %llu, ideal %llu, fragmentation factor %.2f%%\n" -msgstr "obecnie %llu, idealnie %llu, współczynnik fragmentacji %.2f%%\n" +msgid "inode chunk claims untracked block, finobt block - agno %d, bno %d, inopb %d\n" +msgstr "część i-węzła odwołuje się do nieśledzonego bloku, blok finobt - agno %d, bno %d, inopb %d\n" -#: .././db/frag.c:214 -msgid "bad option for frag command\n" -msgstr "błędna opcja dla polecenia frag\n" +#: .././repair/scan.c:988 +#, c-format +msgid "inode chunk claims used block, finobt block - agno %d, bno %d, inopb %d\n" +msgstr "część i-węzła odwołuje się do używanego bloku, blok finobt - agno %d, bno %d, inopb %d\n" -#: .././db/frag.c:349 +#: .././repair/scan.c:1010 #, c-format -msgid "inode %lld actual %lld ideal %lld\n" -msgstr "i-węzeł %lld obecnie %lld idealnie %lld\n" +msgid "finobt rec for ino % (%d/%u) does not match existing rec (%d/%d)\n" +msgstr "rekord finobt dla i-węzła % (%d/%u) nie pasuje do istniejącego rekordu (%d/%d)\n" -#: .././db/frag.c:443 .././db/frag.c:453 +#: .././repair/scan.c:1038 #, c-format -msgid "invalid numrecs (%u) in %s block\n" -msgstr "błędne numrecs (%u) w bloku %s\n" +msgid "undiscovered finobt record, ino % (%d/%u)\n" +msgstr "nie rozpoznany rekord finobt, i-węzeł % (%d/%u)\n" -#: .././db/metadump.c:55 -msgid "[-e] [-g] [-m max_extent] [-w] [-o] filename" -msgstr "[-e] [-g] [-m max_extent] [-w] [-o] nazwa-pliku" +#: .././repair/scan.c:1092 +#, c-format +msgid "finobt ir_freecount/free mismatch, inode chunk %d/%u, freecount %d nfree %d\n" +msgstr "niezgodność finobt ir_freecount/free, porcja i-węzłów %d/%u, freecount %d nfree %d\n" -#: .././db/metadump.c:56 -msgid "dump metadata to a file" -msgstr "zrzut metadanych do pliku" +#: .././repair/scan.c:1098 +#, c-format +msgid "finobt record with no free inodes, inode chunk %d/%u\n" +msgstr "rekord finobt bez wolnych i-węzłów, porcja i-węzłów %d/%u\n" -#: .././db/metadump.c:86 +#: .././repair/scan.c:1142 #, c-format -msgid "" -"\n" -" The 'metadump' command dumps the known metadata to a compact file suitable\n" -" for compressing and sending to an XFS maintainer for corruption analysis \n" -" or xfs_repair failures.\n" -"\n" -" Options:\n" -" -e -- Ignore read errors and keep going\n" -" -g -- Display dump progress\n" -" -m -- Specify max extent size in blocks to copy (default = %d blocks)\n" -" -o -- Don't obfuscate names and extended attributes\n" -" -w -- Show warnings of bad metadata information\n" -"\n" -msgstr "" -"\n" -" Polecenie 'metadump' zrzuca znane metadane do zwięzłego pliku nadającego się\n" -" do skompresowania i wysłania prowadzącym projekt XFS w celu analizy uszkodzeń\n" -" lub błędów xfs_repair.\n" -"\n" -" Opcje:\n" -" -e - ignorowanie błędów odczytu i kontynuowanie\n" -" -g - wyświetlanie postępu\n" -" -m - określenie maksymalnego rozmiaru ekstentu (w blokach) do skopiowania\n" -" (domyślnie %d bloków)\n" -" -o - bez zaciemniania nazw i rozszerzonych atrybutów\n" -" -w - wyświetlanie ostrzeżeń o błędnych metadanych\n" -"\n" +msgid "bad magic # %#x in inobt block %d/%d\n" +msgstr "błędna liczba magiczna %#x w bloku inobt %d/%d\n" -#: .././db/freesp.c:106 +#: .././repair/scan.c:1150 #, c-format -msgid "total free extents %lld\n" -msgstr "razem wolnych ekstentów: %lld\n" +msgid "expected level %d got %d in inobt block %d/%d\n" +msgstr "oczekiwano poziomu %d, a uzyskano %d w bloku inobt %d/%d\n" -#: .././db/freesp.c:107 +#: .././repair/scan.c:1172 #, c-format -msgid "total free blocks %lld\n" -msgstr "razem wolnych bloków: %lld\n" +msgid "inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n" +msgstr "blok b-drzewa i-węzłów przypisany (stan %d), agno %d, bno %d, podejrzany %d\n" -#: .././db/freesp.c:108 +#: .././repair/scan.c:1195 #, c-format -msgid "average free extent size %g\n" -msgstr "średni rozmiar wolnego ekstentu: %g\n" +msgid "dubious inode btree block header %d/%d\n" +msgstr "wątpliwy nagłówek bloku b-drzewa i-węzłów %d/%d\n" -#: .././db/freesp.c:199 -msgid "freesp arguments: [-bcds] [-a agno] [-e binsize] [-h h1]... [-m binmult]\n" -msgstr "argumenty freesp: [-bcds] [-a agno] [-e binsize] [-h h1]... [-m binmult]\n" +#: .././repair/scan.c:1306 +#, c-format +msgid "can't read agfl block for ag %d\n" +msgstr "nie można odczytać bloku agfl dla ag %d\n" -#: .././db/freesp.c:406 -msgid "from" -msgstr "od" +#: .././repair/scan.c:1310 +#, c-format +msgid "agfl has bad CRC for ag %d\n" +msgstr "agfl ma błędną sumę kontrolną dla ag %d\n" -#: .././db/freesp.c:406 -msgid "to" -msgstr "do" +#: .././repair/scan.c:1331 +#, c-format +msgid "bad agbno %u in agfl, agno %d\n" +msgstr "błędne agbno %u w agfl, agno %d\n" -#: .././db/freesp.c:406 -msgid "pct" -msgstr "proc." +#: .././repair/scan.c:1340 +#, c-format +msgid "freeblk count %d != flcount %d in ag %d\n" +msgstr "liczba freeblk %d != flcount %d w ag %d\n" -#: .././db/inode.c:385 +#: .././repair/scan.c:1366 #, c-format -msgid "bad value for inode number %s\n" -msgstr "błędna wartość numeru i-węzła %s\n" +msgid "bad agbno %u for btbno root, agno %d\n" +msgstr "błędne agbno %u dla głównego btbno, agno %d\n" -#: .././db/inode.c:392 +#: .././repair/scan.c:1378 #, c-format -msgid "current inode number is %lld\n" -msgstr "numer bieżącego i-węzła to %lld\n" +msgid "bad agbno %u for btbcnt root, agno %d\n" +msgstr "błędne agbno %u dla głównego btbcnt, agno %d\n" -#: .././db/inode.c:614 +#: .././repair/scan.c:1394 #, c-format -msgid "bad inode number %lld\n" -msgstr "błędny numer i-węzła %lld\n" +msgid "agf_btreeblks %u, counted % in ag %u\n" +msgstr "agf_btreeblks %u, naliczono % w ag %u\n" -#: .././db/sb.c:43 -msgid "set current address to sb header" -msgstr "ustawienie bieżącego adresu na nagłówek sb" +#: .././repair/scan.c:1417 +#, c-format +msgid "bad agbno %u for inobt root, agno %d\n" +msgstr "błędne agbno %u dla głównego inobt, agno %d\n" -#: .././db/sb.c:45 -msgid "[uuid]" -msgstr "[uuid]" +#: .././repair/scan.c:1430 +#, c-format +msgid "bad agbno %u for finobt root, agno %d\n" +msgstr "błędne agbno %u dla głównego finobt, agno %d\n" -#: .././db/sb.c:46 -msgid "write/print FS uuid" -msgstr "zapisanie/wypisanie uuida FS" +#: .././repair/scan.c:1447 +#, c-format +msgid "agi_freecount %u, counted %u in ag %u finobt\n" +msgstr "agi_freecount %u, naliczono %u w ag %u finobt\n" -#: .././db/sb.c:48 -msgid "[label]" -msgstr "[etykieta]" +#: .././repair/scan.c:1457 +#, c-format +msgid "agi unlinked bucket %d is %u in ag %u (inode=%)\n" +msgstr "niedowiązany kubełek agi %d to %u w ag %u (i-węzeł=%)\n" -#: .././db/sb.c:49 -msgid "write/print FS label" -msgstr "zapisanie/wypisanie etykiety FS" +#: .././repair/scan.c:1488 +msgid "can't allocate memory for superblock\n" +msgstr "nie można przydzielić pamięci dla superbloku\n" -#: .././db/sb.c:51 -msgid "[feature | [vnum fnum]]" -msgstr "[cecha | [vnum fnum]]" +#: .././repair/scan.c:1495 +msgid "root superblock" +msgstr "główny superblok" + +#: .././repair/scan.c:1505 +msgid "agf block" +msgstr "blok agf" + +#: .././repair/scan.c:1514 +msgid "agi block" +msgstr "blok agi" -#: .././db/sb.c:52 -msgid "set feature bit(s) in the sb version field" -msgstr "ustawienie bitów cech w polu wersji sb" +#: .././repair/scan.c:1535 +#, c-format +msgid "reset bad sb for ag %d\n" +msgstr "przestawiono błędny superblok dla ag %d\n" -#: .././db/sb.c:124 -msgid "" -"\n" -" set allocation group superblock\n" -"\n" -" Example:\n" -"\n" -" 'sb 7' - set location to 7th allocation group superblock, set type to 'sb'\n" -"\n" -" Located in the first sector of each allocation group, the superblock\n" -" contains the base information for the filesystem.\n" -" The superblock in allocation group 0 is the primary. The copies in the\n" -" remaining allocation groups only serve as backup for filesystem recovery.\n" -" The icount/ifree/fdblocks/frextents are only updated in superblock 0.\n" -"\n" -msgstr "" -"\n" -" ustawienie superbloku grupy alokacji\n" -"\n" -" Przykład:\n" -"\n" -" 'sb 7' - ustawienie pozycji na superblok 7. grupy alokacji i typu na 'sb'\n" -"\n" -" Położony w 1. sektorze każdej grupy alokacji superblok zawiera podstawowe\n" -" informacje o systemie plików.\n" -" Superblok w grupie alokacji 0 jest główny. Kopie w pozostałych grupach\n" -" alokacji służą tylko jako kopie zapasowe do odtwarzania systemu plików.\n" -" Liczby icount/ifree/fdblocks/frextents są uaktualniane tylko w superbloku 0.\n" -"\n" +#: .././repair/scan.c:1538 +#, c-format +msgid "would reset bad sb for ag %d\n" +msgstr "błędny superblok dla ag %d zostałby przestawiony\n" -#: .././db/sb.c:183 +#: .././repair/scan.c:1543 #, c-format -msgid "can't read superblock for AG %u\n" -msgstr "nie można odczytać superbloku dla AG %u\n" +msgid "reset bad agf for ag %d\n" +msgstr "przestawiono błędne agf dla ag %d\n" -#: .././db/sb.c:191 +#: .././repair/scan.c:1546 #, c-format -msgid "bad sb magic # %#x in AG %u\n" -msgstr "błędna liczba magiczna superbloku %#x w AG %u\n" +msgid "would reset bad agf for ag %d\n" +msgstr "błędne agf dla ag %d zostałoby przestawione\n" -#: .././db/sb.c:196 +#: .././repair/scan.c:1551 #, c-format -msgid "bad sb version # %#x in AG %u\n" -msgstr "błędny numer wersji superbloku %#x w AG %u\n" +msgid "reset bad agi for ag %d\n" +msgstr "przestawiono błędne agi dla ag %d\n" -#: .././db/sb.c:218 -msgid "aborting - external log specified for FS with an internal log\n" -msgstr "przerwano - podano log zewnętrzny dla systemu plików z logiem wewnętrznym\n" +#: .././repair/scan.c:1554 +#, c-format +msgid "would reset bad agi for ag %d\n" +msgstr "błędna agi dla ag %d zostałoby przestawione\n" -#: .././db/sb.c:224 -msgid "aborting - no external log specified for FS with an external log\n" -msgstr "przerwano - nie podano logu zewnętrznego dla systemu plików z logiem zewnętrznym\n" +#: .././repair/scan.c:1559 +#, c-format +msgid "bad uncorrected agheader %d, skipping ag...\n" +msgstr "błędny nie poprawiony agheader %d, pominięto ag...\n" -#: .././db/sb.c:242 -msgid "ERROR: cannot find log head/tail, run xfs_repair\n" -msgstr "BŁĄD: nie odnaleziono początku/końca logu, proszę uruchomić xfs_repair\n" +#: .././repair/scan.c:1623 +#, c-format +msgid "can't get %s for ag %d\n" +msgstr "nie można uzyskać %s dla ag %d\n" + +#: .././repair/scan.c:1642 +msgid "no memory for ag header counts\n" +msgstr "brak pamięci na liczniki nagłówków ag\n" + +#: .././repair/scan.c:1667 +#, c-format +msgid "sb_icount %, counted %\n" +msgstr "sb_icount %, naliczono %\n" + +#: .././repair/scan.c:1672 +#, c-format +msgid "sb_ifree %, counted %\n" +msgstr "sb_ifree %, naliczono %\n" + +#: .././repair/scan.c:1677 +#, c-format +msgid "sb_fdblocks %, counted %\n" +msgstr "sb_fdblocks %, naliczono %\n" + +#: .././repair/threads.c:90 +#, c-format +msgid "cannot create worker threads, error = [%d] %s\n" +msgstr "nie można utworzyć wątków pracujących, błąd: [%d] %s\n" + +#: .././repair/threads.c:108 +#, c-format +msgid "cannot allocate worker item, error = [%d] %s\n" +msgstr "nie można przydzielić elementu pracującego, błąd: [%d] %s\n" -#: .././db/sb.c:247 +#: .././repair/versions.c:70 #, c-format +msgid "bogus quota flags 0x%x set in superblock" +msgstr "niepoprawne flagi limitów 0x%x ustawione w superbloku" + +#: .././repair/versions.c:76 +msgid ", bogus flags will be cleared\n" +msgstr ", błędne flagi zostaną wyczyszczone\n" + +#: .././repair/versions.c:78 +msgid ", bogus flags would be cleared\n" +msgstr ", błędne flagi zostałyby wyczyszczone\n" + +#: .././repair/versions.c:132 +msgid "This filesystem has uninitialized extent flags.\n" +msgstr "Ten system plików ma niezainicjowane flagi ekstentów.\n" + +#: .././repair/versions.c:140 +msgid "This filesystem is marked shared.\n" +msgstr "Ten system plików jest oznaczony jako współdzielony.\n" + +#: .././repair/versions.c:146 msgid "" -"ERROR: The filesystem has valuable metadata changes in a log which needs to\n" -"be replayed. Mount the filesystem to replay the log, and unmount it before\n" -"re-running %s. If you are unable to mount the filesystem, then use\n" -"the xfs_repair -L option to destroy the log and attempt a repair.\n" -"Note that destroying the log may cause corruption -- please attempt a mount\n" -"of the filesystem before doing this.\n" +"This filesystem uses feature(s) not yet supported in this release.\n" +"Please run a more recent version of xfs_repair.\n" msgstr "" -"BŁĄD: system plików zawiera wartościowe zmiany metadanych w logu, który\n" -"musi być odtworzony. Należy podmontować system plików, aby odtworzyć log,\n" -"a następnie odmontować go przed ponownym uruchomieniem %s. Jeśli\n" -"systemu plików nie da się podmontować, można użyć opcji -L, aby zniszczyć\n" -"log i spróbować naprawić system plików.\n" -"Należy zauważyć, że zniszczenie logu może spowodować uszkodzenia danych -\n" -"proszę najpierw spróbować podmontować system plików.\n" +"Ten system plików używa możliwości jeszcze nie obsługiwanych w tym wydaniu.\n" +"Proszę uruchomić nowszą wersję xfs_repair.\n" -#: .././db/sb.c:264 -msgid "Clearing log and setting UUID\n" -msgstr "Czyszczenei logu i ustawianie UUID-a\n" +#: .././repair/versions.c:152 +#, c-format +msgid "WARNING: unknown superblock version %d\n" +msgstr "UWAGA: nieznana wersja superbloku %d\n" -#: .././db/sb.c:273 -msgid "ERROR: cannot clear the log\n" -msgstr "BŁĄD: nie można wyczyścić logu\n" +#: .././repair/versions.c:155 +msgid "This filesystem contains features not understood by this program.\n" +msgstr "Ten system plików zawiera cechę nie rozumianą przez ten program.\n" -#: .././db/sb.c:284 +#: .././repair/versions.c:163 msgid "" -"\n" -" write/print FS uuid\n" -"\n" -" Example:\n" -"\n" -" 'uuid' - print UUID\n" -" 'uuid 01234567-0123-0123-0123-0123456789ab' - write UUID\n" -" 'uuid generate' - generate and write\n" -" 'uuid rewrite' - copy UUID from SB 0\n" -"\n" -"The print function checks the UUID in each SB and will warn if the UUIDs\n" -"differ between AGs (the log is not checked). The write commands will\n" -"set the uuid in all AGs to either a specified value, a newly generated\n" -"value or the value found in the first superblock (SB 0) respectively.\n" -"As a side effect of writing the UUID, the log is cleared (which is fine\n" -"on a CLEANLY unmounted FS).\n" -"\n" +"WARNING: you have disallowed superblock-feature-bits-allowed\n" +"\tbut this superblock has feature bits. The superblock\n" +"\twill be downgraded. This may cause loss of filesystem meta-data\n" msgstr "" +"UWAGA: zabroniono superblock-feature-bits-allowed, ale ten\n" +"\tsuperblok ma ustawione bity cech. Superblok zostanie zdegradowany.\n" +"\tMoże to spowodować utratę metadanych systemu plików.\n" + +#: .././repair/versions.c:168 +msgid "" +"WARNING: you have disallowed superblock-feature-bits-allowed\n" +"\tbut this superblock has feature bits. The superblock\n" +"\twould be downgraded. This might cause loss of filesystem\n" +"\tmeta-data.\n" +msgstr "" +"UWAGA: zabroniono superblock-feature-bits-allowed, ale ten\n" +"\tsuperblok ma ustawione bity cech. Superblok zostałby zdegradowany.\n" +"\tMogłoby to spowodować utratę metadanych systemu plików.\n" + +#: .././repair/versions.c:182 +msgid "" +"WARNING: you have disallowed attributes but this filesystem\n" +"\thas attributes. The filesystem will be downgraded and\n" +"\tall attributes will be removed.\n" +msgstr "" +"UWAGA: zabroniono używania atrybutów, ale ten system plików zawiera\n" +"\tatrybuty. System plików zostanie zdegradowany, a wszystkie\n" +"\tatrybuty usunięte.\n" + +#: .././repair/versions.c:187 +msgid "" +"WARNING: you have disallowed attributes but this filesystem\n" +"\thas attributes. The filesystem would be downgraded and\n" +"\tall attributes would be removed.\n" +msgstr "" +"UWAGA: zabroniono używania atrybutów, ale ten system plików zawiera\n" +"\tatrybuty. System plików zostałby zdegradowany, a wszystkie\n" +"\tatrybuty usunięte.\n" + +#: .././repair/versions.c:200 +msgid "" +"WARNING: you have disallowed attr2 attributes but this filesystem\n" +"\thas attributes. The filesystem will be downgraded and\n" +"\tall attr2 attributes will be removed.\n" +msgstr "" +"UWAGA: zabroniono używania atrybutów attr2, ale ten system plików\n" +"\tzawiera atrybuty. System plików zostanie zdegradowany, a wszystkie\n" +"\tatrybuty attr2 usunięte.\n" + +#: .././repair/versions.c:205 +msgid "" +"WARNING: you have disallowed attr2 attributes but this filesystem\n" +"\thas attributes. The filesystem would be downgraded and\n" +"\tall attr2 attributes would be removed.\n" +msgstr "" +"UWAGA: zabroniono używania atrybutów attr2, ale ten system plików\n" +"\tzawiera atrybuty. System plików zostałby zdegradowany, a wszystkie\n" +"\tatrybuty attr2 usunięte.\n" + +#: .././repair/versions.c:218 +msgid "" +"WARNING: you have disallowed version 2 inodes but this filesystem\n" +"\thas version 2 inodes. The filesystem will be downgraded and\n" +"\tall version 2 inodes will be converted to version 1 inodes.\n" +"\tThis may cause some hard links to files to be destroyed\n" +msgstr "" +"UWAGA: zabroniono używania i-węzłów w wersji 2, ale ten system plików\n" +"\tzawiera i-węzły w wersji 2. System plików zostanie zdegradowany,\n" +"\ta wszystkie i-węzły w wersji 2 zostaną przekonwertowane do wersji 1.\n" +"\tMoże to spowodować zniszczenie niektórych twardych dowiązań do\n" +"\tplików.\n" + +#: .././repair/versions.c:224 +msgid "" +"WARNING: you have disallowed version 2 inodes but this filesystem\n" +"\thas version 2 inodes. The filesystem would be downgraded and\n" +"\tall version 2 inodes would be converted to version 1 inodes.\n" +"\tThis might cause some hard links to files to be destroyed\n" +msgstr "" +"UWAGA: zabroniono używania i-węzłów w wersji 2, ale ten system plików\n" +"\tzawiera i-węzły w wersji 2. System plików zostałby zdegradowany,\n" +"\ta wszystkie i-węzły w wersji 2 zostałyby przekonwertowane do\n" +"\twersji 1. Mogłoby to spowodować zniszczenie niektórych twardych\n" +"\tdowiązań do plików.\n" + +#: .././repair/versions.c:238 +msgid "" +"WARNING: you have disallowed quotas but this filesystem\n" +"\thas quotas. The filesystem will be downgraded and\n" +"\tall quota information will be removed.\n" +msgstr "" +"UWAGA: zabroniono używania limitów (quot), ale ten system plików\n" +"\tzawiera limity. System plików zostanie zdegradowany, a wszystkie\n" +"\tinformacje o limitach usunięte.\n" + +#: .././repair/versions.c:243 +msgid "" +"WARNING: you have disallowed quotas but this filesystem\n" +"\thas quotas. The filesystem would be downgraded and\n" +"\tall quota information would be removed.\n" +msgstr "" +"UWAGA: zabroniono używania limitów (quot), ale ten system plików\n" +"\tzawiera limity. System plików zostałby zdegradowany, a wszystkie\n" +"\tinformacje o limitach usunięte.\n" + +#: .././repair/versions.c:271 +msgid "" +"WARNING: you have disallowed aligned inodes but this filesystem\n" +"\thas aligned inodes. The filesystem will be downgraded.\n" +"\tThis will permanently degrade the performance of this filesystem.\n" +msgstr "" +"UWAGA: zabroniono używania wyrównanych i-węzłów, ale ten system plików\n" +"\tzawiera wyrównane i-węzły. System plików zostanie zdegradowany.\n" +"\tTrwale zdegraduje to wydajność tego systemu plików.\n" + +#: .././repair/versions.c:276 +msgid "" +"WARNING: you have disallowed aligned inodes but this filesystem\n" +"\thas aligned inodes. The filesystem would be downgraded.\n" +"\tThis would permanently degrade the performance of this filesystem.\n" +msgstr "" +"UWAGA: zabroniono używania wyrównanych i-węzłów, ale ten system plików\n" +"\tzawiera wyrównane i-węzły. System plików zostałby zdegradowany.\n" +"\tTrwale zdegradowałoby to wydajność tego systemu plików.\n" + +#: .././repair/xfs_repair.c:81 +#, c-format +msgid "" +"Usage: %s [options] device\n" "\n" -" zapisanie/wypisanie uuida systemu plików\n" -"\n" -"Przykład:\n" -"\n" -" 'uuid' - wypisanie UUID-a\n" -" 'uuid 01234567-0123-0123-0123-0123456789ab' - zapisanie UUID-a\n" -" 'uuid generate' - wygenerowanie i zapisanie\n" -" 'uuid rewrite' - skopiowanie UUID-a z sb 0\n" -"\n" -"Funkcja wypisująca sprawdza UUID w każdym superbloku i ostrzega, jeśli UUID-y\n" -"się różnią między AG (log nie jest sprawdzany). Polecenia zapisu ustawiają\n" -"UUID we wszystkich AG odpowiednio na określoną wartość, nowo wygenerowaną\n" -"wartość lub wartość znalezioną w pierwszym superbloku (SB 0).\n" -"Jako efekt uboczny zapisu UUID-a czyszczony jest log (co nie jest problemem\n" -"przy CZYSTO odmontowanym systemie plików).\n" +"Options:\n" +" -f The device is a file\n" +" -L Force log zeroing. Do this as a last resort.\n" +" -l logdev Specifies the device where the external log resides.\n" +" -m maxmem Maximum amount of memory to be used in megabytes.\n" +" -n No modify mode, just checks the filesystem for damage.\n" +" -P Disables prefetching.\n" +" -r rtdev Specifies the device where the realtime section resides.\n" +" -v Verbose output.\n" +" -c subopts Change filesystem parameters - use xfs_admin.\n" +" -o subopts Override default behaviour, refer to man page.\n" +" -t interval Reporting interval in seconds.\n" +" -d Repair dangerously.\n" +" -V Reports version and exits.\n" +msgstr "" +"Składnia: %s [opcje] urządzenie\n" "\n" +"Opcje:\n" +" -f Urządzenie jest plikiem\n" +" -L Wymuszenie wyzerowania logu. Wykonywać tylko w ostateczności.\n" +" -l urz_logu Określenie urządzenia z zewnętrznym logiem.\n" +" -m maks_pam Maksymalna ilość pamięci do użycia w megabajtach.\n" +" -n Tryb bez modyfikacji, tylko sprawdzenie systemu plików.\n" +" -P Wyłączenie prefetch.\n" +" -r urz_rt Określenie urządzenia z sekcją realtime.\n" +" -v Szczegółowe wyjście.\n" +" -c podopcje Zmiana parametrów systemu plików przy użyciu xfs_admina.\n" +" -o podopcje Zmiana domyślnego zachowania, więcej na stronie manuala.\n" +" -t czas Okres informowania o postępach w minutach.\n" +" -d Naprawianie w sposób niebezpieczny.\n" +" -V Wypisanie informacji o wersji i zakończenie.\n" + +#: .././repair/xfs_repair.c:107 +msgid "no error" +msgstr "brak błędu" + +#: .././repair/xfs_repair.c:108 +msgid "bad magic number" +msgstr "błędna liczba magiczna" + +#: .././repair/xfs_repair.c:109 +msgid "bad blocksize field" +msgstr "błędne pole blocksize" + +#: .././repair/xfs_repair.c:110 +msgid "bad blocksize log field" +msgstr "błędne pole logu blocksize" + +#: .././repair/xfs_repair.c:111 +msgid "bad or unsupported version" +msgstr "błędna lub nie obsługiwana wersja" + +#: .././repair/xfs_repair.c:113 +msgid "filesystem mkfs-in-progress bit set" +msgstr "ustawiony bit mkfs-in-progress systemu plików" + +#: .././repair/xfs_repair.c:115 +msgid "inconsistent filesystem geometry information" +msgstr "niespójne informacje o geometrii systemu plików" -#: .././db/sb.c:336 .././db/sb.c:488 -msgid "invalid parameters\n" -msgstr "błędne parametry\n" +#: .././repair/xfs_repair.c:117 +msgid "bad inode size or inconsistent with number of inodes/block" +msgstr "błędny rozmiar i-węzła lub niespójność z liczbą i-węzłów/blok" -#: .././db/sb.c:343 .././db/sb.c:495 .././db/sb.c:640 -#, c-format -msgid "%s: not in expert mode, writing disabled\n" -msgstr "%s: nie w trybie expert, zapis wyłączony\n" +#: .././repair/xfs_repair.c:118 +msgid "bad sector size" +msgstr "błędny rozmiar sektora" -#: .././db/sb.c:355 -msgid "failed to read UUID from AG 0\n" -msgstr "nie udało się odczytać UUID-a z AG 0\n" +#: .././repair/xfs_repair.c:120 +msgid "AGF geometry info conflicts with filesystem geometry" +msgstr "informacje o geometrii AGF są w konflikcie z geometrią systemu plików" -#: .././db/sb.c:360 -#, c-format -msgid "old UUID = %s\n" -msgstr "stary UUID = %s\n" +#: .././repair/xfs_repair.c:122 +msgid "AGI geometry info conflicts with filesystem geometry" +msgstr "informacje o geometrii AGI są w konflikcie z geometrią systemu plików" -#: .././db/sb.c:363 -msgid "invalid UUID\n" -msgstr "błędny UUID\n" +#: .././repair/xfs_repair.c:124 +msgid "AG superblock geometry info conflicts with filesystem geometry" +msgstr "informacje o geometrii superbloku AG są w konflikcie z geometrią systemu plików" -#: .././db/sb.c:372 .././db/sb.c:500 .././db/sb.c:712 -msgid "writing all SBs\n" -msgstr "zapisywanie wszystkich superbloków\n" +#: .././repair/xfs_repair.c:125 +msgid "attempted to perform I/O beyond EOF" +msgstr "próbowano wykonać operację we/wy poza końcem pliku" -#: .././db/sb.c:375 -#, c-format -msgid "failed to set UUID in AG %d\n" -msgstr "nie udało się ustawić UUID-a w AG %d\n" +#: .././repair/xfs_repair.c:127 +msgid "inconsistent filesystem geometry in realtime filesystem component" +msgstr "niespójna geometria systemu plików w składniku realtime" -#: .././db/sb.c:380 -#, c-format -msgid "new UUID = %s\n" -msgstr "nowy UUID = %s\n" +#: .././repair/xfs_repair.c:129 +msgid "maximum indicated percentage of inodes > 100%" +msgstr "określono maksymalny procent i-węzłów > 100%" -#: .././db/sb.c:388 -#, c-format -msgid "failed to read UUID from AG %d\n" -msgstr "nie udało się odczytać UUID-a z AG %d\n" +#: .././repair/xfs_repair.c:131 +msgid "inconsistent inode alignment value" +msgstr "niespójna wartość wyrównania i-węzła" -#: .././db/sb.c:394 -#, c-format -msgid "warning: UUID in AG %d differs to the primary SB\n" -msgstr "uwaga: UUID w AG %d różni się od głównego SB\n" +#: .././repair/xfs_repair.c:133 +msgid "not enough secondary superblocks with matching geometry" +msgstr "za mało zapasowych superbloków o pasującej geometrii" -#: .././db/sb.c:405 -msgid "warning - external log specified for FS with an internal log\n" -msgstr "uwaga: podano log zewnętrzny dla systemu plików z logiem wewnętrznym\n" +#: .././repair/xfs_repair.c:135 +msgid "bad stripe unit in superblock" +msgstr "błędna jednostka pasa w superbloku" -#: .././db/sb.c:408 -msgid "warning - no external log specified for FS with an external log\n" -msgstr "uwaga: nie podano logu zewnętrznego dla systemu plików z logiem zewnętrznym\n" +#: .././repair/xfs_repair.c:137 +msgid "bad stripe width in superblock" +msgstr "błędna szerokość pasa w superbloku" -#: .././db/sb.c:413 -#, c-format -msgid "UUID = %s\n" -msgstr "UUID = %s\n" +#: .././repair/xfs_repair.c:139 +msgid "bad shared version number in superblock" +msgstr "błędny numer wersji współdzielenia w superbloku" -#: .././db/sb.c:424 -msgid "" -"\n" -" write/print FS label\n" -"\n" -" Example:\n" -"\n" -" 'label' - print label\n" -" 'label 123456789012' - write label\n" -" 'label --' - write an empty label\n" -"\n" -"The print function checks the label in each SB and will warn if the labels\n" -"differ between AGs. The write commands will set the label in all AGs to the\n" -"specified value. The maximum length of a label is 12 characters - use of a\n" -"longer label will result in truncation and a warning will be issued.\n" -"\n" -msgstr "" -"\n" -" zapisanie/wypisanie etykiety systemu plików\n" -"\n" -" Przykład:\n" -"\n" -" 'label' - wypisanie etykiety\n" -" 'label 123456789012' - zapisanie etykiety\n" -" 'label --' - zapisanie etykiety pustej\n" -"\n" -"Funkcja wypisująca sprawdza etykietę w każdym superbloku i ostrzega, jeśli\n" -"etykiety różnią się między AG. Polecenia zapisu ustawiają etykietw we\n" -"wszystkich AG na określoną wartość. Maksymalna długość etykiety to 12 znaków;\n" -"użycie etykiety dłuższej zaskutkuje ucięciem jej i wypisaniem ostrzeżenia.\n" -"\n" +#: .././repair/xfs_repair.c:141 +msgid "bad CRC in superblock" +msgstr "błędna suma kontrolna w superbloku" -#: .././db/sb.c:461 +#: .././repair/xfs_repair.c:146 #, c-format -msgid "%s: truncating label length from %d to %d\n" -msgstr "%s: skrócono długość etykiety z %d do %d\n" +msgid "bad error code - %d\n" +msgstr "błędny kod błędu - %d\n" -#: .././db/sb.c:503 +#: .././repair/xfs_repair.c:154 #, c-format -msgid "failed to set label in AG %d\n" -msgstr "nie udało się ustawić etykiety w AG %d\n" +msgid "-%c %s option cannot have a value\n" +msgstr "opcja -%c %s nie przyjmuje wartości\n" -#: .././db/sb.c:506 -#, c-format -msgid "new label = \"%s\"\n" -msgstr "nowa etykieta = \"%s\"\n" +#: .././repair/xfs_repair.c:245 +msgid "-o ihash option has been removed and will be ignored\n" +msgstr "opcja -o ihash została usunięta i zostanie zignorowana\n" -#: .././db/sb.c:513 -#, c-format -msgid "failed to read label in AG %d\n" -msgstr "nie udało się odczytać etykiety w AG %d\n" +#: .././repair/xfs_repair.c:250 +msgid "-o bhash option cannot be used with -m option\n" +msgstr "opcja -o bhash nie może być użyta wraz z opcją -m\n" -#: .././db/sb.c:519 -#, c-format -msgid "warning: AG %d label differs\n" -msgstr "uwaga: etykieta w AG %d różni się\n" +#: .././repair/xfs_repair.c:302 +msgid "-m option cannot be used with -o bhash option\n" +msgstr "opcja -m nie może być użyta wraz z opcją -o bhash\n" -#: .././db/sb.c:521 +#: .././repair/xfs_repair.c:344 #, c-format -msgid "label = \"%s\"\n" -msgstr "etykieta = \"%s\"\n" - -#: .././db/sb.c:531 msgid "" "\n" -" set/print feature bits in sb version\n" -"\n" -" Example:\n" -"\n" -" 'version' - print current feature bits\n" -" 'version extflg' - enable unwritten extents\n" -" 'version attr1' - enable v1 inline extended attributes\n" -" 'version attr2' - enable v2 inline extended attributes\n" -" 'version log2' - enable v2 log format\n" -"\n" -"The version function prints currently enabled features for a filesystem\n" -"according to the version field of its primary superblock.\n" -"It can also be used to enable selected features, such as support for\n" -"unwritten extents. The updated version is written into all AGs.\n" -"\n" +"fatal error -- " msgstr "" "\n" -" ustawienie/wypisanie bitów cech w wersji superbloku\n" -"\n" -" Przykład:\n" -"\n" -" 'version' - wypisanie bieżących bitów cech\n" -" 'version extflg' - włączenie nie zapisanych ekstentów\n" -" 'version attr1' - włączenie rozszerzonych atrybutów inline v1\n" -" 'version attr2' - włączenie rozszerzonych atrybutów inline v2\n" -" 'version log2' - włączenie formatu logu v2\n" -"\n" -"Funkcja 'version' wypisuje aktualnie włączone cechy dla systemu plików\n" -"zgodnie z polem wersji w głównym superbloku.\n" -"Może być używana także do włączania wybranych cech, takich jak obsługa\n" -"nie zapisanych ekstentów. Uaktualniona wersja jest zapisywana we wszystkich\n" -"AG.\n" -"\n" - -#: .././db/sb.c:560 -msgid "Superblock has mismatched features2 fields, skipping modification\n" -msgstr "Superblok ma niepasujące pola features2, pominięto modyfikację\n" - -#: .././db/sb.c:659 -msgid "unwritten extents flag is already enabled\n" -msgstr "flaga nie zapisanych ekstentów jest już włączona\n" - -#: .././db/sb.c:679 -msgid "version 2 log format is already in use\n" -msgstr "format logu w wersji 2 jest już w użyciu\n" - -#: .././db/sb.c:706 -#, c-format -msgid "%s: invalid version change command \"%s\"\n" -msgstr "%s: błędne polecenie zmiany wersji \"%s\"\n" - -#: .././db/sb.c:715 -#, c-format -msgid "failed to set versionnum in AG %d\n" -msgstr "nie udało się ustawić versionnum w AG %d\n" - -#: .././db/sb.c:733 -#, c-format -msgid "versionnum [0x%x+0x%x] = %s\n" -msgstr "versionnum [0x%x+0x%x] = %s\n" +"błąd krytyczny - " -#: .././copy/xfs_copy.c:102 +#: .././repair/xfs_repair.c:460 #, c-format -msgid "Check logfile \"%s\" for more details\n" -msgstr "Więcej szczegółów w pliku logu \"%s\"\n" +msgid "sb root inode value % %sinconsistent with calculated value %u\n" +msgstr "wartość i-węzła głównego superbloku % %sniespójna z obliczoną wartością %u\n" -#: .././copy/xfs_copy.c:108 +#: .././repair/xfs_repair.c:467 #, c-format -msgid "%s: could not write to logfile \"%s\".\n" -msgstr "%s: nie udało się zapisać pliku logu \"%s\".\n" +msgid "resetting superblock root inode pointer to %u\n" +msgstr "przestawiono wskaźnik i-węzła głównego superbloku na %u\n" -#: .././copy/xfs_copy.c:111 +#: .././repair/xfs_repair.c:471 #, c-format -msgid "Aborting XFS copy -- logfile error -- reason: %s\n" -msgstr "Przerwano XFS copy - błąd pliku logu - przyczyna: %s\n" - -#: .././copy/xfs_copy.c:126 .././copy/xfs_copy.c:286 .././copy/xfs_copy.c:563 -#: .././copy/xfs_copy.c:570 -msgid "Aborting XFS copy - reason" -msgstr "Przerwano XFS copy - przyczyna" - -#: .././copy/xfs_copy.c:140 -msgid "THE FOLLOWING COPIES FAILED TO COMPLETE\n" -msgstr "NASTĘPUJĄCYCH KOPII NIE UDAŁO SIĘ UKOŃCZYĆ\n" - -#: .././copy/xfs_copy.c:144 -msgid "write error" -msgstr "błąd zapisu" - -#: .././copy/xfs_copy.c:146 -msgid "lseek64 error" -msgstr "błąd lseek64" +msgid "would reset superblock root inode pointer to %u\n" +msgstr "wskaźnik i-węzła głównego superbloku zostałby przestawiony na %u\n" -#: .././copy/xfs_copy.c:147 +#: .././repair/xfs_repair.c:483 #, c-format -msgid " at offset %lld\n" -msgstr " pod offsetem %lld\n" +msgid "sb realtime bitmap inode % %sinconsistent with calculated value %u\n" +msgstr "i-węzeł bitmapy realtime superbloku % %sniespójny z obliczoną wartością %u\n" -#: .././copy/xfs_copy.c:151 +#: .././repair/xfs_repair.c:490 #, c-format -msgid "All copies completed.\n" -msgstr "Wszystkie kopie ukończone.\n" +msgid "resetting superblock realtime bitmap ino pointer to %u\n" +msgstr "przestawiono wskaźnik i-węzła bitmapy realtime superbloku na %u\n" -#: .././copy/xfs_copy.c:154 +#: .././repair/xfs_repair.c:494 #, c-format -msgid "See \"%s\" for more details.\n" -msgstr "Więcej szczegółów w \"%s\".\n" +msgid "would reset superblock realtime bitmap ino pointer to %u\n" +msgstr "wskaźnik i-węzła bitmapy realtime superbloku zostałby przestawiony na %u\n" -#: .././copy/xfs_copy.c:255 +#: .././repair/xfs_repair.c:506 #, c-format -msgid "%s: write error on target %d \"%s\" at offset %lld\n" -msgstr "%s: błąd zapisu przy celu %d \"%s\" pod offsetem %lld\n" +msgid "sb realtime summary inode % %sinconsistent with calculated value %u\n" +msgstr "i-węzeł opisu realtime superbloku % %sniespójny z obliczoną wartością %u\n" -#: .././copy/xfs_copy.c:260 +#: .././repair/xfs_repair.c:513 #, c-format -msgid "%s: lseek64 error on target %d \"%s\" at offset %lld\n" -msgstr "%s: błąd lseek64 przy celu %d \"%s\" pod offsetem %lld\n" +msgid "resetting superblock realtime summary ino pointer to %u\n" +msgstr "przestawiono wskaźnik i-węzła opisu realtime superbloku na %u\n" -#: .././copy/xfs_copy.c:266 +#: .././repair/xfs_repair.c:517 #, c-format -msgid "Aborting target %d - reason" -msgstr "Przerywano zapis celu %d - przyczyna" - -#: .././copy/xfs_copy.c:270 -msgid "Aborting XFS copy - no more targets.\n" -msgstr "Przerwano XFS copy - nie ma więcej celów.\n" +msgid "would reset superblock realtime summary ino pointer to %u\n" +msgstr "wskaźnik i-węzła opisu realtime superbloku zostałby przestawiony na %u\n" -#: .././copy/xfs_copy.c:281 -#, c-format -msgid "%s: thread %d died unexpectedly, target \"%s\" incomplete\n" -msgstr "%s: wątek %d zmarł nieoczekiwanie, cel \"%s\" niekompletny\n" +#: .././repair/xfs_repair.c:563 +msgid "" +"Primary superblock would have been modified.\n" +"Cannot proceed further in no_modify mode.\n" +"Exiting now.\n" +msgstr "" +"Główny superblok zostałby zmodyfikowany.\n" +"Nie można kontynuować w trybie bez modyfikacji.\n" +"Zakończono.\n" -#: .././copy/xfs_copy.c:283 -#, c-format -msgid "%s: offset was probably %lld\n" -msgstr "%s: offset prawdopodobnie %lld\n" +#: .././repair/xfs_repair.c:571 +msgid "" +"Primary superblock bad after phase 1!\n" +"Exiting now.\n" +msgstr "" +"Nieprawidłowy główny superblok po fazie 1!\n" +"Koniec działania.\n" -#: .././copy/xfs_copy.c:294 -#, c-format -msgid "%s: Unknown child died (should never happen!)\n" -msgstr "%s: Nieznany potomek zmarł (nie powinno się zdarzyć!)\n" +#: .././repair/xfs_repair.c:587 +msgid "" +"Cannot get host filesystem geometry.\n" +"Repair may fail if there is a sector size mismatch between\n" +"the image and the host filesystem.\n" +msgstr "" +"Nie można pobrać geometrii systemu plików hosta.\n" +"Naprawienie może się nie powieść, jeśli istnieje niespójność rozmiaru\n" +"sektora między obrazem a systemem plików hosta.\n" -#: .././copy/xfs_copy.c:304 -#, c-format -msgid "Usage: %s [-bd] [-L logfile] source target [target ...]\n" -msgstr "Składnia: %s [-bd] [-L plik_logu] źródło cel [cel ...]\n" +#: .././repair/xfs_repair.c:599 +msgid "" +"Sector size on host filesystem larger than image sector size.\n" +"Cannot turn off direct IO, so exiting.\n" +msgstr "" +"Rozmiar sektora na systemie plików hosta większy niż rozmiar sektora obrazu.\n" +"Nie można wyłączyć bezpośredniego we/wy - zakończono działanie.\n" -#: .././copy/xfs_copy.c:386 +#: .././repair/xfs_repair.c:612 #, c-format -msgid "%s: lseek64 failure at offset %lld\n" -msgstr "%s: niepowodzenie lseek64 pod offsetem %lld\n" +msgid "%s: cannot repair this filesystem. Sorry.\n" +msgstr "%s: niestety nie można naprawić tego systemu plików.\n" -#: .././copy/xfs_copy.c:401 +#: .././repair/xfs_repair.c:671 #, c-format -msgid "assert error: buf->length = %d, buf->size = %d\n" -msgstr "błąd zapewnienia: buf->length = %d, buf->size = %d\n" +msgid " - reporting progress in intervals of %s\n" +msgstr " - informowanie o postępie w odstępach %s\n" -#: .././copy/xfs_copy.c:408 +#: .././repair/xfs_repair.c:716 #, c-format -msgid "%s: read failure at offset %lld\n" -msgstr "%s: błąd odczytu pod offsetem %lld\n" +msgid " - max_mem = %lu, icount = %, imem = %, dblock = %, dmem = %\n" +msgstr " - max_mem = %lu, icount = %, imem = %, dblock = %, dmem = %\n" -#: .././copy/xfs_copy.c:561 +#: .././repair/xfs_repair.c:725 #, c-format -msgid "%s: couldn't open log file \"%s\"\n" -msgstr "%s: nie udało się otworzyć pliku logu \"%s\"\n" +msgid "" +"Required memory for repair is greater that the maximum specified\n" +"with the -m option. Please increase it to at least %lu.\n" +msgstr "" +"Pamięć wymagana do naprawy przekracza maksimum określone opcją -m.\n" +"Proszę ją zwiększyć do co najmniej %lu.\n" -#: .././copy/xfs_copy.c:568 +#: .././repair/xfs_repair.c:730 #, c-format -msgid "%s: couldn't set up logfile stream\n" -msgstr "%s: nie udało się ustanowić strumienia pliku logu\n" +msgid "" +"Memory available for repair (%luMB) may not be sufficient.\n" +"At least %luMB is needed to repair this filesystem efficiently\n" +"If repair fails due to lack of memory, please\n" +msgstr "" +"Pamięć dostępna przy naprawie (%luMB) może nie być wystarczająca.\n" +"Aby wydajnie naprawić ten system plików, niezbędne jest co najmniej %luMB.\n" +"Jeśli naprawa nie powiedzie się z powodu braku pamięci, proszę\n" -#: .././copy/xfs_copy.c:580 -msgid "Couldn't allocate target array\n" -msgstr "Nie udało się przydzielić tablicy celów\n" +#: .././repair/xfs_repair.c:736 +msgid "turn prefetching off (-P) to reduce the memory footprint.\n" +msgstr "wyłączyć prefetch (-P), aby zmniejszyć zużycie pamięci.\n" -#: .././copy/xfs_copy.c:595 +#: .././repair/xfs_repair.c:739 #, c-format -msgid "%s: couldn't register atexit function.\n" -msgstr "%s: nie udało się zarejestrować funkcji atexit.\n" +msgid "increase system RAM and/or swap space to at least %luMB.\n" +msgstr "proszę rozszerzyć rozmiar RAM systemu i/lub przestrzeni wymiany do co najmniej %luMB.\n" -#: .././copy/xfs_copy.c:604 +#: .././repair/xfs_repair.c:754 #, c-format -msgid "%s: couldn't open source \"%s\"\n" -msgstr "%s: nie udało się otworzyć źródła \"%s\"\n" +msgid " - block cache size set to %d entries\n" +msgstr " - rozmiar bufora bloku ustawiony na %d wpisów\n" -#: .././copy/xfs_copy.c:610 -#, c-format -msgid "%s: couldn't stat source \"%s\"\n" -msgstr "%s: nie udało się wykonać stat na źródle \"%s\"\n" +#: .././repair/xfs_repair.c:778 +msgid "Found unsupported filesystem features. Exiting now.\n" +msgstr "Znaleziono nie obsługiwane cechy systemu plików. Zakończono.\n" -#: .././copy/xfs_copy.c:620 +#: .././repair/xfs_repair.c:796 #, c-format -msgid "%s: Cannot set direct I/O flag on \"%s\".\n" -msgstr "%s: Nie można ustawić flagi bezpośredniego we/wy na \"%s\".\n" +msgid "No modify flag set, skipping phase 5\n" +msgstr "Ustawiono flagę braku modyfikacji, pominięto fazę 5\n" -#: .././copy/xfs_copy.c:625 -#, c-format -msgid "%s: xfsctl on file \"%s\" failed.\n" -msgstr "%s: xfsctl na pliku \"%s\" nie powiodło się.\n" +#: .././repair/xfs_repair.c:815 +msgid "Inode allocation btrees are too corrupted, skipping phases 6 and 7\n" +msgstr "B-drzewa alokacji i-węzłów są zbyt uszkodzone, pominięto fazy 6 i 7\n" -#: .././copy/xfs_copy.c:648 -#, c-format -msgid "%s: Warning -- a filesystem is mounted on the source device.\n" -msgstr "%s: Uwaga - system plików jest podmontowany na urządzeniu źródłowym.\n" +#: .././repair/xfs_repair.c:821 +msgid "Warning: no quota inodes were found. Quotas disabled.\n" +msgstr "Uwaga: nie znaleziono i-węzłów limitów (quot). Limity wyłączone.\n" -#: .././copy/xfs_copy.c:651 -msgid "\t\tGenerated copies may be corrupt unless the source is\n" -msgstr "\t\tWygenerowane kopie mogą być uszkodzone o ile źródło nie jest\n" +#: .././repair/xfs_repair.c:824 +msgid "Warning: no quota inodes were found. Quotas would be disabled.\n" +msgstr "Uwaga: nie znaleziono i-węzłów limitów (quot). Limity zostałyby wyłączone.\n" -#: .././copy/xfs_copy.c:653 -msgid "\t\tunmounted or mounted read-only. Copy proceeding...\n" -msgstr "\t\todmontowane lub podmontowane tylko do odczytu. Kopiowanie w trakcie...\n" +#: .././repair/xfs_repair.c:829 +msgid "Warning: quota inodes were cleared. Quotas disabled.\n" +msgstr "Uwaga: i-węzły limitów (quot) były wyczyszczone. Limity wyłączone.\n" -#: .././copy/xfs_copy.c:670 -#, c-format +#: .././repair/xfs_repair.c:832 +msgid "Warning: quota inodes would be cleared. Quotas would be disabled.\n" +msgstr "Uwaga: i-węzły limitów (quot) zostałyby wyczyszczone. Limity zostałyby wyłączone.\n" + +#: .././repair/xfs_repair.c:838 msgid "" -"%s: couldn't initialize XFS library\n" -"%s: Aborting.\n" +"Warning: user quota information was cleared.\n" +"User quotas can not be enforced until limit information is recreated.\n" msgstr "" -"%s: nie udało się zainicjować biblioteki XFS\n" -"%s: Przerwano.\n" +"Uwaga: informacje o limitach użytkowników były wyczyszczone.\n" +"Limity użytkowników nie mogą być wymuszone do czasu odtworzenia informacji.\n" -#: .././copy/xfs_copy.c:684 -#, c-format +#: .././repair/xfs_repair.c:842 msgid "" -"%s: %s filesystem failed to initialize\n" -"%s: Aborting.\n" +"Warning: user quota information would be cleared.\n" +"User quotas could not be enforced until limit information was recreated.\n" msgstr "" -"%s: Nie powiodła się inicjalizacja systemu plików %s\n" -"%s: Przerwano.\n" +"Uwaga: informacje o limitach użytkowników zostałyby wyczyszczone.\n" +"Limity użytkowników nie mogłyby być wymuszone do czasu odtworzenia informacji.\n" -#: .././copy/xfs_copy.c:688 -#, c-format +#: .././repair/xfs_repair.c:850 msgid "" -"%s %s filesystem failed to initialize\n" -"%s: Aborting.\n" +"Warning: group quota information was cleared.\n" +"Group quotas can not be enforced until limit information is recreated.\n" msgstr "" -"%s: Nie powiodła się inicjalizacja systemu plików %s\n" -"%s: Przerwano.\n" +"Uwaga: informacje o limitach grup były wyczyszczone.\n" +"Limity grup nie mogą być wymuszone do czasu odtworzenia informacji.\n" -#: .././copy/xfs_copy.c:692 -#, c-format +#: .././repair/xfs_repair.c:854 msgid "" -"%s: %s has an external log.\n" -"%s: Aborting.\n" +"Warning: group quota information would be cleared.\n" +"Group quotas could not be enforced until limit information was recreated.\n" msgstr "" -"%s: %s ma zewnętrzny log.\n" -"%s: Przerwano.\n" +"Uwaga: informacje o limitach grup zostałyby wyczyszczone.\n" +"Limity grup nie mogłyby być wymuszone do czasu odtworzenia informacji.\n" -#: .././copy/xfs_copy.c:696 -#, c-format +#: .././repair/xfs_repair.c:862 msgid "" -"%s: %s has a real-time section.\n" -"%s: Aborting.\n" +"Warning: project quota information was cleared.\n" +"Project quotas can not be enforced until limit information is recreated.\n" msgstr "" -"%s: %s ma sekcję real-time.\n" -"%s: Przerwano.\n" +"Uwaga: informacje o limitach projektów były wyczyszczone.\n" +"Limity projektów nie mogą być wymuszone do czasu odtworzenia informacji.\n" -#: .././copy/xfs_copy.c:721 +#: .././repair/xfs_repair.c:866 msgid "" -"Error: filesystem block size is smaller than the disk sectorsize.\n" -"Aborting XFS copy now.\n" +"Warning: project quota information would be cleared.\n" +"Project quotas could not be enforced until limit information was recreated.\n" msgstr "" -"Błąd: rozmiar bloku systemu plików jest mniejszy niż rozmiar sektora dysku.\n" -"Przerwano XFS copy.\n" +"Uwaga: informacje o limitach projektów zostałyby wyczyszczone.\n" +"Limity projektów nie mogłyby być wymuszone do czasu odtworzenia informacji.\n" -#: .././copy/xfs_copy.c:742 -#, c-format -msgid "Creating file %s\n" -msgstr "Tworzenie pliku %s\n" +#: .././repair/xfs_repair.c:877 +msgid "No modify flag set, skipping filesystem flush and exiting.\n" +msgstr "Flaga braku modyfikacji ustawiona, pominięto zrzucanie systemu plików, zakończono.\n" + +#: .././repair/xfs_repair.c:896 +msgid "Note - quota info will be regenerated on next quota mount.\n" +msgstr "Uwaga - informacje o limitach zostaną ponownie wygenerowane przy następnym montowaniu.\n" -#: .././copy/xfs_copy.c:760 +#: .././repair/xfs_repair.c:903 #, c-format msgid "" -"%s: a filesystem is mounted on target device \"%s\".\n" -"%s cannot copy to mounted filesystems. Aborting\n" +"Note - stripe unit (%d) and width (%d) fields have been reset.\n" +"Please set with mount -o sunit=,swidth=\n" msgstr "" -"%s: na urządzeniu docelowym \"%s\" jest podmontowany system plików.\n" -"%s nie może kopiować na podmontowane systemy plików. Przerwano.\n" +"Uwaga - pola jednostki pasa (%d) i szerokości pasa (%d) zostały przestawione.\n" +"Proszę ustawić przy użyciu mount -o sunit=,swidth=\n" -#: .././copy/xfs_copy.c:771 -#, c-format -msgid "%s: couldn't open target \"%s\"\n" -msgstr "%s: nie udało się otworzyć celu \"%s\"\n" +#: .././repair/xfs_repair.c:926 +msgid "done\n" +msgstr "gotowe\n" -#: .././copy/xfs_copy.c:781 +#: .././repair/xfs_repair.c:930 +msgid "Repair of readonly mount complete. Immediate reboot encouraged.\n" +msgstr "Naprawa systemu zamontowanego tylko do odczytu zakończona. Zalecany natychmiastowy restart systemu.\n" + +#: .././rtcp/xfs_rtcp.c:30 #, c-format -msgid "%s: cannot grow data section.\n" -msgstr "%s: nie można powiększyć sekcji danych.\n" +msgid "%s [-e extsize] [-p] [-V] source target\n" +msgstr "%s [-e rozm_fragmentu] [-p] [-V] źródło cel\n" -#: .././copy/xfs_copy.c:789 +#: .././rtcp/xfs_rtcp.c:69 #, c-format -msgid "%s: xfsctl on \"%s\" failed.\n" -msgstr "%s: xfsctl na \"%s\" nie powiodło się.\n" +msgid "%s: must specify files to copy\n" +msgstr "%s: trzeba podać pliki do skopiowania\n" -#: .././copy/xfs_copy.c:808 +#: .././rtcp/xfs_rtcp.c:84 #, c-format -msgid "%s: failed to write last block\n" -msgstr "%s: nie udało się zapisać ostatniego bloku\n" +msgid "%s: stat64 of %s failed\n" +msgstr "%s: stat64 na %s nie powiodło się\n" -#: .././copy/xfs_copy.c:810 +#: .././rtcp/xfs_rtcp.c:91 #, c-format -msgid "\tIs target \"%s\" too small?\n" -msgstr "\tCzy cel \"%s\" jest zbyt mały?\n" +msgid "%s: final argument is not directory\n" +msgstr "%s: ostatni argument nie jest katalogiem\n" -#: .././copy/xfs_copy.c:820 -msgid "Couldn't initialize global thread mask\n" -msgstr "Nie udało się zainicjować globalnej maski wątków\n" +#: .././rtcp/xfs_rtcp.c:138 +#, c-format +msgid "%s: failed stat64 on %s: %s\n" +msgstr "%s: nie udało się wykonać stat64 na %s: %s\n" -#: .././copy/xfs_copy.c:827 -msgid "Error initializing wbuf 0\n" -msgstr "Błąd inicjalizacji wbuf 0\n" +#: .././rtcp/xfs_rtcp.c:159 +#, c-format +msgid "%s: %s filesystem has no realtime partition\n" +msgstr "%s: system plików %s nie ma partycji realtime\n" -#: .././copy/xfs_copy.c:835 -msgid "Error initializing btree buf 1\n" -msgstr "Błąd inicjalizacji btree buf 1\n" +#: .././rtcp/xfs_rtcp.c:180 .././rtcp/xfs_rtcp.c:208 +#, c-format +msgid "%s: open of %s failed: %s\n" +msgstr "%s: otwarcie %s nie powiodło się: %s\n" -#: .././copy/xfs_copy.c:840 -msgid "Error creating first semaphore.\n" -msgstr "Błąd tworzenia pierwszego semafora.\n" +#: .././rtcp/xfs_rtcp.c:197 +#, c-format +msgid "%s: set attributes on %s failed: %s\n" +msgstr "%s: ustawienie atrybutów dla %s nie powiodło się: %s\n" -#: .././copy/xfs_copy.c:855 -msgid "Couldn't malloc space for thread args\n" -msgstr "Nie udało się przydzielić miejsca na argumenty wątku\n" +#: .././rtcp/xfs_rtcp.c:215 +#, c-format +msgid "%s: get attributes of %s failed: %s\n" +msgstr "%s: pobranie atrybutów %s nie powiodło się: %s\n" -#: .././copy/xfs_copy.c:867 +#: .././rtcp/xfs_rtcp.c:225 .././rtcp/xfs_rtcp.c:262 #, c-format -msgid "Error creating thread mutex %d\n" -msgstr "Błąd podczas tworzenia sekcji krytycznej %d wątku\n" +msgid "%s: %s is not a realtime file.\n" +msgstr "%s: %s nie jest plikiem realtime.\n" -#: .././copy/xfs_copy.c:884 +#: .././rtcp/xfs_rtcp.c:235 #, c-format -msgid "Error creating thread for target %d\n" -msgstr "Błąd podczas tworzenia wątku dla celu %d\n" +msgid "%s: %s file extent size is %d, instead of %d.\n" +msgstr "%s: plik %s ma rozmiar ekstentu %d zamiast %d.\n" -#: .././copy/xfs_copy.c:974 -msgid "WARNING: source filesystem inconsistent.\n" -msgstr "UWAGA: źródłowy system plików niespójny.\n" +#: .././rtcp/xfs_rtcp.c:248 .././rtcp/xfs_rtcp.c:271 +#, c-format +msgid "%s: open of %s source failed: %s\n" +msgstr "%s: otwarcie źródła %s nie powiodło się: %s\n" -#: .././copy/xfs_copy.c:976 -msgid " A leaf btree rec isn't a leaf. Aborting now.\n" -msgstr " Liść rekordu b-drzewa nie jest liściem. Przerwano.\n" +#: .././rtcp/xfs_rtcp.c:285 +#, c-format +msgid "%s: couldn't get direct I/O information: %s\n" +msgstr "%s: nie udało się uzyskać informacji o bezpośrednim we/wy: %s\n" -#~ msgid "Unknown inode format.\n" -#~ msgstr "Nieznany format i-węzła.\n" +#: .././rtcp/xfs_rtcp.c:295 +#, c-format +msgid "%s: extent size %d not a multiple of %d.\n" +msgstr "%s: rozmiar ekstentu %d nie jest wielokrotnością %d.\n" -# XXX msgid bug: "0x" prefix for decimal number -#~ msgid "inode 0x% bad # of bmap records (%u, min - %u, max - %u)\n" -#~ msgstr "błędna liczba rekordów bmap w i-węźle 0x% (%u, minimum - %u, maksimum - %u)\n" +#: .././rtcp/xfs_rtcp.c:309 +#, c-format +msgid "The size of %s is not a multiple of %d.\n" +msgstr "Rozmiar %s nie jest wielokrotnością %d.\n" -#~ msgid "could not allocate expanded nlink array\n" -#~ msgstr "Nie udało się przydzielić rozszerzonej tablicy nlink\n" +#: .././rtcp/xfs_rtcp.c:312 +#, c-format +msgid "%s will be padded to %lld bytes.\n" +msgstr "%s: zostanie dopełniony do %lld bajtów.\n" -#~ msgid "bmap of block #%u of inode % failed\n" -#~ msgstr "bmap bloku #%u i-węzła % nie powiodło się\n" +#: .././rtcp/xfs_rtcp.c:318 +#, c-format +msgid "Use the -p option to pad %s to a size which is a multiple of %d bytes.\n" +msgstr "Można użyć opcji -p do dopełnienia %s do rozmiaru będącego wielokrotnością %d bajtów.\n" -#~ msgid "error following ag %d unlinked list\n" -#~ msgstr "błąd podczas podążania za odłączoną listą ag %d\n" +#: .././rtcp/xfs_rtcp.c:360 +#, c-format +msgid "%s: write error: %s\n" +msgstr "%s: błąd zapisu: %s\n" -#~ msgid "ts_alloc: cannot allocate thread specific storage\n" -#~ msgstr "ts_alloc: nie można przydzielić miejsca dla wątku\n" +#: .././rtcp/xfs_rtcp.c:388 +#, c-format +msgid "%s: could not open %s: %s\n" +msgstr "%s: nie udało się otworzyć %s: %s\n" diff -Nru xfsprogs-3.1.9ubuntu2/po/xfsprogs.pot xfsprogs-3.2.1ubuntu1/po/xfsprogs.pot --- xfsprogs-3.1.9ubuntu2/po/xfsprogs.pot 2012-12-12 23:28:51.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/po/xfsprogs.pot 2014-07-21 09:16:03.000000000 +0000 @@ -8,10 +8,11 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-12-13 10:28+1100\n" +"POT-Creation-Date: 2014-07-21 19:16+1000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" @@ -31,8 +32,8 @@ msgid "Aborting XFS copy -- logfile error -- reason: %s\n" msgstr "" -#: .././copy/xfs_copy.c:126 .././copy/xfs_copy.c:286 .././copy/xfs_copy.c:563 -#: .././copy/xfs_copy.c:570 +#: .././copy/xfs_copy.c:126 .././copy/xfs_copy.c:267 .././copy/xfs_copy.c:546 +#: .././copy/xfs_copy.c:553 msgid "Aborting XFS copy - reason" msgstr "" @@ -63,228 +64,242 @@ msgid "See \"%s\" for more details.\n" msgstr "" -#: .././copy/xfs_copy.c:255 +#: .././copy/xfs_copy.c:236 #, c-format msgid "%s: write error on target %d \"%s\" at offset %lld\n" msgstr "" -#: .././copy/xfs_copy.c:260 +#: .././copy/xfs_copy.c:241 #, c-format msgid "%s: lseek64 error on target %d \"%s\" at offset %lld\n" msgstr "" -#: .././copy/xfs_copy.c:266 +#: .././copy/xfs_copy.c:247 #, c-format msgid "Aborting target %d - reason" msgstr "" -#: .././copy/xfs_copy.c:270 +#: .././copy/xfs_copy.c:251 msgid "Aborting XFS copy - no more targets.\n" msgstr "" -#: .././copy/xfs_copy.c:281 +#: .././copy/xfs_copy.c:262 #, c-format msgid "%s: thread %d died unexpectedly, target \"%s\" incomplete\n" msgstr "" -#: .././copy/xfs_copy.c:283 +#: .././copy/xfs_copy.c:264 #, c-format msgid "%s: offset was probably %lld\n" msgstr "" -#: .././copy/xfs_copy.c:294 +#: .././copy/xfs_copy.c:275 #, c-format msgid "%s: Unknown child died (should never happen!)\n" msgstr "" -#: .././copy/xfs_copy.c:304 +#: .././copy/xfs_copy.c:285 #, c-format -msgid "Usage: %s [-bd] [-L logfile] source target [target ...]\n" +msgid "Usage: %s [-bdV] [-L logfile] source target [target ...]\n" msgstr "" -#: .././copy/xfs_copy.c:386 +#: .././copy/xfs_copy.c:367 #, c-format msgid "%s: lseek64 failure at offset %lld\n" msgstr "" -#: .././copy/xfs_copy.c:401 +#: .././copy/xfs_copy.c:382 #, c-format msgid "assert error: buf->length = %d, buf->size = %d\n" msgstr "" -#: .././copy/xfs_copy.c:408 +#: .././copy/xfs_copy.c:388 #, c-format msgid "%s: read failure at offset %lld\n" msgstr "" -#: .././copy/xfs_copy.c:543 .././db/init.c:93 .././estimate/xfs_estimate.c:141 -#: .././fsr/xfs_fsr.c:302 .././growfs/xfs_growfs.c:182 .././io/init.c:184 -#: .././logprint/logprint.c:196 .././mkfs/xfs_mkfs.c:1623 -#: .././quota/init.c:131 .././repair/xfs_repair.c:317 .././rtcp/xfs_rtcp.c:55 +#: .././copy/xfs_copy.c:418 +msgid "ag header buffer invalid!\n" +msgstr "" + +#: .././copy/xfs_copy.c:526 .././db/init.c:94 .././estimate/xfs_estimate.c:144 +#: .././fsr/xfs_fsr.c:300 .././growfs/xfs_growfs.c:182 .././io/init.c:190 +#: .././logprint/logprint.c:203 .././mkfs/xfs_mkfs.c:1703 +#: .././quota/init.c:131 .././repair/xfs_repair.c:319 .././rtcp/xfs_rtcp.c:55 #, c-format msgid "%s version %s\n" msgstr "" -#: .././copy/xfs_copy.c:561 +#: .././copy/xfs_copy.c:544 #, c-format msgid "%s: couldn't open log file \"%s\"\n" msgstr "" -#: .././copy/xfs_copy.c:568 +#: .././copy/xfs_copy.c:551 #, c-format msgid "%s: couldn't set up logfile stream\n" msgstr "" -#: .././copy/xfs_copy.c:580 +#: .././copy/xfs_copy.c:563 msgid "Couldn't allocate target array\n" msgstr "" -#: .././copy/xfs_copy.c:595 -#, c-format -msgid "%s: couldn't register atexit function.\n" -msgstr "" - -#: .././copy/xfs_copy.c:604 +#: .././copy/xfs_copy.c:582 #, c-format msgid "%s: couldn't open source \"%s\"\n" msgstr "" -#: .././copy/xfs_copy.c:610 +#: .././copy/xfs_copy.c:588 #, c-format msgid "%s: couldn't stat source \"%s\"\n" msgstr "" -#: .././copy/xfs_copy.c:620 +#: .././copy/xfs_copy.c:598 #, c-format msgid "%s: Cannot set direct I/O flag on \"%s\".\n" msgstr "" -#: .././copy/xfs_copy.c:625 +#: .././copy/xfs_copy.c:603 #, c-format msgid "%s: xfsctl on file \"%s\" failed.\n" msgstr "" -#: .././copy/xfs_copy.c:648 +#: .././copy/xfs_copy.c:626 #, c-format msgid "%s: Warning -- a filesystem is mounted on the source device.\n" msgstr "" -#: .././copy/xfs_copy.c:651 +#: .././copy/xfs_copy.c:629 msgid "\t\tGenerated copies may be corrupt unless the source is\n" msgstr "" -#: .././copy/xfs_copy.c:653 +#: .././copy/xfs_copy.c:631 msgid "\t\tunmounted or mounted read-only. Copy proceeding...\n" msgstr "" -#: .././copy/xfs_copy.c:670 +#: .././copy/xfs_copy.c:648 #, c-format msgid "" "%s: couldn't initialize XFS library\n" "%s: Aborting.\n" msgstr "" -#: .././copy/xfs_copy.c:684 +#: .././copy/xfs_copy.c:668 +#, c-format +msgid "%s: Cannot yet copy V5 fs without '-d'\n" +msgstr "" + +#: .././copy/xfs_copy.c:674 #, c-format msgid "" "%s: %s filesystem failed to initialize\n" "%s: Aborting.\n" msgstr "" -#: .././copy/xfs_copy.c:688 +#: .././copy/xfs_copy.c:678 #, c-format msgid "" "%s %s filesystem failed to initialize\n" "%s: Aborting.\n" msgstr "" -#: .././copy/xfs_copy.c:692 +#: .././copy/xfs_copy.c:682 #, c-format msgid "" "%s: %s has an external log.\n" "%s: Aborting.\n" msgstr "" -#: .././copy/xfs_copy.c:696 +#: .././copy/xfs_copy.c:686 #, c-format msgid "" "%s: %s has a real-time section.\n" "%s: Aborting.\n" msgstr "" -#: .././copy/xfs_copy.c:721 +#: .././copy/xfs_copy.c:711 msgid "" "Error: filesystem block size is smaller than the disk sectorsize.\n" "Aborting XFS copy now.\n" msgstr "" -#: .././copy/xfs_copy.c:742 +#: .././copy/xfs_copy.c:732 #, c-format msgid "Creating file %s\n" msgstr "" -#: .././copy/xfs_copy.c:760 +#: .././copy/xfs_copy.c:750 #, c-format msgid "" "%s: a filesystem is mounted on target device \"%s\".\n" "%s cannot copy to mounted filesystems. Aborting\n" msgstr "" -#: .././copy/xfs_copy.c:771 +#: .././copy/xfs_copy.c:761 #, c-format msgid "%s: couldn't open target \"%s\"\n" msgstr "" -#: .././copy/xfs_copy.c:781 +#: .././copy/xfs_copy.c:771 #, c-format msgid "%s: cannot grow data section.\n" msgstr "" -#: .././copy/xfs_copy.c:789 +#: .././copy/xfs_copy.c:779 #, c-format msgid "%s: xfsctl on \"%s\" failed.\n" msgstr "" -#: .././copy/xfs_copy.c:808 +#: .././copy/xfs_copy.c:798 #, c-format msgid "%s: failed to write last block\n" msgstr "" -#: .././copy/xfs_copy.c:810 +#: .././copy/xfs_copy.c:800 #, c-format msgid "\tIs target \"%s\" too small?\n" msgstr "" -#: .././copy/xfs_copy.c:820 +#: .././copy/xfs_copy.c:810 msgid "Couldn't initialize global thread mask\n" msgstr "" -#: .././copy/xfs_copy.c:827 +#: .././copy/xfs_copy.c:817 msgid "Error initializing wbuf 0\n" msgstr "" -#: .././copy/xfs_copy.c:835 +#: .././copy/xfs_copy.c:825 msgid "Error initializing btree buf 1\n" msgstr "" -#: .././copy/xfs_copy.c:840 +#: .././copy/xfs_copy.c:830 msgid "Error creating first semaphore.\n" msgstr "" -#: .././copy/xfs_copy.c:855 +#: .././copy/xfs_copy.c:845 msgid "Couldn't malloc space for thread args\n" msgstr "" -#: .././copy/xfs_copy.c:867 +#: .././copy/xfs_copy.c:857 #, c-format msgid "Error creating thread mutex %d\n" msgstr "" -#: .././copy/xfs_copy.c:884 +#: .././copy/xfs_copy.c:874 #, c-format msgid "Error creating thread for target %d\n" msgstr "" +#: .././copy/xfs_copy.c:928 +#, c-format +msgid "Error: current level %d >= btree levels %d\n" +msgstr "" + +#: .././copy/xfs_copy.c:947 +#, c-format +msgid "Bad btree magic 0x%x\n" +msgstr "" + #: .././copy/xfs_copy.c:974 msgid "WARNING: source filesystem inconsistent.\n" msgstr "" @@ -293,1410 +308,1536 @@ msgid " A leaf btree rec isn't a leaf. Aborting now.\n" msgstr "" -#: .././db/check.c:372 -msgid "free block usage information" -msgstr "" - -#: .././db/check.c:375 -msgid "[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..." +#: .././db/agf.c:35 .././db/sb.c:42 .././db/agfl.c:36 .././db/agi.c:35 +msgid "[agno]" msgstr "" -#: .././db/check.c:376 -msgid "get block usage and check consistency" +#: .././db/agf.c:36 +msgid "set address to agf header" msgstr "" -#: .././db/check.c:379 -msgid "[-n count] [-x minlen] [-y maxlen] [-s seed] [-0123] [-t type] ..." +#: .././db/agf.c:82 +msgid "" +"\n" +" set allocation group free block list\n" +"\n" +" Example:\n" +"\n" +" agf 2 - move location to AGF in 2nd filesystem allocation group\n" +"\n" +" Located in the second sector of each allocation group, the AGF\n" +" contains the root of two different freespace btrees:\n" +" The 'cnt' btree keeps track freespace indexed on section size.\n" +" The 'bno' btree tracks sections of freespace indexed on block number.\n" msgstr "" -#: .././db/check.c:380 -msgid "trash randomly selected block(s)" +#: .././db/agf.c:107 .././db/sb.c:163 .././db/agfl.c:106 .././db/agi.c:94 +#, c-format +msgid "bad allocation group number %s\n" msgstr "" -#: .././db/check.c:383 -msgid "[-n] [-c blockcount]" +#: .././db/bmap.c:39 +msgid "[-ad] [block [len]]" msgstr "" -#: .././db/check.c:384 -msgid "print usage for current block(s)" +#: .././db/bmap.c:40 +msgid "show block map for current file" msgstr "" -#: .././db/check.c:387 -msgid "[-s] [-i ino] ..." +#: .././db/bmap.c:152 .././db/inode.c:417 +msgid "no current inode\n" msgstr "" -#: .././db/check.c:388 -msgid "print inode-name pairs" +#: .././db/bmap.c:165 +msgid "bad option for bmap command\n" msgstr "" -#: .././db/check.c:408 +#: .././db/bmap.c:182 #, c-format -msgid "-i %lld bad inode number\n" +msgid "bad block number for bmap %s\n" msgstr "" -#: .././db/check.c:420 +#: .././db/bmap.c:190 #, c-format -msgid "inode %lld add link, now %u\n" +msgid "bad len for bmap %s\n" msgstr "" -#: .././db/check.c:447 +#: .././db/bmap.c:213 #, c-format -msgid "inode %lld parent %lld\n" -msgstr "" - -#: .././db/check.c:760 -msgid "block usage information not allocated\n" -msgstr "" - -#: .././db/check.c:798 -msgid "already have block usage information\n" +msgid "%s offset %lld startblock %llu (%u/%u) count %llu flag %u\n" msgstr "" -#: .././db/check.c:814 .././db/check.c:922 -msgid "WARNING: this may be a newer XFS filesystem.\n" +#: .././db/bmap.c:215 .././db/check.c:2136 .././db/check.c:2148 +#: .././db/check.c:2175 .././repair/dinode.c:50 +msgid "data" msgstr "" -#: .././db/check.c:850 -#, c-format -msgid "sb_icount %lld, counted %lld\n" +#: .././db/bmap.c:215 .././db/check.c:2136 .././db/check.c:2148 +#: .././db/check.c:2175 .././repair/dinode.c:51 +msgid "attr" msgstr "" -#: .././db/check.c:856 -#, c-format -msgid "sb_ifree %lld, counted %lld\n" +#: .././db/block.c:43 .././db/block.c:49 +msgid "filoff" msgstr "" -#: .././db/check.c:862 -#, c-format -msgid "sb_fdblocks %lld, counted %lld\n" +#: .././db/block.c:44 +msgid "set address to file offset (attr fork)" msgstr "" -#: .././db/check.c:868 -#, c-format -msgid "sb_fdblocks %lld, aggregate AGF count %lld\n" +#: .././db/block.c:46 +msgid "[d]" msgstr "" -#: .././db/check.c:874 -#, c-format -msgid "sb_frextents %lld, counted %lld\n" +#: .././db/block.c:47 +msgid "set address to daddr value" msgstr "" -#: .././db/check.c:881 -#, c-format -msgid "sb_features2 (0x%x) not same as sb_bad_features2 (0x%x)\n" +#: .././db/block.c:50 +msgid "set address to file offset (data fork)" msgstr "" -#: .././db/check.c:890 -#, c-format -msgid "sb versionnum missing attr bit %x\n" +#: .././db/block.c:52 +msgid "[fsb]" msgstr "" -#: .././db/check.c:897 -#, c-format -msgid "sb versionnum missing nlink bit %x\n" +#: .././db/block.c:53 +msgid "set address to fsblock value" msgstr "" -#: .././db/check.c:904 -#, c-format -msgid "sb versionnum missing quota bit %x\n" +#: .././db/block.c:59 +msgid "" +"\n" +" Example:\n" +"\n" +" 'ablock 23' - sets the file position to the 23rd filesystem block in\n" +" the inode's attribute fork. The filesystem block size is specified in\n" +" the superblock.\n" +"\n" msgstr "" -#: .././db/check.c:911 +#: .././db/block.c:82 .././db/block.c:177 #, c-format -msgid "sb versionnum extra align bit %x\n" +msgid "bad block number %s\n" msgstr "" -#: .././db/check.c:951 -msgid "zeroed" +#: .././db/block.c:90 +msgid "no attribute data for file\n" msgstr "" -#: .././db/check.c:951 -msgid "set" +#: .././db/block.c:96 +msgid "file attr block is unmapped\n" msgstr "" -#: .././db/check.c:951 -msgid "flipped" +#: .././db/block.c:119 +msgid "" +"\n" +" Example:\n" +"\n" +" 'daddr 102' - sets position to the 102nd absolute disk block\n" +" (512 byte block).\n" msgstr "" -#: .././db/check.c:951 -msgid "randomized" +#: .././db/block.c:135 +#, c-format +msgid "current daddr is %lld\n" msgstr "" -#: .././db/check.c:961 +#: .././db/block.c:141 #, c-format -msgid "can't read block %u/%u for trashing\n" +msgid "bad daddr %s\n" msgstr "" -#: .././db/check.c:991 -#, c-format -msgid "blocktrash: %u/%u %s block %d bit%s starting %d:%d %s\n" +#: .././db/block.c:153 +msgid "" +"\n" +" Example:\n" +"\n" +" 'dblock 23' - sets the file position to the 23rd filesystem block in\n" +" the inode's data fork. The filesystem block size is specified in the\n" +" superblock.\n" +"\n" msgstr "" -#: .././db/check.c:1023 .././db/check.c:1180 -msgid "must run blockget first\n" +#: .././db/block.c:185 +msgid "no type for file data\n" msgstr "" -#: .././db/check.c:1067 -#, c-format -msgid "bad blocktrash count %s\n" +#: .././db/block.c:192 +msgid "file data block is unmapped\n" msgstr "" -#: .././db/check.c:1081 -#, c-format -msgid "bad blocktrash type %s\n" +#: .././db/block.c:210 +msgid "" +"\n" +" Example:\n" +"\n" +" 'fsblock 1023' - sets the file position to the 1023rd filesystem block.\n" +" The filesystem block size is specified in the superblock and set during\n" +" mkfs time. Offset is absolute (not AG relative).\n" +"\n" msgstr "" -#: .././db/check.c:1090 +#: .././db/block.c:229 #, c-format -msgid "bad blocktrash min %s\n" +msgid "current fsblock is %lld\n" msgstr "" -#: .././db/check.c:1098 +#: .././db/block.c:235 .././db/block.c:241 #, c-format -msgid "bad blocktrash max %s\n" +msgid "bad fsblock %s\n" msgstr "" -#: .././db/check.c:1103 -msgid "bad option for blocktrash command\n" +#: .././db/attrset.c:38 +msgid "[-r|-s|-p|-u] [-n] [-R|-C] [-v n] name" msgstr "" -#: .././db/check.c:1108 -msgid "bad min/max for blocktrash command\n" +#: .././db/attrset.c:39 +msgid "set the named attribute on the current inode" msgstr "" -#: .././db/check.c:1134 -msgid "blocktrash: no matching blocks\n" +#: .././db/attrset.c:42 +msgid "[-r|-s|-p|-u] [-n] name" msgstr "" -#: .././db/check.c:1138 -#, c-format -msgid "blocktrash: seed %u\n" +#: .././db/attrset.c:43 +msgid "remove the named attribute from the current inode" msgstr "" -#: .././db/check.c:1196 -#, c-format -msgid "bad blockuse count %s\n" +#: .././db/attrset.c:49 +msgid "" +"\n" +" The 'attr_set' and 'attr_remove' commands provide interfaces for debugging\n" +" the extended attribute allocation and removal code.\n" +" Both commands require an attribute name to be specified, and the attr_set\n" +" command allows an optional value length (-v) to be provided as well.\n" +" There are 4 namespace flags:\n" +" -r -- 'root'\n" +" -u -- 'user'\t\t(default)\n" +" -s -- 'secure'\n" +"\n" +" For attr_set, these options further define the type of set operation:\n" +" -C -- 'create' - create attribute, fail if it already exists\n" +" -R -- 'replace' - replace attribute, fail if it does not exist\n" +" The backward compatibility mode 'noattr2' can be emulated (-n) also.\n" +"\n" msgstr "" -#: .././db/check.c:1202 .././db/check.c:1887 -msgid "must run blockget -n first\n" +#: .././db/attrset.c:86 .././db/attrset.c:189 .././db/print.c:74 +#: .././db/addr.c:72 .././db/type.c:142 .././db/write.c:101 +msgid "no current type\n" msgstr "" -#: .././db/check.c:1208 -msgid "bad option for blockuse command\n" +#: .././db/attrset.c:90 .././db/attrset.c:193 +msgid "current type is not inode\n" msgstr "" -#: .././db/check.c:1215 +#: .././db/attrset.c:125 #, c-format -msgid "block %llu (%u/%u) type %s" +msgid "bad attr_set valuelen %s\n" msgstr "" -#: .././db/check.c:1219 -#, c-format -msgid " inode %lld" +#: .././db/attrset.c:131 +msgid "bad option for attr_set command\n" msgstr "" -#: .././db/check.c:1257 -#, c-format -msgid "block %u/%u expected type %s got %s\n" +#: .././db/attrset.c:137 +msgid "too few options for attr_set (no name given)\n" msgstr "" -#: .././db/check.c:1289 +#: .././db/attrset.c:146 #, c-format -msgid "blocks %u/%u..%u claimed by inode %lld\n" +msgid "cannot allocate buffer (%d)\n" msgstr "" -#: .././db/check.c:1297 +#: .././db/attrset.c:155 .././db/attrset.c:230 #, c-format -msgid "block %u/%u claimed by inode %lld, previous inum %lld\n" +msgid "failed to iget inode %llu\n" msgstr "" -#: .././db/check.c:1326 +#: .././db/attrset.c:162 #, c-format -msgid "link count mismatch for inode %lld (name %s), nlink %d, counted %d\n" +msgid "failed to set attr %s on inode %llu\n" msgstr "" -#: .././db/check.c:1334 -#, c-format -msgid "disconnected inode %lld, nlink %d\n" +#: .././db/attrset.c:217 +msgid "bad option for attr_remove command\n" msgstr "" -#: .././db/check.c:1338 -#, c-format -msgid "allocated inode %lld has 0 link count\n" +#: .././db/attrset.c:223 +msgid "too few options for attr_remove (no name given)\n" msgstr "" -#: .././db/check.c:1348 +#: .././db/attrset.c:236 #, c-format -msgid "inode %lld name %s\n" +msgid "failed to remove attr %s from inode %llu\n" msgstr "" -#: .././db/check.c:1382 .././db/check.c:1397 +#: .././db/command.c:82 .././db/help.c:56 .././libxcmd/help.c:49 #, c-format -msgid "block %u/%u out of range\n" +msgid "command %s not found\n" msgstr "" -#: .././db/check.c:1385 .././db/check.c:1400 +#: .././db/command.c:86 #, c-format -msgid "blocks %u/%u..%u out of range\n" +msgid "bad argument count %d to %s, expected " msgstr "" -#: .././db/check.c:1423 +#: .././db/command.c:88 #, c-format -msgid "rtblock %llu expected type %s got %s\n" +msgid "at least %d" msgstr "" -#: .././db/check.c:1443 +#: .././db/command.c:92 #, c-format -msgid "rtblocks %llu..%llu claimed by inode %lld\n" +msgid "between %d and %d" msgstr "" -#: .././db/check.c:1452 -#, c-format -msgid "rtblock %llu claimed by inode %lld, previous inum %lld\n" +#: .././db/command.c:93 +msgid " arguments\n" msgstr "" -#: .././db/check.c:1470 +#: .././db/debug.c:27 +msgid "[flagbits]" +msgstr "" + +#: .././db/debug.c:28 +msgid "set debug option bits" +msgstr "" + +#: .././db/debug.c:42 +#, c-format +msgid "bad value for debug %s\n" +msgstr "" + +#: .././db/check.c:362 +msgid "free block usage information" +msgstr "" + +#: .././db/check.c:365 +msgid "[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..." +msgstr "" + +#: .././db/check.c:366 +msgid "get block usage and check consistency" +msgstr "" + +#: .././db/check.c:369 +msgid "[-n count] [-x minlen] [-y maxlen] [-s seed] [-0123] [-t type] ..." +msgstr "" + +#: .././db/check.c:370 +msgid "trash randomly selected block(s)" +msgstr "" + +#: .././db/check.c:373 +msgid "[-n] [-c blockcount]" +msgstr "" + +#: .././db/check.c:374 +msgid "print usage for current block(s)" +msgstr "" + +#: .././db/check.c:377 +msgid "[-s] [-i ino] ..." +msgstr "" + +#: .././db/check.c:378 +msgid "print inode-name pairs" +msgstr "" + +#: .././db/check.c:398 +#, c-format +msgid "-i %lld bad inode number\n" +msgstr "" + +#: .././db/check.c:410 +#, c-format +msgid "inode %lld add link, now %u\n" +msgstr "" + +#: .././db/check.c:437 +#, c-format +msgid "inode %lld parent %lld\n" +msgstr "" + +#: .././db/check.c:750 +msgid "block usage information not allocated\n" +msgstr "" + +#: .././db/check.c:788 +msgid "already have block usage information\n" +msgstr "" + +#: .././db/check.c:818 .././db/check.c:926 +msgid "WARNING: this may be a newer XFS filesystem.\n" +msgstr "" + +#: .././db/check.c:854 +#, c-format +msgid "sb_icount %lld, counted %lld\n" +msgstr "" + +#: .././db/check.c:860 +#, c-format +msgid "sb_ifree %lld, counted %lld\n" +msgstr "" + +#: .././db/check.c:866 +#, c-format +msgid "sb_fdblocks %lld, counted %lld\n" +msgstr "" + +#: .././db/check.c:872 +#, c-format +msgid "sb_fdblocks %lld, aggregate AGF count %lld\n" +msgstr "" + +#: .././db/check.c:878 +#, c-format +msgid "sb_frextents %lld, counted %lld\n" +msgstr "" + +#: .././db/check.c:885 +#, c-format +msgid "sb_features2 (0x%x) not same as sb_bad_features2 (0x%x)\n" +msgstr "" + +#: .././db/check.c:894 +#, c-format +msgid "sb versionnum missing attr bit %x\n" +msgstr "" + +#: .././db/check.c:901 +#, c-format +msgid "sb versionnum missing nlink bit %x\n" +msgstr "" + +#: .././db/check.c:908 +#, c-format +msgid "sb versionnum missing quota bit %x\n" +msgstr "" + +#: .././db/check.c:915 +#, c-format +msgid "sb versionnum extra align bit %x\n" +msgstr "" + +#: .././db/check.c:955 +msgid "zeroed" +msgstr "" + +#: .././db/check.c:955 +msgid "set" +msgstr "" + +#: .././db/check.c:955 +msgid "flipped" +msgstr "" + +#: .././db/check.c:955 +msgid "randomized" +msgstr "" + +#: .././db/check.c:965 +#, c-format +msgid "can't read block %u/%u for trashing\n" +msgstr "" + +#: .././db/check.c:995 +#, c-format +msgid "blocktrash: %u/%u %s block %d bit%s starting %d:%d %s\n" +msgstr "" + +#: .././db/check.c:1027 .././db/check.c:1185 +msgid "must run blockget first\n" +msgstr "" + +#: .././db/check.c:1071 +#, c-format +msgid "bad blocktrash count %s\n" +msgstr "" + +#: .././db/check.c:1085 +#, c-format +msgid "bad blocktrash type %s\n" +msgstr "" + +#: .././db/check.c:1094 +#, c-format +msgid "bad blocktrash min %s\n" +msgstr "" + +#: .././db/check.c:1102 +#, c-format +msgid "bad blocktrash max %s\n" +msgstr "" + +#: .././db/check.c:1107 +msgid "bad option for blocktrash command\n" +msgstr "" + +#: .././db/check.c:1112 +msgid "bad min/max for blocktrash command\n" +msgstr "" + +#: .././db/check.c:1138 +msgid "blocktrash: no matching blocks\n" +msgstr "" + +#: .././db/check.c:1142 +#, c-format +msgid "blocktrash: seed %u\n" +msgstr "" + +#: .././db/check.c:1200 +#, c-format +msgid "bad blockuse count %s\n" +msgstr "" + +#: .././db/check.c:1206 .././db/check.c:1892 +msgid "must run blockget -n first\n" +msgstr "" + +#: .././db/check.c:1212 +msgid "bad option for blockuse command\n" +msgstr "" + +#: .././db/check.c:1219 +#, c-format +msgid "block %llu (%u/%u) type %s" +msgstr "" + +#: .././db/check.c:1223 +#, c-format +msgid " inode %lld" +msgstr "" + +#: .././db/check.c:1261 +#, c-format +msgid "block %u/%u expected type %s got %s\n" +msgstr "" + +#: .././db/check.c:1293 +#, c-format +msgid "blocks %u/%u..%u claimed by inode %lld\n" +msgstr "" + +#: .././db/check.c:1301 +#, c-format +msgid "block %u/%u claimed by inode %lld, previous inum %lld\n" +msgstr "" + +#: .././db/check.c:1330 +#, c-format +msgid "link count mismatch for inode %lld (name %s), nlink %d, counted %d\n" +msgstr "" + +#: .././db/check.c:1338 +#, c-format +msgid "disconnected inode %lld, nlink %d\n" +msgstr "" + +#: .././db/check.c:1342 +#, c-format +msgid "allocated inode %lld has 0 link count\n" +msgstr "" + +#: .././db/check.c:1352 +#, c-format +msgid "inode %lld name %s\n" +msgstr "" + +#: .././db/check.c:1386 .././db/check.c:1401 +#, c-format +msgid "block %u/%u out of range\n" +msgstr "" + +#: .././db/check.c:1389 .././db/check.c:1404 +#, c-format +msgid "blocks %u/%u..%u out of range\n" +msgstr "" + +#: .././db/check.c:1427 +#, c-format +msgid "rtblock %llu expected type %s got %s\n" +msgstr "" + +#: .././db/check.c:1447 +#, c-format +msgid "rtblocks %llu..%llu claimed by inode %lld\n" +msgstr "" + +#: .././db/check.c:1456 +#, c-format +msgid "rtblock %llu claimed by inode %lld, previous inum %lld\n" +msgstr "" + +#: .././db/check.c:1474 #, c-format msgid "root inode %lld is missing\n" msgstr "" -#: .././db/check.c:1475 +#: .././db/check.c:1479 #, c-format msgid "root inode %lld is not a directory\n" msgstr "" -#: .././db/check.c:1491 +#: .././db/check.c:1495 #, c-format msgid "rtblock %llu out of range\n" msgstr "" -#: .././db/check.c:1515 +#: .././db/check.c:1519 #, c-format msgid "blocks %u/%u..%u claimed by block %u/%u\n" msgstr "" -#: .././db/check.c:1524 +#: .././db/check.c:1528 #, c-format msgid "setting block %u/%u to %s\n" msgstr "" -#: .././db/check.c:1547 +#: .././db/check.c:1551 #, c-format msgid "setting rtblock %llu to %s\n" msgstr "" -#: .././db/check.c:1568 .././repair/rt.c:151 +#: .././db/check.c:1572 .././repair/rt.c:151 #, c-format msgid "rt summary mismatch, size %d block %llu, file: %d, computed: %d\n" msgstr "" -#: .././db/check.c:1593 +#: .././db/check.c:1597 #, c-format msgid "block %u/%u type %s not expected\n" msgstr "" -#: .././db/check.c:1614 +#: .././db/check.c:1618 #, c-format msgid "rtblock %llu type %s not expected\n" msgstr "" -#: .././db/check.c:1651 +#: .././db/check.c:1655 #, c-format msgid "dir ino %lld missing leaf entry for %x/%x\n" msgstr "" -#: .././db/check.c:1770 +#: .././db/check.c:1774 #, c-format msgid "bad superblock magic number %x, giving up\n" msgstr "" -#: .././db/check.c:1824 +#: .././db/check.c:1828 msgid "bad option for blockget command\n" msgstr "" -#: .././db/check.c:1904 +#: .././db/check.c:1909 #, c-format msgid "bad option -%c for ncheck command\n" msgstr "" -#: .././db/check.c:1977 .././db/check.c:2946 +#: .././db/check.c:1983 #, c-format msgid "block 0 for directory inode %lld is missing\n" msgstr "" -#: .././db/check.c:1997 .././db/check.c:2957 +#: .././db/check.c:2003 #, c-format msgid "can't read block 0 for directory inode %lld\n" msgstr "" -#: .././db/check.c:2043 +#: .././db/check.c:2049 #, c-format msgid "inode %lld extent [%lld,%lld,%lld,%d]\n" msgstr "" -#: .././db/check.c:2046 +#: .././db/check.c:2052 #, c-format msgid "bmap rec out of order, inode %lld entry %d\n" msgstr "" -#: .././db/check.c:2052 +#: .././db/check.c:2058 #, c-format msgid "inode %lld bad rt block number %lld, offset %lld\n" msgstr "" -#: .././db/check.c:2062 .././db/check.c:2068 +#: .././db/check.c:2068 .././db/check.c:2074 #, c-format msgid "inode %lld bad block number %lld [%d,%d], offset %lld\n" msgstr "" -#: .././db/check.c:2086 .././db/check.c:2100 +#: .././db/check.c:2092 .././db/check.c:2106 #, c-format msgid "inode %lld block %lld at offset %lld\n" msgstr "" -#: .././db/check.c:2127 +#: .././db/check.c:2133 #, c-format msgid "level for ino %lld %s fork bmap root too large (%u)\n" msgstr "" -#: .././db/check.c:2130 .././db/check.c:2142 .././db/check.c:2169 -#: .././db/bmap.c:216 .././repair/scan.c:184 .././repair/dinode.c:568 -#: .././repair/dinode.c:1135 -msgid "data" -msgstr "" - -#: .././db/check.c:2130 .././db/check.c:2142 .././db/check.c:2169 -#: .././db/bmap.c:216 .././repair/scan.c:186 .././repair/dinode.c:570 -#: .././repair/dinode.c:1137 -msgid "attr" -msgstr "" - -#: .././db/check.c:2139 +#: .././db/check.c:2145 #, c-format msgid "numrecs for ino %lld %s fork bmap root too large (%u)\n" msgstr "" -#: .././db/check.c:2166 +#: .././db/check.c:2172 #, c-format msgid "extent count for ino %lld %s fork too low (%d) for file format\n" msgstr "" -#: .././db/check.c:2216 .././db/check.c:3297 +#: .././db/check.c:2222 .././db/check.c:3153 #, c-format msgid "bad directory data magic # %#x for dir ino %lld block %d\n" msgstr "" -#: .././db/check.c:2233 +#: .././db/check.c:2239 #, c-format msgid "bad block directory tail for dir ino %lld\n" msgstr "" -#: .././db/check.c:2278 +#: .././db/check.c:2284 #, c-format msgid "dir %lld block %d bad free entry at %d\n" msgstr "" -#: .././db/check.c:2302 +#: .././db/check.c:2308 #, c-format msgid "dir %lld block %d zero length entry at %d\n" msgstr "" -#: .././db/check.c:2311 +#: .././db/check.c:2317 #, c-format msgid "dir %lld block %d bad entry at %d\n" msgstr "" -#: .././db/check.c:2329 +#: .././db/check.c:2335 #, c-format msgid "dir %lld block %d entry %*.*s %lld\n" msgstr "" -#: .././db/check.c:2336 +#: .././db/check.c:2342 #, c-format msgid "dir %lld block %d entry %*.*s bad inode number %lld\n" msgstr "" -#: .././db/check.c:2346 .././db/check.c:3020 +#: .././db/check.c:2352 #, c-format msgid "multiple .. entries in dir %lld (%lld, %lld)\n" msgstr "" -#: .././db/check.c:2363 .././db/check.c:3037 +#: .././db/check.c:2369 #, c-format msgid "dir %lld entry . inode number mismatch (%lld)\n" msgstr "" -#: .././db/check.c:2376 +#: .././db/check.c:2382 #, c-format msgid "dir %lld block %d bad count %u\n" msgstr "" -#: .././db/check.c:2387 .././db/check.c:3311 +#: .././db/check.c:2393 .././db/check.c:3167 #, c-format msgid "dir %lld block %d extra leaf entry %x %x\n" msgstr "" -#: .././db/check.c:2399 +#: .././db/check.c:2405 #, c-format msgid "dir %lld block %d bad bestfree data\n" msgstr "" -#: .././db/check.c:2407 +#: .././db/check.c:2412 #, c-format msgid "dir %lld block %d bad block tail count %d (stale %d)\n" msgstr "" -#: .././db/check.c:2416 +#: .././db/check.c:2421 #, c-format msgid "dir %lld block %d bad stale tail count %d\n" msgstr "" -#: .././db/check.c:2422 +#: .././db/check.c:2427 #, c-format msgid "dir %lld block %d consecutive free entries\n" msgstr "" -#: .././db/check.c:2428 +#: .././db/check.c:2433 #, c-format msgid "dir %lld block %d entry/unused tag mismatch\n" msgstr "" -#: .././db/check.c:2481 +#: .././db/check.c:2482 #, c-format msgid "no . entry for directory %lld\n" msgstr "" -#: .././db/check.c:2486 +#: .././db/check.c:2487 #, c-format msgid "no .. entry for directory %lld\n" msgstr "" -#: .././db/check.c:2490 +#: .././db/check.c:2491 #, c-format msgid ". and .. same for non-root directory %lld\n" msgstr "" -#: .././db/check.c:2495 +#: .././db/check.c:2496 #, c-format msgid "root directory %lld has .. %lld\n" msgstr "" -#: .././db/check.c:2525 .././db/check.c:2560 +#: .././db/check.c:2529 #, c-format msgid "bad size (%lld) or format (%d) for directory inode %lld\n" msgstr "" -#: .././db/check.c:2588 +#: .././db/check.c:2557 #, c-format msgid "bad number of extents %d for inode %lld\n" msgstr "" -#: .././db/check.c:2660 +#: .././db/check.c:2629 #, c-format msgid "bad magic number %#x for inode %lld\n" msgstr "" -#: .././db/check.c:2667 +#: .././db/check.c:2636 #, c-format msgid "bad version number %#x for inode %lld\n" msgstr "" -#: .././db/check.c:2675 +#: .././db/check.c:2644 #, c-format msgid "bad nblocks %lld for free inode %lld\n" msgstr "" -#: .././db/check.c:2686 +#: .././db/check.c:2655 #, c-format msgid "bad nlink %d for free inode %lld\n" msgstr "" -#: .././db/check.c:2692 +#: .././db/check.c:2661 #, c-format msgid "bad mode %#o for free inode %lld\n" msgstr "" -#: .././db/check.c:2701 +#: .././db/check.c:2670 #, c-format msgid "bad next unlinked %#x for inode %lld\n" msgstr "" -#: .././db/check.c:2711 +#: .././db/check.c:2680 #, c-format msgid "bad format %d for inode %lld type %#o\n" msgstr "" -#: .././db/check.c:2718 +#: .././db/check.c:2688 #, c-format msgid "bad fork offset %d for inode %lld\n" msgstr "" -#: .././db/check.c:2725 +#: .././db/check.c:2695 #, c-format msgid "bad attribute format %d for inode %lld\n" msgstr "" -#: .././db/check.c:2731 +#: .././db/check.c:2701 #, c-format msgid "" "inode %lld mode %#o fmt %s afmt %s nex %d anex %d nblk %lld sz %lld%s%s%s%s%s" "%s%s\n" msgstr "" -#: .././db/check.c:2851 +#: .././db/check.c:2822 #, c-format msgid "bad nblocks %lld for inode %lld, counted %lld\n" msgstr "" -#: .././db/check.c:2858 +#: .././db/check.c:2829 #, c-format msgid "bad nextents %d for inode %lld, counted %d\n" msgstr "" -#: .././db/check.c:2864 +#: .././db/check.c:2835 #, c-format msgid "bad anextents %d for inode %lld, counted %d\n" msgstr "" -#: .././db/check.c:2916 +#: .././db/check.c:2887 #, c-format msgid "local inode %lld data is too large (size %lld)\n" msgstr "" -#: .././db/check.c:2925 +#: .././db/check.c:2896 #, c-format msgid "local inode %lld attr is too large (size %d)\n" msgstr "" -#: .././db/check.c:2990 -#, c-format -msgid "bad directory leaf magic # %#x for dir ino %lld\n" -msgstr "" - -#: .././db/check.c:3003 .././db/check.c:3768 -#, c-format -msgid "dir %lld entry %*.*s %lld\n" -msgstr "" - -#: .././db/check.c:3010 .././db/check.c:3664 .././db/check.c:3756 -#, c-format -msgid "dir %lld entry %*.*s bad inode number %lld\n" -msgstr "" - -#: .././db/check.c:3089 .././db/check.c:3358 +#: .././db/check.c:2945 #, c-format msgid "dir inode %lld block %u=%llu\n" msgstr "" -#: .././db/check.c:3101 .././db/check.c:3368 +#: .././db/check.c:2957 #, c-format msgid "can't read block %u for directory inode %lld\n" msgstr "" -#: .././db/check.c:3115 .././db/check.c:3381 +#: .././db/check.c:2971 #, c-format msgid "multiple .. entries in dir %lld\n" msgstr "" -#: .././db/check.c:3137 +#: .././db/check.c:2993 #, c-format msgid "missing free index for data block %d in dir ino %lld\n" msgstr "" -#: .././db/check.c:3163 +#: .././db/check.c:3019 #, c-format msgid "bad free block magic # %#x for dir ino %lld block %d\n" msgstr "" -#: .././db/check.c:3173 +#: .././db/check.c:3029 #, c-format msgid "bad free block firstdb %d for dir ino %lld block %d\n" msgstr "" -#: .././db/check.c:3186 +#: .././db/check.c:3042 #, c-format msgid "bad free block nvalid/nused %d/%d for dir ino %lld block %d\n" msgstr "" -#: .././db/check.c:3200 +#: .././db/check.c:3056 #, c-format msgid "bad free block ent %d is %d should be %d for dir ino %lld block %d\n" msgstr "" -#: .././db/check.c:3214 +#: .././db/check.c:3070 #, c-format msgid "bad free block nused %d should be %d for dir ino %lld block %d\n" msgstr "" -#: .././db/check.c:3243 +#: .././db/check.c:3100 #, c-format msgid "bad leaf block forw/back pointers %d/%d for dir ino %lld block %d\n" msgstr "" -#: .././db/check.c:3252 +#: .././db/check.c:3109 #, c-format msgid "single leaf block for dir ino %lld block %d should be at block %d\n" msgstr "" -#: .././db/check.c:3264 +#: .././db/check.c:3121 #, c-format msgid "bestfree %d for dir ino %lld block %d doesn't match table value %d\n" msgstr "" -#: .././db/check.c:3288 +#: .././db/check.c:3144 #, c-format msgid "bad node block level %d for dir ino %lld block %d\n" msgstr "" -#: .././db/check.c:3320 +#: .././db/check.c:3176 #, c-format msgid "dir %lld block %d stale mismatch %d/%d\n" msgstr "" -#: .././db/check.c:3352 -#, c-format -msgid "can't read root block for directory inode %lld\n" -msgstr "" - -#: .././db/check.c:3441 +#: .././db/check.c:3232 #, c-format msgid "can't read block %lld for %s quota inode (fsblock %lld)\n" msgstr "" -#: .././db/check.c:3451 +#: .././db/check.c:3242 #, c-format msgid "%s dqblk %lld entry %d id %u bc %lld ic %lld rc %lld\n" msgstr "" -#: .././db/check.c:3459 +#: .././db/check.c:3250 #, c-format msgid "bad magic number %#x for %s dqblk %lld entry %d id %u\n" msgstr "" -#: .././db/check.c:3468 +#: .././db/check.c:3259 #, c-format msgid "bad version number %#x for %s dqblk %lld entry %d id %u\n" msgstr "" -#: .././db/check.c:3478 +#: .././db/check.c:3269 #, c-format msgid "bad flags %#x for %s dqblk %lld entry %d id %u\n" msgstr "" -#: .././db/check.c:3487 +#: .././db/check.c:3278 #, c-format msgid "bad id %u for %s dqblk %lld entry %d id %u\n" msgstr "" -#: .././db/check.c:3533 +#: .././db/check.c:3324 #, c-format msgid "block %lld for rtbitmap inode is missing\n" msgstr "" -#: .././db/check.c:3544 +#: .././db/check.c:3335 #, c-format msgid "can't read block %lld for rtbitmap inode\n" msgstr "" -#: .././db/check.c:3600 +#: .././db/check.c:3391 #, c-format msgid "block %lld for rtsummary inode is missing\n" msgstr "" -#: .././db/check.c:3611 +#: .././db/check.c:3402 #, c-format msgid "can't read block %lld for rtsummary inode\n" msgstr "" -#: .././db/check.c:3644 .././db/check.c:3748 +#: .././db/check.c:3435 #, c-format msgid "dir %lld entry . %lld\n" msgstr "" -#: .././db/check.c:3652 +#: .././db/check.c:3443 #, c-format msgid "dir %llu bad size in entry at %d\n" msgstr "" -#: .././db/check.c:3676 +#: .././db/check.c:3455 +#, c-format +msgid "dir %lld entry %*.*s bad inode number %lld\n" +msgstr "" + +#: .././db/check.c:3467 #, c-format msgid "dir %lld entry %*.*s offset %d %lld\n" msgstr "" -#: .././db/check.c:3681 +#: .././db/check.c:3472 #, c-format msgid "dir %lld entry %*.*s bad offset %d\n" msgstr "" -#: .././db/check.c:3694 +#: .././db/check.c:3485 #, c-format msgid "dir %llu size is %lld, should be %u\n" msgstr "" -#: .././db/check.c:3702 +#: .././db/check.c:3493 #, c-format msgid "dir %llu offsets too high\n" msgstr "" -#: .././db/check.c:3713 .././db/check.c:3782 +#: .././db/check.c:3504 #, c-format msgid "dir %lld entry .. bad inode number %lld\n" msgstr "" -#: .././db/check.c:3718 .././db/check.c:3787 +#: .././db/check.c:3509 #, c-format msgid "dir %lld entry .. %lld\n" msgstr "" -#: .././db/check.c:3721 +#: .././db/check.c:3512 #, c-format msgid "dir %lld i8count mismatch is %d should be %d\n" msgstr "" -#: .././db/check.c:3773 -#, c-format -msgid "dir %llu size is %lld, should be %d\n" -msgstr "" - -#: .././db/check.c:3864 +#: .././db/check.c:3594 #, c-format msgid "%s quota id %u, have/exp" msgstr "" -#: .././db/check.c:3867 +#: .././db/check.c:3597 #, c-format msgid " bc %lld/%lld" msgstr "" -#: .././db/check.c:3871 +#: .././db/check.c:3601 #, c-format msgid " ic %lld/%lld" msgstr "" -#: .././db/check.c:3875 +#: .././db/check.c:3605 #, c-format msgid " rc %lld/%lld" msgstr "" -#: .././db/check.c:3931 +#: .././db/check.c:3661 #, c-format msgid "can't read superblock for ag %u\n" msgstr "" -#: .././db/check.c:3940 +#: .././db/check.c:3670 #, c-format msgid "bad sb magic # %#x in ag %u\n" msgstr "" -#: .././db/check.c:3946 +#: .././db/check.c:3676 #, c-format msgid "bad sb version # %#x in ag %u\n" msgstr "" -#: .././db/check.c:3956 .././db/sb.c:201 +#: .././db/check.c:3686 .././db/sb.c:213 msgid "mkfs not completed successfully\n" msgstr "" -#: .././db/check.c:3968 .././db/frag.c:365 +#: .././db/check.c:3698 .././db/frag.c:366 #, c-format msgid "can't read agf block for ag %u\n" msgstr "" -#: .././db/check.c:3974 +#: .././db/check.c:3704 #, c-format msgid "bad agf magic # %#x in ag %u\n" msgstr "" -#: .././db/check.c:3980 +#: .././db/check.c:3710 #, c-format msgid "bad agf version # %#x in ag %u\n" msgstr "" -#: .././db/check.c:3996 .././db/frag.c:374 +#: .././db/check.c:3726 .././db/frag.c:375 #, c-format msgid "can't read agi block for ag %u\n" msgstr "" -#: .././db/check.c:4002 +#: .././db/check.c:3732 #, c-format msgid "bad agi magic # %#x in ag %u\n" msgstr "" -#: .././db/check.c:4008 +#: .././db/check.c:3738 #, c-format msgid "bad agi version # %#x in ag %u\n" msgstr "" -#: .././db/check.c:4033 .././repair/scan.c:1121 +#: .././db/check.c:3763 .././repair/scan.c:1383 #, c-format msgid "agf_freeblks %u, counted %u in ag %u\n" msgstr "" -#: .././db/check.c:4040 .././repair/scan.c:1126 +#: .././db/check.c:3770 .././repair/scan.c:1388 #, c-format msgid "agf_longest %u, counted %u in ag %u\n" msgstr "" -#: .././db/check.c:4048 +#: .././db/check.c:3778 #, c-format msgid "agf_btreeblks %u, counted %u in ag %u\n" msgstr "" -#: .././db/check.c:4056 .././repair/scan.c:1156 +#: .././db/check.c:3786 .././repair/scan.c:1436 #, c-format msgid "agi_count %u, counted %u in ag %u\n" msgstr "" -#: .././db/check.c:4063 .././repair/scan.c:1161 +#: .././db/check.c:3793 .././repair/scan.c:1441 #, c-format msgid "agi_freecount %u, counted %u in ag %u\n" msgstr "" -#: .././db/check.c:4072 +#: .././db/check.c:3802 #, c-format msgid "agi unlinked bucket %d is %u in ag %u (inode=%lld)\n" msgstr "" -#: .././db/check.c:4109 +#: .././db/check.c:3840 #, c-format msgid "can't read agfl block for ag %u\n" msgstr "" -#: .././db/check.c:4128 +#: .././db/check.c:3850 .././db/freesp.c:255 .././repair/scan.c:1319 #, c-format -msgid "freeblk count %u != flcount %u in ag %u\n" +msgid "agf %d freelist blocks bad, skipping freelist scan\n" msgstr "" -#: .././db/check.c:4157 .././db/check.c:4185 .././db/frag.c:397 -#: .././db/frag.c:420 .././db/freesp.c:270 +#: .././db/check.c:3872 #, c-format -msgid "can't read btree block %u/%u\n" +msgid "freeblk count %u != flcount %u in ag %u\n" +msgstr "" + +#: .././db/check.c:3901 .././db/check.c:3929 .././db/freesp.c:289 +#: .././db/frag.c:398 .././db/frag.c:421 +#, c-format +msgid "can't read btree block %u/%u\n" msgstr "" -#: .././db/check.c:4218 +#: .././db/check.c:3962 #, c-format msgid "bad magic # %#x in inode %lld bmbt block %u/%u\n" msgstr "" -#: .././db/check.c:4225 +#: .././db/check.c:3969 #, c-format msgid "expected level %d got %d in inode %lld bmbt block %u/%u\n" msgstr "" -#: .././db/check.c:4237 .././db/check.c:4254 +#: .././db/check.c:3981 .././db/check.c:3998 #, c-format msgid "bad btree nrecs (%u, min=%u, max=%u) in inode %lld bmap block %lld\n" msgstr "" -#: .././db/check.c:4282 +#: .././db/check.c:4026 #, c-format msgid "bad magic # %#x in btbno block %u/%u\n" msgstr "" -#: .././db/check.c:4291 +#: .././db/check.c:4035 #, c-format msgid "expected level %d got %d in btbno block %u/%u\n" msgstr "" -#: .././db/check.c:4300 .././db/check.c:4328 .././db/check.c:4373 -#: .././db/check.c:4404 +#: .././db/check.c:4044 .././db/check.c:4072 .././db/check.c:4117 +#: .././db/check.c:4148 #, c-format msgid "bad btree nrecs (%u, min=%u, max=%u) in btbno block %u/%u\n" msgstr "" -#: .././db/check.c:4315 .././repair/scan.c:621 +#: .././db/check.c:4059 .././repair/scan.c:630 #, c-format msgid "out-of-order bno btree record %d (%u %u) block %u/%u\n" msgstr "" -#: .././db/check.c:4355 +#: .././db/check.c:4099 #, c-format msgid "bad magic # %#x in btcnt block %u/%u\n" msgstr "" -#: .././db/check.c:4364 +#: .././db/check.c:4108 #, c-format msgid "expected level %d got %d in btcnt block %u/%u\n" msgstr "" -#: .././db/check.c:4392 .././repair/scan.c:633 +#: .././db/check.c:4136 .././repair/scan.c:642 #, c-format msgid "out-of-order cnt btree record %d (%u %u) block %u/%u\n" msgstr "" -#: .././db/check.c:4435 +#: .././db/check.c:4179 #, c-format msgid "bad magic # %#x in inobt block %u/%u\n" msgstr "" -#: .././db/check.c:4442 +#: .././db/check.c:4186 #, c-format msgid "expected level %d got %d in inobt block %u/%u\n" msgstr "" -#: .././db/check.c:4451 .././db/check.c:4517 +#: .././db/check.c:4195 .././db/check.c:4261 #, c-format msgid "bad btree nrecs (%u, min=%u, max=%u) in inobt block %u/%u\n" msgstr "" -#: .././db/check.c:4486 .././db/frag.c:489 +#: .././db/check.c:4230 .././db/frag.c:490 #, c-format msgid "can't read inode block %u/%u\n" msgstr "" -#: .././db/check.c:4504 +#: .././db/check.c:4248 #, c-format msgid "ir_freecount/free mismatch, inode chunk %u/%u, freecount %d nfree %d\n" msgstr "" -#: .././db/check.c:4559 +#: .././db/check.c:4303 #, c-format msgid "setting inode to %lld for block %u/%u\n" msgstr "" -#: .././db/check.c:4591 +#: .././db/check.c:4335 #, c-format msgid "setting inode to %lld for rtblock %llu\n" msgstr "" -#: .././db/check.c:4607 +#: .././db/check.c:4351 #, c-format msgid "inode %lld nlink %u %s dir\n" msgstr "" -#: .././db/convert.c:171 -#, c-format -msgid "bad argument count %d to convert, expected 3,5,7,9 arguments\n" +#: .././db/echo.c:27 +msgid "[args]..." msgstr "" -#: .././db/convert.c:176 .././db/convert.c:183 -#, c-format -msgid "unknown conversion type %s\n" +#: .././db/echo.c:28 +msgid "echo arguments" msgstr "" -#: .././db/convert.c:187 -msgid "result type same as argument\n" +#: .././db/faddr.c:40 .././db/faddr.c:63 +msgid "no current allocation group, cannot set new addr\n" msgstr "" -#: .././db/convert.c:191 -#, c-format -msgid "conflicting conversion type %s\n" +#: .././db/faddr.c:45 .././db/faddr.c:117 .././db/faddr.c:148 +#: .././db/faddr.c:180 .././db/faddr.c:202 .././db/faddr.c:232 +#: .././db/faddr.c:262 .././db/faddr.c:316 .././db/faddr.c:335 +msgid "null block number, cannot set new addr\n" msgstr "" -#: .././db/convert.c:270 -#, c-format -msgid "%s is not a number\n" +#: .././db/faddr.c:68 .././db/faddr.c:353 .././db/faddr.c:371 +#: .././db/faddr.c:389 +msgid "null inode number, cannot set new addr\n" msgstr "" -#: .././db/metadump.c:55 -msgid "[-e] [-g] [-m max_extent] [-w] [-o] filename" +#: .././db/faddr.c:88 +msgid "null attribute block number, cannot set new addr\n" msgstr "" -#: .././db/metadump.c:56 -msgid "dump metadata to a file" +#: .././db/faddr.c:94 +msgid "attribute block is unmapped\n" msgstr "" -#: .././db/metadump.c:86 -#, c-format -msgid "" -"\n" -" The 'metadump' command dumps the known metadata to a compact file suitable\n" -" for compressing and sending to an XFS maintainer for corruption analysis \n" -" or xfs_repair failures.\n" -"\n" -" Options:\n" -" -e -- Ignore read errors and keep going\n" -" -g -- Display dump progress\n" -" -m -- Specify max extent size in blocks to copy (default = %d blocks)\n" -" -o -- Don't obfuscate names and extended attributes\n" -" -w -- Show warnings of bad metadata information\n" -"\n" +#: .././db/faddr.c:123 .././db/faddr.c:155 .././db/faddr.c:208 +#: .././db/faddr.c:239 +msgid "file block is unmapped\n" msgstr "" -#: .././db/frag.c:173 -#, c-format -msgid "actual %llu, ideal %llu, fragmentation factor %.2f%%\n" +#: .././db/faddr.c:285 +msgid "null directory block number, cannot set new addr\n" msgstr "" -#: .././db/frag.c:214 -msgid "bad option for frag command\n" +#: .././db/faddr.c:292 +msgid "directory block is unmapped\n" msgstr "" -#: .././db/frag.c:349 +#: .././db/convert.c:171 #, c-format -msgid "inode %lld actual %lld ideal %lld\n" +msgid "bad argument count %d to convert, expected 3,5,7,9 arguments\n" msgstr "" -#: .././db/frag.c:443 .././db/frag.c:453 +#: .././db/convert.c:176 .././db/convert.c:183 #, c-format -msgid "invalid numrecs (%u) in %s block\n" -msgstr "" - -#: .././db/attrset.c:38 -msgid "[-r|-s|-p|-u] [-n] [-R|-C] [-v n] name" +msgid "unknown conversion type %s\n" msgstr "" -#: .././db/attrset.c:39 -msgid "set the named attribute on the current inode" +#: .././db/convert.c:187 +msgid "result type same as argument\n" msgstr "" -#: .././db/attrset.c:42 -msgid "[-r|-s|-p|-u] [-n] name" +#: .././db/convert.c:191 +#, c-format +msgid "conflicting conversion type %s\n" msgstr "" -#: .././db/attrset.c:43 -msgid "remove the named attribute from the current inode" +#: .././db/convert.c:269 +#, c-format +msgid "%s is not a number\n" msgstr "" -#: .././db/attrset.c:49 -msgid "" -"\n" -" The 'attr_set' and 'attr_remove' commands provide interfaces for debugging\n" -" the extended attribute allocation and removal code.\n" -" Both commands require an attribute name to be specified, and the attr_set\n" -" command allows an optional value length (-v) to be provided as well.\n" -" There are 4 namespace flags:\n" -" -r -- 'root'\n" -" -u -- 'user'\t\t(default)\n" -" -s -- 'secure'\n" -"\n" -" For attr_set, these options further define the type of set operation:\n" -" -C -- 'create' - create attribute, fail if it already exists\n" -" -R -- 'replace' - replace attribute, fail if it does not exist\n" -" The backward compatibility mode 'noattr2' can be emulated (-n) also.\n" -"\n" +#: .././db/flist.c:149 +#, c-format +msgid "field %s not found\n" msgstr "" -#: .././db/attrset.c:86 .././db/attrset.c:189 .././db/addr.c:72 -#: .././db/print.c:74 .././db/type.c:102 .././db/write.c:101 -msgid "no current type\n" +#: .././db/flist.c:159 +#, c-format +msgid "no elements in %s\n" msgstr "" -#: .././db/attrset.c:90 .././db/attrset.c:193 -msgid "current type is not inode\n" +#: .././db/flist.c:165 +#, c-format +msgid "indices %d-%d for field %s out of range %d-%d\n" msgstr "" -#: .././db/attrset.c:125 +#: .././db/flist.c:173 #, c-format -msgid "bad attr_set valuelen %s\n" +msgid "index %d for field %s out of range %d-%d\n" msgstr "" -#: .././db/attrset.c:131 -msgid "bad option for attr_set command\n" +#: .././db/flist.c:187 +#, c-format +msgid "field %s is not an array\n" msgstr "" -#: .././db/attrset.c:137 -msgid "too few options for attr_set (no name given)\n" +#: .././db/flist.c:200 +#, c-format +msgid "field %s has no subfields\n" msgstr "" -#: .././db/attrset.c:146 +#: .././db/flist.c:220 #, c-format -msgid "cannot allocate buffer (%d)\n" +msgid "fl@%p:\n" msgstr "" -#: .././db/attrset.c:155 .././db/attrset.c:230 +#: .././db/flist.c:221 #, c-format -msgid "failed to iget inode %llu\n" +msgid "\tname=%s, fld=%p, child=%p, sibling=%p\n" msgstr "" -#: .././db/attrset.c:162 +#: .././db/flist.c:223 #, c-format -msgid "failed to set attr %s on inode %llu\n" +msgid "\tlow=%d, high=%d, flags=%d (%s%s), offset=%d\n" msgstr "" -#: .././db/attrset.c:217 -msgid "bad option for attr_remove command\n" +#: .././db/flist.c:225 +msgid "oklow " msgstr "" -#: .././db/attrset.c:223 -msgid "too few options for attr_remove (no name given)\n" +#: .././db/flist.c:226 +msgid "okhigh" msgstr "" -#: .././db/attrset.c:236 +#: .././db/flist.c:227 #, c-format -msgid "failed to remove attr %s from inode %llu\n" +msgid "\tfld->name=%s, fld->ftyp=%d (%s)\n" msgstr "" -#: .././db/addr.c:35 -msgid "[field-expression]" +#: .././db/flist.c:230 +#, c-format +msgid "\tfld->flags=%d (%s%s%s%s%s)\n" msgstr "" -#: .././db/addr.c:36 -msgid "set current address" +#: .././db/flist.c:322 +#, c-format +msgid "bad syntax in field name %s\n" msgstr "" -#: .././db/addr.c:42 -msgid "" -"\n" -" 'addr' uses the given field to set the filesystem address and type\n" -"\n" -" Examples:\n" -"\n" -" sb\n" -" a rootino - set the type to inode and set position to the root inode\n" -" a u.bmx[0].startblock (for inode with blockmap)\n" -"\n" +#: .././db/flist.c:378 +#, c-format +msgid "missing closing quote %s\n" msgstr "" -#: .././db/addr.c:82 +#: .././db/flist.c:395 #, c-format -msgid "no fields for type %s\n" +msgid "bad character in field %s\n" msgstr "" -#: .././db/addr.c:95 -msgid "array not allowed for addr command\n" +#: .././db/inode.c:412 +#, c-format +msgid "bad value for inode number %s\n" msgstr "" -#: .././db/addr.c:105 +#: .././db/inode.c:419 #, c-format -msgid "no next type for field %s\n" +msgid "current inode number is %lld\n" msgstr "" -#: .././db/addr.c:112 +#: .././db/inode.c:654 #, c-format -msgid "no addr function for field %s (type %s)\n" +msgid "bad inode number %lld\n" msgstr "" -#: .././db/agf.c:35 .././db/agfl.c:36 .././db/agi.c:35 .././db/sb.c:42 -msgid "[agno]" +#: .././db/hash.c:30 +msgid "string" msgstr "" -#: .././db/agf.c:36 -msgid "set address to agf header" +#: .././db/hash.c:31 +msgid "calculate hash value" msgstr "" -#: .././db/agf.c:79 +#: .././db/hash.c:37 msgid "" "\n" -" set allocation group free block list\n" -"\n" -" Example:\n" +" 'hash' prints out the calculated hash value for a string using the\n" +"directory/attribute code hash function.\n" "\n" -" agf 2 - move location to AGF in 2nd filesystem allocation group\n" +" Usage: \"hash \"\n" "\n" -" Located in the second sector of each allocation group, the AGF\n" -" contains the root of two different freespace btrees:\n" -" The 'cnt' btree keeps track freespace indexed on section size.\n" -" The 'bno' btree tracks sections of freespace indexed on block number.\n" msgstr "" -#: .././db/agf.c:104 .././db/agfl.c:90 .././db/agi.c:89 .././db/sb.c:151 -#, c-format -msgid "bad allocation group number %s\n" +#: .././db/help.c:30 .././db/io.c:48 .././libxcmd/help.c:92 +msgid "[command]" msgstr "" -#: .././db/agfl.c:37 -msgid "set address to agfl block" +#: .././db/help.c:31 .././libxcmd/help.c:93 +msgid "help for one or all commands" msgstr "" -#: .././db/agfl.c:63 +#: .././db/help.c:40 .././libxcmd/help.c:33 +#, c-format msgid "" "\n" -" set allocation group freelist\n" -"\n" -" Example:\n" -"\n" -" agfl 5\n" -" Located in the fourth sector of each allocation group,\n" -" the agfl freelist for internal btree space allocation is maintained\n" -" for each allocation group. This acts as a reserved pool of space\n" -" separate from the general filesystem freespace (not used for user data).\n" -"\n" +"Use 'help commandname' for extended help.\n" msgstr "" -#: .././db/agi.c:36 -msgid "set address to agi header" +#: .././db/help.c:89 +#, c-format +msgid "(or %s) " msgstr "" -#: .././db/agi.c:64 -msgid "" -"\n" -" set allocation group inode btree\n" -"\n" -" Example:\n" -"\n" -" agi 3 (set location to 3rd allocation group inode btree and type to 'agi')\n" -"\n" -" Located in the 3rd 512 byte block of each allocation group,\n" -" the agi inode btree tracks all used/free inodes in the allocation group.\n" -" Inodes are allocated in 16k 'chunks', each btree entry tracks a 'chunk'.\n" -"\n" +#: .././db/dir2.c:1019 +msgid "Unknown directory buffer type!\n" msgstr "" -#: .././db/block.c:43 .././db/block.c:49 -msgid "filoff" +#: .././db/dir2.c:1031 +msgid "Writing unknown directory buffer type!\n" msgstr "" -#: .././db/block.c:44 -msgid "set address to file offset (attr fork)" +#: .././db/input.c:43 +msgid "source-file" msgstr "" -#: .././db/block.c:46 -msgid "[d]" +#: .././db/input.c:44 +msgid "get commands from source-file" msgstr "" -#: .././db/block.c:47 -msgid "set address to daddr value" -msgstr "" - -#: .././db/block.c:50 -msgid "set address to file offset (data fork)" -msgstr "" - -#: .././db/block.c:52 -msgid "[fsb]" -msgstr "" - -#: .././db/block.c:53 -msgid "set address to fsblock value" -msgstr "" - -#: .././db/block.c:59 -msgid "" -"\n" -" Example:\n" -"\n" -" 'ablock 23' - sets the file position to the 23rd filesystem block in\n" -" the inode's attribute fork. The filesystem block size is specified in\n" -" the superblock.\n" -"\n" -msgstr "" - -#: .././db/block.c:82 .././db/block.c:177 -#, c-format -msgid "bad block number %s\n" -msgstr "" - -#: .././db/block.c:90 -msgid "no attribute data for file\n" -msgstr "" - -#: .././db/block.c:96 -msgid "file attr block is unmapped\n" -msgstr "" - -#: .././db/block.c:119 -msgid "" -"\n" -" Example:\n" -"\n" -" 'daddr 102' - sets position to the 102nd absolute disk block\n" -" (512 byte block).\n" -msgstr "" - -#: .././db/block.c:135 +#: .././db/input.c:320 #, c-format -msgid "current daddr is %lld\n" +msgid "can't open %s\n" msgstr "" -#: .././db/block.c:141 +#: .././db/malloc.c:27 #, c-format -msgid "bad daddr %s\n" -msgstr "" - -#: .././db/block.c:153 -msgid "" -"\n" -" Example:\n" -"\n" -" 'dblock 23' - sets the file position to the 23rd filesystem block in\n" -" the inode's data fork. The filesystem block size is specified in the\n" -" superblock.\n" -"\n" -msgstr "" - -#: .././db/block.c:185 -msgid "no type for file data\n" -msgstr "" - -#: .././db/block.c:192 -msgid "file data block is unmapped\n" -msgstr "" - -#: .././db/block.c:210 -msgid "" -"\n" -" Example:\n" -"\n" -" 'fsblock 1023' - sets the file position to the 1023rd filesystem block.\n" -" The filesystem block size is specified in the superblock and set during\n" -" mkfs time. Offset is absolute (not AG relative).\n" -"\n" +msgid "%s: out of memory\n" msgstr "" -#: .././db/block.c:229 -#, c-format -msgid "current fsblock is %lld\n" +#: .././db/output.c:30 +msgid "[stop|start ]" msgstr "" -#: .././db/block.c:235 .././db/block.c:241 -#, c-format -msgid "bad fsblock %s\n" +#: .././db/output.c:31 +msgid "start or stop logging to a file" msgstr "" -#: .././db/init.c:46 +#: .././db/output.c:68 #, c-format -msgid "Usage: %s [-fFrxV] [-p prog] [-l logdev] [-c cmd]... device\n" -msgstr "" - -#: .././db/init.c:112 -msgid "" -"\n" -"fatal error -- couldn't initialize XFS library\n" +msgid "logging to %s\n" msgstr "" -#: .././db/init.c:118 -#, c-format -msgid "%s: %s is invalid (cannot read first 512 bytes)\n" +#: .././db/output.c:70 .././db/output.c:77 +msgid "no log file\n" msgstr "" -#: .././db/init.c:129 +#: .././db/output.c:80 #, c-format -msgid "" -"%s: %s is not a valid XFS filesystem (unexpected SB magic number 0x%08x)\n" +msgid "already logging to %s\n" msgstr "" -#: .././db/init.c:141 +#: .././db/output.c:84 #, c-format -msgid "%s: device %s unusable (not an XFS filesystem?)\n" +msgid "can't open %s for writing\n" msgstr "" -#: .././db/command.c:82 .././db/help.c:56 .././libxcmd/help.c:49 -#, c-format -msgid "command %s not found\n" +#: .././db/output.c:90 +msgid "bad log command, ignored\n" msgstr "" -#: .././db/command.c:86 -#, c-format -msgid "bad argument count %d to %s, expected " +#: .././db/print.c:41 +msgid "[value]..." msgstr "" -#: .././db/command.c:88 -#, c-format -msgid "at least %d" +#: .././db/print.c:42 +msgid "print field values" msgstr "" -#: .././db/command.c:92 +#: .././db/print.c:79 #, c-format -msgid "between %d and %d" +msgid "no print function for type %s\n" msgstr "" -#: .././db/command.c:93 -msgid " arguments\n" +#: .././db/print.c:153 +msgid "(empty)\n" msgstr "" -#: .././db/debug.c:27 -msgid "[flagbits]" +#: .././db/print.c:215 +msgid "(empty)" msgstr "" -#: .././db/debug.c:28 -msgid "set debug option bits" +#: .././db/print.c:275 +msgid "no arguments allowed\n" msgstr "" -#: .././db/debug.c:42 -#, c-format -msgid "bad value for debug %s\n" +#: .././db/quit.c:27 +msgid "exit xfs_db" msgstr "" #: .././db/dquot.c:37 @@ -1707,236 +1848,465 @@ msgid "set current address to project, group or user quota block" msgstr "" -#: .././db/dquot.c:124 +#: .././db/dquot.c:127 msgid "bad option for dquot command\n" msgstr "" -#: .././db/dquot.c:128 +#: .././db/dquot.c:131 msgid "project" msgstr "" -#: .././db/dquot.c:128 +#: .././db/dquot.c:131 msgid "group" msgstr "" -#: .././db/dquot.c:128 +#: .././db/dquot.c:131 msgid "user" msgstr "" -#: .././db/dquot.c:130 +#: .././db/dquot.c:133 #, c-format msgid "dquot command requires one %s id argument\n" msgstr "" -#: .././db/dquot.c:137 +#: .././db/dquot.c:143 #, c-format msgid "no %s quota inode present\n" msgstr "" -#: .././db/dquot.c:142 +#: .././db/dquot.c:148 #, c-format msgid "bad %s id for dquot %s\n" msgstr "" -#: .././db/dquot.c:154 +#: .././db/dquot.c:160 #, c-format msgid "no %s quota data for id %d\n" msgstr "" -#: .././db/echo.c:27 -msgid "[args]..." -msgstr "" - -#: .././db/echo.c:28 -msgid "echo arguments" +#: .././db/addr.c:35 +msgid "[field-expression]" msgstr "" -#: .././db/faddr.c:40 .././db/faddr.c:63 -msgid "no current allocation group, cannot set new addr\n" +#: .././db/addr.c:36 +msgid "set current address" msgstr "" -#: .././db/faddr.c:45 .././db/faddr.c:117 .././db/faddr.c:148 -#: .././db/faddr.c:180 .././db/faddr.c:202 .././db/faddr.c:232 -#: .././db/faddr.c:262 .././db/faddr.c:316 .././db/faddr.c:335 -msgid "null block number, cannot set new addr\n" +#: .././db/addr.c:42 +msgid "" +"\n" +" 'addr' uses the given field to set the filesystem address and type\n" +"\n" +" Examples:\n" +"\n" +" sb\n" +" a rootino - set the type to inode and set position to the root inode\n" +" a u.bmx[0].startblock (for inode with blockmap)\n" +"\n" msgstr "" -#: .././db/faddr.c:68 .././db/faddr.c:353 .././db/faddr.c:371 -#: .././db/faddr.c:389 -msgid "null inode number, cannot set new addr\n" +#: .././db/addr.c:82 +#, c-format +msgid "no fields for type %s\n" msgstr "" -#: .././db/faddr.c:88 -msgid "null attribute block number, cannot set new addr\n" +#: .././db/addr.c:94 +msgid "array not allowed for addr command\n" msgstr "" -#: .././db/faddr.c:94 -msgid "attribute block is unmapped\n" +#: .././db/addr.c:103 +#, c-format +msgid "no next type for field %s\n" msgstr "" -#: .././db/faddr.c:123 .././db/faddr.c:155 .././db/faddr.c:208 -#: .././db/faddr.c:239 -msgid "file block is unmapped\n" +#: .././db/addr.c:110 +#, c-format +msgid "no addr function for field %s (type %s)\n" msgstr "" -#: .././db/faddr.c:285 -msgid "null directory block number, cannot set new addr\n" +#: .././db/metadump.c:59 +msgid "[-e] [-g] [-m max_extent] [-w] [-o] filename" msgstr "" -#: .././db/faddr.c:292 -msgid "directory block is unmapped\n" +#: .././db/metadump.c:60 +msgid "dump metadata to a file" msgstr "" -#: .././db/flist.c:149 +#: .././db/metadump.c:90 #, c-format -msgid "field %s not found\n" +msgid "" +"\n" +" The 'metadump' command dumps the known metadata to a compact file suitable\n" +" for compressing and sending to an XFS maintainer for corruption analysis \n" +" or xfs_repair failures.\n" +"\n" +" Options:\n" +" -e -- Ignore read errors and keep going\n" +" -g -- Display dump progress\n" +" -m -- Specify max extent size in blocks to copy (default = %d blocks)\n" +" -o -- Don't obfuscate names and extended attributes\n" +" -w -- Show warnings of bad metadata information\n" +"\n" msgstr "" -#: .././db/flist.c:159 -#, c-format -msgid "no elements in %s\n" +#: .././db/sb.c:43 +msgid "set current address to sb header" msgstr "" -#: .././db/flist.c:165 -#, c-format -msgid "indices %d-%d for field %s out of range %d-%d\n" +#: .././db/sb.c:45 +msgid "[uuid]" msgstr "" -#: .././db/flist.c:173 -#, c-format -msgid "index %d for field %s out of range %d-%d\n" +#: .././db/sb.c:46 +msgid "write/print FS uuid" msgstr "" -#: .././db/flist.c:187 -#, c-format -msgid "field %s is not an array\n" +#: .././db/sb.c:48 +msgid "[label]" msgstr "" -#: .././db/flist.c:200 -#, c-format -msgid "field %s has no subfields\n" +#: .././db/sb.c:49 +msgid "write/print FS label" msgstr "" -#: .././db/flist.c:220 -#, c-format -msgid "fl@%p:\n" +#: .././db/sb.c:51 +msgid "[feature | [vnum fnum]]" msgstr "" -#: .././db/flist.c:221 -#, c-format -msgid "\tname=%s, fld=%p, child=%p, sibling=%p\n" +#: .././db/sb.c:52 +msgid "set feature bit(s) in the sb version field" msgstr "" -#: .././db/flist.c:223 -#, c-format -msgid "\tlow=%d, high=%d, flags=%d (%s%s), offset=%d\n" +#: .././db/sb.c:136 +msgid "" +"\n" +" set allocation group superblock\n" +"\n" +" Example:\n" +"\n" +" 'sb 7' - set location to 7th allocation group superblock, set type to 'sb'\n" +"\n" +" Located in the first sector of each allocation group, the superblock\n" +" contains the base information for the filesystem.\n" +" The superblock in allocation group 0 is the primary. The copies in the\n" +" remaining allocation groups only serve as backup for filesystem recovery.\n" +" The icount/ifree/fdblocks/frextents are only updated in superblock 0.\n" +"\n" msgstr "" -#: .././db/flist.c:225 -msgid "oklow " +#: .././db/sb.c:195 +#, c-format +msgid "can't read superblock for AG %u\n" msgstr "" -#: .././db/flist.c:226 -msgid "okhigh" +#: .././db/sb.c:203 +#, c-format +msgid "bad sb magic # %#x in AG %u\n" msgstr "" -#: .././db/flist.c:227 +#: .././db/sb.c:208 #, c-format -msgid "\tfld->name=%s, fld->ftyp=%d (%s)\n" +msgid "bad sb version # %#x in AG %u\n" msgstr "" -#: .././db/flist.c:230 +#: .././db/sb.c:233 +msgid "aborting - external log specified for FS with an internal log\n" +msgstr "" + +#: .././db/sb.c:239 +msgid "aborting - no external log specified for FS with an external log\n" +msgstr "" + +#: .././db/sb.c:261 +msgid "ERROR: cannot find log head/tail, run xfs_repair\n" +msgstr "" + +#: .././db/sb.c:266 #, c-format -msgid "\tfld->flags=%d (%s%s%s%s%s)\n" +msgid "" +"ERROR: The filesystem has valuable metadata changes in a log which needs to\n" +"be replayed. Mount the filesystem to replay the log, and unmount it before\n" +"re-running %s. If you are unable to mount the filesystem, then use\n" +"the xfs_repair -L option to destroy the log and attempt a repair.\n" +"Note that destroying the log may cause corruption -- please attempt a mount\n" +"of the filesystem before doing this.\n" msgstr "" -#: .././db/flist.c:322 +#: .././db/sb.c:283 +msgid "Clearing log and setting UUID\n" +msgstr "" + +#: .././db/sb.c:291 +msgid "ERROR: cannot clear the log\n" +msgstr "" + +#: .././db/sb.c:302 +msgid "" +"\n" +" write/print FS uuid\n" +"\n" +" Example:\n" +"\n" +" 'uuid' - print UUID\n" +" 'uuid 01234567-0123-0123-0123-0123456789ab' - write UUID\n" +" 'uuid generate' - generate and write\n" +" 'uuid rewrite' - copy UUID from SB 0\n" +"\n" +"The print function checks the UUID in each SB and will warn if the UUIDs\n" +"differ between AGs (the log is not checked). The write commands will\n" +"set the uuid in all AGs to either a specified value, a newly generated\n" +"value or the value found in the first superblock (SB 0) respectively.\n" +"As a side effect of writing the UUID, the log is cleared (which is fine\n" +"on a CLEANLY unmounted FS).\n" +"\n" +msgstr "" + +#: .././db/sb.c:354 .././db/sb.c:506 +msgid "invalid parameters\n" +msgstr "" + +#: .././db/sb.c:361 .././db/sb.c:513 .././db/sb.c:670 #, c-format -msgid "bad syntax in field name %s\n" +msgid "%s: not in expert mode, writing disabled\n" msgstr "" -#: .././db/flist.c:378 +#: .././db/sb.c:373 +msgid "failed to read UUID from AG 0\n" +msgstr "" + +#: .././db/sb.c:378 #, c-format -msgid "missing closing quote %s\n" +msgid "old UUID = %s\n" msgstr "" -#: .././db/flist.c:395 +#: .././db/sb.c:381 +msgid "invalid UUID\n" +msgstr "" + +#: .././db/sb.c:390 .././db/sb.c:518 .././db/sb.c:756 +msgid "writing all SBs\n" +msgstr "" + +#: .././db/sb.c:393 #, c-format -msgid "bad character in field %s\n" +msgid "failed to set UUID in AG %d\n" msgstr "" -#: .././db/fprint.c:98 -msgid "null" +#: .././db/sb.c:398 +#, c-format +msgid "new UUID = %s\n" msgstr "" -#: .././db/inode.c:385 +#: .././db/sb.c:406 #, c-format -msgid "bad value for inode number %s\n" +msgid "failed to read UUID from AG %d\n" msgstr "" -#: .././db/inode.c:390 .././db/bmap.c:153 -msgid "no current inode\n" +#: .././db/sb.c:412 +#, c-format +msgid "warning: UUID in AG %d differs to the primary SB\n" +msgstr "" + +#: .././db/sb.c:423 +msgid "warning - external log specified for FS with an internal log\n" +msgstr "" + +#: .././db/sb.c:426 +msgid "warning - no external log specified for FS with an external log\n" msgstr "" -#: .././db/inode.c:392 +#: .././db/sb.c:431 #, c-format -msgid "current inode number is %lld\n" +msgid "UUID = %s\n" +msgstr "" + +#: .././db/sb.c:442 +msgid "" +"\n" +" write/print FS label\n" +"\n" +" Example:\n" +"\n" +" 'label' - print label\n" +" 'label 123456789012' - write label\n" +" 'label --' - write an empty label\n" +"\n" +"The print function checks the label in each SB and will warn if the labels\n" +"differ between AGs. The write commands will set the label in all AGs to the\n" +"specified value. The maximum length of a label is 12 characters - use of a\n" +"longer label will result in truncation and a warning will be issued.\n" +"\n" msgstr "" -#: .././db/inode.c:614 +#: .././db/sb.c:479 #, c-format -msgid "bad inode number %lld\n" +msgid "%s: truncating label length from %d to %d\n" msgstr "" -#: .././db/hash.c:30 -msgid "string" +#: .././db/sb.c:521 +#, c-format +msgid "failed to set label in AG %d\n" msgstr "" -#: .././db/hash.c:31 -msgid "calculate hash value" +#: .././db/sb.c:524 +#, c-format +msgid "new label = \"%s\"\n" msgstr "" -#: .././db/hash.c:37 +#: .././db/sb.c:531 +#, c-format +msgid "failed to read label in AG %d\n" +msgstr "" + +#: .././db/sb.c:537 +#, c-format +msgid "warning: AG %d label differs\n" +msgstr "" + +#: .././db/sb.c:539 +#, c-format +msgid "label = \"%s\"\n" +msgstr "" + +#: .././db/sb.c:549 msgid "" "\n" -" 'hash' prints out the calculated hash value for a string using the\n" -"directory/attribute code hash function.\n" +" set/print feature bits in sb version\n" "\n" -" Usage: \"hash \"\n" +" Example:\n" +"\n" +" 'version' - print current feature bits\n" +" 'version extflg' - enable unwritten extents\n" +" 'version attr1' - enable v1 inline extended attributes\n" +" 'version attr2' - enable v2 inline extended attributes\n" +" 'version log2' - enable v2 log format\n" +"\n" +"The version function prints currently enabled features for a filesystem\n" +"according to the version field of its primary superblock.\n" +"It can also be used to enable selected features, such as support for\n" +"unwritten extents. The updated version is written into all AGs.\n" "\n" msgstr "" -#: .././db/help.c:30 .././db/io.c:48 .././libxcmd/help.c:92 -msgid "[command]" +#: .././db/sb.c:578 +msgid "Superblock has mismatched features2 fields, skipping modification\n" msgstr "" -#: .././db/help.c:31 .././libxcmd/help.c:93 -msgid "help for one or all commands" +#: .././db/sb.c:690 +msgid "unwritten extents flag is already enabled\n" msgstr "" -#: .././db/help.c:40 .././libxcmd/help.c:33 +#: .././db/sb.c:697 +msgid "unwritten extents always enabled for v5 superblocks.\n" +msgstr "" + +#: .././db/sb.c:714 +msgid "version 2 log format is already in use\n" +msgstr "" + +#: .././db/sb.c:721 +msgid "Version 2 logs always enabled for v5 superblocks.\n" +msgstr "" + +#: .././db/sb.c:726 +#, c-format +msgid "%s: Cannot change %s on v5 superblocks.\n" +msgstr "" + +#: .././db/sb.c:750 +#, c-format +msgid "%s: invalid version change command \"%s\"\n" +msgstr "" + +#: .././db/sb.c:759 +#, c-format +msgid "failed to set versionnum in AG %d\n" +msgstr "" + +#: .././db/sb.c:777 +#, c-format +msgid "versionnum [0x%x+0x%x] = %s\n" +msgstr "" + +#: .././db/fprint.c:99 +msgid "null" +msgstr "" + +#: .././db/init.c:47 #, c-format +msgid "Usage: %s [-ifFrxV] [-p prog] [-l logdev] [-c cmd]... device\n" +msgstr "" + +#: .././db/init.c:114 msgid "" "\n" -"Use 'help commandname' for extended help.\n" +"fatal error -- couldn't initialize XFS library\n" msgstr "" -#: .././db/help.c:89 +#: .././db/init.c:129 #, c-format -msgid "(or %s) " +msgid "%s: %s is invalid (cannot read first 512 bytes)\n" msgstr "" -#: .././db/input.c:43 -msgid "source-file" +#: .././db/init.c:141 +#, c-format +msgid "" +"%s: %s is not a valid XFS filesystem (unexpected SB magic number 0x%08x)\n" msgstr "" -#: .././db/input.c:44 -msgid "get commands from source-file" +#: .././db/init.c:144 +#, c-format +msgid "Use -F to force a read attempt.\n" msgstr "" -#: .././db/input.c:320 +#: .././db/init.c:153 #, c-format -msgid "can't open %s\n" +msgid "%s: device %s unusable (not an XFS filesystem?)\n" +msgstr "" + +#: .././db/init.c:167 +#, c-format +msgid "%s: cannot init perag data (%d). Continuing anyway.\n" +msgstr "" + +#: .././db/freesp.c:110 +#, c-format +msgid "total free extents %lld\n" +msgstr "" + +#: .././db/freesp.c:111 +#, c-format +msgid "total free blocks %lld\n" +msgstr "" + +#: .././db/freesp.c:112 +#, c-format +msgid "average free extent size %g\n" +msgstr "" + +#: .././db/freesp.c:203 +msgid "" +"freesp arguments: [-bcds] [-a agno] [-e binsize] [-h h1]... [-m binmult]\n" +msgstr "" + +#: .././db/freesp.c:427 +msgid "from" +msgstr "" + +#: .././db/freesp.c:427 +msgid "to" +msgstr "" + +#: .././db/freesp.c:427 .././repair/progress.c:26 +msgid "extents" +msgstr "" + +#: .././db/freesp.c:427 .././repair/progress.c:18 +msgid "blocks" +msgstr "" + +#: .././db/freesp.c:427 +msgid "pct" msgstr "" #: .././db/io.c:46 @@ -1972,57 +2342,58 @@ msgid "can't pop anything from I/O stack\n" msgstr "" -#: .././db/io.c:132 +#: .././db/io.c:138 msgid "" "\n" " Changes the address and data type to the first entry on the stack.\n" "\n" msgstr "" -#: .././db/io.c:146 +#: .././db/io.c:152 #, c-format msgid "\tbyte offset %lld, length %d\n" msgstr "" -#: .././db/io.c:147 +#: .././db/io.c:153 #, c-format msgid "\tbuffer block %lld (fsbno %lld), %d bb%s\n" msgstr "" -#: .././db/io.c:151 +#: .././db/io.c:157 .././db/io.c:508 +#, c-format msgid "\tblock map" msgstr "" -#: .././db/io.c:156 +#: .././db/io.c:163 #, c-format msgid "\tinode %lld, dir inode %lld, type %s\n" msgstr "" -#: .././db/io.c:157 .././growfs/xfs_growfs.c:86 .././logprint/log_misc.c:152 -#: .././mkfs/xfs_mkfs.c:1979 +#: .././db/io.c:164 .././growfs/xfs_growfs.c:83 .././logprint/log_misc.c:151 +#: .././mkfs/xfs_mkfs.c:2126 #, c-format msgid "none" msgstr "" -#: .././db/io.c:167 +#: .././db/io.c:174 msgid "no entries in location ring.\n" msgstr "" -#: .././db/io.c:171 +#: .././db/io.c:178 msgid " type bblock bblen fsbno inode\n" msgstr "" -#: .././db/io.c:225 +#: .././db/io.c:232 #, c-format msgid "no such command %s\n" msgstr "" -#: .././db/io.c:229 +#: .././db/io.c:236 #, c-format msgid "no push form allowed for %s\n" msgstr "" -#: .././db/io.c:253 +#: .././db/io.c:260 msgid "" "\n" " Allows you to push the current address and data type on the stack for\n" @@ -2031,15 +2402,15 @@ "\n" msgstr "" -#: .././db/io.c:269 .././db/io.c:310 +#: .././db/io.c:276 .././db/io.c:316 msgid "ring is empty\n" msgstr "" -#: .././db/io.c:273 +#: .././db/io.c:280 msgid "no further entries\n" msgstr "" -#: .././db/io.c:293 +#: .././db/io.c:299 msgid "" "\n" " The 'forward' ('f') command moves to the next location in the position\n" @@ -2050,11 +2421,11 @@ "\n" msgstr "" -#: .././db/io.c:314 +#: .././db/io.c:320 msgid "no previous entries\n" msgstr "" -#: .././db/io.c:334 +#: .././db/io.c:339 msgid "" "\n" " The 'back' ('b') command moves to the previous location in the position\n" @@ -2065,12 +2436,12 @@ "\n" msgstr "" -#: .././db/io.c:357 +#: .././db/io.c:362 #, c-format msgid "invalid entry: %d\n" msgstr "" -#: .././db/io.c:374 +#: .././db/io.c:381 #, c-format msgid "" "\n" @@ -2094,45 +2465,30 @@ "\n" msgstr "" -#: .././db/io.c:438 .././db/io.c:481 +#: .././db/io.c:434 .././db/io.c:450 #, c-format -msgid "can't seek in filesystem at bb %lld\n" -msgstr "" - -#: .././db/io.c:515 -msgid "nothing to write\n" +msgid "write error: %s\n" msgstr "" -#: .././db/io.c:521 +#: .././db/io.c:440 .././db/io.c:456 #, c-format -msgid "incomplete write, block: %lld\n" +msgid "read error: %s\n" msgstr "" -#: .././db/io.c:524 -#, c-format -msgid "write error: %s\n" -msgstr "" - -#: .././db/io.c:529 -#, c-format -msgid "incomplete read, block: %lld\n" -msgstr "" - -#: .././db/io.c:532 -#, c-format -msgid "read error: %s\n" +#: .././db/io.c:463 +msgid "nothing to write\n" msgstr "" -#: .././db/io.c:548 +#: .././db/io.c:493 msgid "set_cur no stack element to set\n" msgstr "" -#: .././db/io.c:554 +#: .././db/io.c:507 #, c-format msgid "xfs_db got a bbmap for %lld\n" msgstr "" -#: .././db/io.c:585 +#: .././db/io.c:583 msgid "" "\n" " The stack is used to explicitly store your location and data type\n" @@ -2145,98 +2501,90 @@ "\n" msgstr "" -#: .././db/malloc.c:27 -#, c-format -msgid "%s: out of memory\n" -msgstr "" - -#: .././db/output.c:30 -msgid "[stop|start ]" -msgstr "" - -#: .././db/output.c:31 -msgid "start or stop logging to a file" +#: .././db/agfl.c:37 +msgid "set address to agfl block" msgstr "" -#: .././db/output.c:68 -#, c-format -msgid "logging to %s\n" +#: .././db/agfl.c:79 +msgid "" +"\n" +" set allocation group freelist\n" +"\n" +" Example:\n" +"\n" +" agfl 5\n" +" Located in the fourth sector of each allocation group,\n" +" the agfl freelist for internal btree space allocation is maintained\n" +" for each allocation group. This acts as a reserved pool of space\n" +" separate from the general filesystem freespace (not used for user data).\n" +"\n" msgstr "" -#: .././db/output.c:70 .././db/output.c:77 -msgid "no log file\n" +#: .././db/type.c:49 +msgid "[newtype]" msgstr "" -#: .././db/output.c:80 -#, c-format -msgid "already logging to %s\n" +#: .././db/type.c:50 +msgid "set/show current data type" msgstr "" -#: .././db/output.c:84 +#: .././db/type.c:144 #, c-format -msgid "can't open %s for writing\n" -msgstr "" - -#: .././db/output.c:90 -msgid "bad log command, ignored\n" -msgstr "" - -#: .././db/print.c:41 -msgid "[value]..." +msgid "current type is \"%s\"\n" msgstr "" -#: .././db/print.c:42 -msgid "print field values" +#: .././db/type.c:146 +msgid "" +"\n" +" supported types are:\n" +" " msgstr "" -#: .././db/print.c:79 +#: .././db/type.c:163 #, c-format -msgid "no print function for type %s\n" -msgstr "" - -#: .././db/print.c:153 -msgid "(empty)\n" -msgstr "" - -#: .././db/print.c:215 -msgid "(empty)" -msgstr "" - -#: .././db/print.c:275 -msgid "no arguments allowed\n" +msgid "no such type %s\n" msgstr "" -#: .././db/quit.c:27 -msgid "exit xfs_db" +#: .././db/type.c:166 +msgid "no current object\n" msgstr "" -#: .././db/type.c:50 -msgid "[newtype]" +#: .././db/agi.c:36 +msgid "set address to agi header" msgstr "" -#: .././db/type.c:51 -msgid "set/show current data type" +#: .././db/agi.c:69 +msgid "" +"\n" +" set allocation group inode btree\n" +"\n" +" Example:\n" +"\n" +" agi 3 (set location to 3rd allocation group inode btree and type to 'agi')\n" +"\n" +" Located in the 3rd 512 byte block of each allocation group,\n" +" the agi inode btree tracks all used/free inodes in the allocation group.\n" +" Inodes are allocated in 16k 'chunks', each btree entry tracks a 'chunk'.\n" +"\n" msgstr "" -#: .././db/type.c:104 +#: .././db/frag.c:173 #, c-format -msgid "current type is \"%s\"\n" +msgid "actual %llu, ideal %llu, fragmentation factor %.2f%%\n" msgstr "" -#: .././db/type.c:106 -msgid "" -"\n" -" supported types are:\n" -" " +#: .././db/frag.c:214 +msgid "bad option for frag command\n" msgstr "" -#: .././db/type.c:121 +#: .././db/frag.c:350 #, c-format -msgid "no such type %s\n" +msgid "inode %lld actual %lld ideal %lld\n" msgstr "" -#: .././db/type.c:124 -msgid "no current object\n" +#: .././db/frag.c:444 .././db/frag.c:454 +#, c-format +msgid "invalid numrecs (%u) in %s block\n" msgstr "" #: .././db/write.c:41 @@ -2290,917 +2638,628 @@ msgstr "" #: .././db/write.c:167 .././db/write.c:196 .././db/write.c:226 -#: .././db/write.c:258 .././db/write.c:293 .././db/write.c:342 -#: .././db/write.c:371 +#: .././db/write.c:259 .././db/write.c:295 .././db/write.c:344 +#: .././db/write.c:373 #, c-format msgid "length (%d) too large for data block size (%d)" msgstr "" -#: .././db/write.c:559 +#: .././db/write.c:615 msgid "usage: write fieldname value\n" msgstr "" -#: .././db/write.c:565 +#: .././db/write.c:621 #, c-format msgid "unable to parse '%s'.\n" msgstr "" -#: .././db/write.c:579 +#: .././db/write.c:635 msgid "parsing error\n" msgstr "" -#: .././db/write.c:598 +#: .././db/write.c:654 #, c-format msgid "unable to convert value '%s'.\n" msgstr "" -#: .././db/write.c:621 +#: .././db/write.c:677 msgid "usage (in string mode): write \"string...\"\n" msgstr "" -#: .././db/write.c:663 +#: .././db/write.c:719 msgid "write: invalid subcommand\n" msgstr "" -#: .././db/write.c:668 +#: .././db/write.c:724 #, c-format msgid "write %s: invalid number of arguments\n" msgstr "" -#: .././db/write.c:692 +#: .././db/write.c:748 msgid "usage: write (in data mode)\n" msgstr "" -#: .././db/freesp.c:106 -#, c-format -msgid "total free extents %lld\n" +#: .././db/attr.c:556 +msgid "Unknown attribute buffer type!\n" msgstr "" -#: .././db/freesp.c:107 -#, c-format -msgid "total free blocks %lld\n" +#: .././db/attr.c:568 +msgid "Writing unknown attribute buffer type!\n" msgstr "" -#: .././db/freesp.c:108 +#: .././estimate/xfs_estimate.c:78 #, c-format -msgid "average free extent size %g\n" -msgstr "" - -#: .././db/freesp.c:199 msgid "" -"freesp arguments: [-bcds] [-a agno] [-e binsize] [-h h1]... [-m binmult]\n" +"Usage: %s [opts] directory [directory ...]\n" +"\t-b blocksize (fundamental filesystem blocksize)\n" +"\t-i logsize (internal log size)\n" +"\t-e logsize (external log size)\n" +"\t-v prints more verbose messages\n" +"\t-V prints version and exits\n" +"\t-h prints this usage message\n" +"\n" +"Note:\tblocksize may have 'k' appended to indicate x1024\n" +"\tlogsize may also have 'm' appended to indicate (1024 x 1024)\n" msgstr "" -#: .././db/freesp.c:406 -msgid "from" +#: .././estimate/xfs_estimate.c:109 +#, c-format +msgid "blocksize %llu too small\n" msgstr "" -#: .././db/freesp.c:406 -msgid "to" +#: .././estimate/xfs_estimate.c:114 +#, c-format +msgid "blocksize %llu too large\n" msgstr "" -#: .././db/freesp.c:406 .././repair/progress.c:26 -msgid "extents" +#: .././estimate/xfs_estimate.c:121 +#, c-format +msgid "already have external log noted, can't have both\n" msgstr "" -#: .././db/freesp.c:406 .././repair/progress.c:18 -msgid "blocks" +#: .././estimate/xfs_estimate.c:130 +#, c-format +msgid "already have internal log noted, can't have both\n" msgstr "" -#: .././db/freesp.c:406 -msgid "pct" +#: .././estimate/xfs_estimate.c:160 +#, c-format +msgid "" +"directory bsize blocks megabytes " +"logsize\n" msgstr "" -#: .././db/sb.c:43 -msgid "set current address to sb header" +#: .././estimate/xfs_estimate.c:174 +#, c-format +msgid "dirsize=%llu\n" msgstr "" -#: .././db/sb.c:45 -msgid "[uuid]" +#: .././estimate/xfs_estimate.c:175 +#, c-format +msgid "fullblocks=%llu\n" msgstr "" -#: .././db/sb.c:46 -msgid "write/print FS uuid" +#: .././estimate/xfs_estimate.c:176 +#, c-format +msgid "isize=%llu\n" msgstr "" -#: .././db/sb.c:48 -msgid "[label]" +#: .././estimate/xfs_estimate.c:178 +#, c-format +msgid "%llu regular files\n" msgstr "" -#: .././db/sb.c:49 -msgid "write/print FS label" +#: .././estimate/xfs_estimate.c:179 +#, c-format +msgid "%llu symbolic links\n" msgstr "" -#: .././db/sb.c:51 -msgid "[feature | [vnum fnum]]" +#: .././estimate/xfs_estimate.c:180 +#, c-format +msgid "%llu directories\n" msgstr "" -#: .././db/sb.c:52 -msgid "set feature bit(s) in the sb version field" +#: .././estimate/xfs_estimate.c:181 +#, c-format +msgid "%llu special files\n" msgstr "" -#: .././db/sb.c:124 -msgid "" -"\n" -" set allocation group superblock\n" -"\n" -" Example:\n" -"\n" -" 'sb 7' - set location to 7th allocation group superblock, set type to 'sb'\n" -"\n" -" Located in the first sector of each allocation group, the superblock\n" -" contains the base information for the filesystem.\n" -" The superblock in allocation group 0 is the primary. The copies in the\n" -" remaining allocation groups only serve as backup for filesystem recovery.\n" -" The icount/ifree/fdblocks/frextents are only updated in superblock 0.\n" -"\n" +#: .././estimate/xfs_estimate.c:194 +#, c-format +msgid "%s will take about %.1f megabytes\n" msgstr "" -#: .././db/sb.c:183 +#: .././estimate/xfs_estimate.c:201 #, c-format -msgid "can't read superblock for AG %u\n" +msgid "%-39s %5llu %8llu %10.1fMB %10llu\n" msgstr "" -#: .././db/sb.c:191 +#: .././estimate/xfs_estimate.c:207 #, c-format -msgid "bad sb magic # %#x in AG %u\n" +msgid "\twith the external log using %llu blocks " msgstr "" -#: .././db/sb.c:196 +#: .././estimate/xfs_estimate.c:209 #, c-format -msgid "bad sb version # %#x in AG %u\n" +msgid "or about %.1f megabytes\n" msgstr "" -#: .././db/sb.c:218 -msgid "aborting - external log specified for FS with an internal log\n" +#: .././fsr/xfs_fsr.c:194 +#, c-format +msgid "%s: cannot read %s\n" msgstr "" -#: .././db/sb.c:224 -msgid "aborting - no external log specified for FS with an external log\n" +#: .././fsr/xfs_fsr.c:273 +#, c-format +msgid "%s: Stats not yet supported for XFS\n" msgstr "" -#: .././db/sb.c:242 -msgid "ERROR: cannot find log head/tail, run xfs_repair\n" +#: .././fsr/xfs_fsr.c:337 +#, c-format +msgid "%s: could not stat: %s: %s\n" msgstr "" -#: .././db/sb.c:247 +#: .././fsr/xfs_fsr.c:356 #, c-format -msgid "" -"ERROR: The filesystem has valuable metadata changes in a log which needs to\n" -"be replayed. Mount the filesystem to replay the log, and unmount it before\n" -"re-running %s. If you are unable to mount the filesystem, then use\n" -"the xfs_repair -L option to destroy the log and attempt a repair.\n" -"Note that destroying the log may cause corruption -- please attempt a mount\n" -"of the filesystem before doing this.\n" +msgid "%s: char special not supported: %s\n" msgstr "" -#: .././db/sb.c:264 -msgid "Clearing log and setting UUID\n" +#: .././fsr/xfs_fsr.c:362 +#, c-format +msgid "%s: cannot defragment: %s: Not XFS\n" msgstr "" -#: .././db/sb.c:273 -msgid "ERROR: cannot clear the log\n" +#: .././fsr/xfs_fsr.c:372 +#, c-format +msgid "%s: not fsys dev, dir, or reg file, ignoring\n" msgstr "" -#: .././db/sb.c:284 +#: .././fsr/xfs_fsr.c:387 +#, c-format msgid "" +"Usage: %s [-d] [-v] [-g] [-t time] [-p passes] [-f leftf] [-m mtab]\n" +" %s [-d] [-v] [-g] xfsdev | dir | file ...\n" +" %s -V\n" "\n" -" write/print FS uuid\n" -"\n" -" Example:\n" -"\n" -" 'uuid' - print UUID\n" -" 'uuid 01234567-0123-0123-0123-0123456789ab' - write UUID\n" -" 'uuid generate' - generate and write\n" -" 'uuid rewrite' - copy UUID from SB 0\n" -"\n" -"The print function checks the UUID in each SB and will warn if the UUIDs\n" -"differ between AGs (the log is not checked). The write commands will\n" -"set the uuid in all AGs to either a specified value, a newly generated\n" -"value or the value found in the first superblock (SB 0) respectively.\n" -"As a side effect of writing the UUID, the log is cleared (which is fine\n" -"on a CLEANLY unmounted FS).\n" -"\n" +"Options:\n" +" -g Print to syslog (default if stdout not a tty).\n" +" -t time How long to run in seconds.\n" +" -p passes Number of passes before terminating global re-org.\n" +" -f leftoff Use this instead of %s.\n" +" -m mtab Use something other than /etc/mtab.\n" +" -d Debug, print even more.\n" +" -v Verbose, more -v's more verbose.\n" +" -V Print version number and exit.\n" msgstr "" -#: .././db/sb.c:336 .././db/sb.c:488 -msgid "invalid parameters\n" +#: .././fsr/xfs_fsr.c:417 +#, c-format +msgid "could not open mtab file: %s\n" msgstr "" -#: .././db/sb.c:343 .././db/sb.c:495 .././db/sb.c:640 +#: .././fsr/xfs_fsr.c:423 .././fsr/xfs_fsr.c:455 #, c-format -msgid "%s: not in expert mode, writing disabled\n" +msgid "out of memory: %s\n" msgstr "" -#: .././db/sb.c:355 -msgid "failed to read UUID from AG 0\n" +#: .././fsr/xfs_fsr.c:446 +#, c-format +msgid "Skipping %s: not mounted rw\n" msgstr "" -#: .././db/sb.c:360 +#: .././fsr/xfs_fsr.c:460 #, c-format -msgid "old UUID = %s\n" -msgstr "" - -#: .././db/sb.c:363 -msgid "invalid UUID\n" +msgid "out of memory on realloc: %s\n" msgstr "" -#: .././db/sb.c:372 .././db/sb.c:500 .././db/sb.c:712 -msgid "writing all SBs\n" +#: .././fsr/xfs_fsr.c:471 .././fsr/xfs_fsr.c:475 +#, c-format +msgid "strdup(%s) failed\n" msgstr "" -#: .././db/sb.c:375 +#: .././fsr/xfs_fsr.c:485 #, c-format -msgid "failed to set UUID in AG %d\n" +msgid "no rw xfs file systems in mtab: %s\n" msgstr "" -#: .././db/sb.c:380 +#: .././fsr/xfs_fsr.c:489 #, c-format -msgid "new UUID = %s\n" +msgid "Found %d mounted, writable, XFS filesystems\n" msgstr "" -#: .././db/sb.c:388 +#: .././fsr/xfs_fsr.c:519 #, c-format -msgid "failed to read UUID from AG %d\n" +msgid "%s: open failed\n" msgstr "" -#: .././db/sb.c:394 +#: .././fsr/xfs_fsr.c:534 #, c-format -msgid "warning: UUID in AG %d differs to the primary SB\n" +msgid "Can't use %s: mode=0%o own=%d nlink=%d\n" msgstr "" -#: .././db/sb.c:405 -msgid "warning - external log specified for FS with an internal log\n" +#: .././fsr/xfs_fsr.c:554 +#, c-format +msgid "could not read %s, starting with %s\n" msgstr "" -#: .././db/sb.c:408 -msgid "warning - no external log specified for FS with an external log\n" +#: .././fsr/xfs_fsr.c:593 +#, c-format +msgid "START: pass=%d ino=%llu %s %s\n" msgstr "" -#: .././db/sb.c:413 +#: .././fsr/xfs_fsr.c:610 #, c-format -msgid "UUID = %s\n" +msgid "Completed all %d passes\n" msgstr "" -#: .././db/sb.c:424 -msgid "" -"\n" -" write/print FS label\n" -"\n" -" Example:\n" -"\n" -" 'label' - print label\n" -" 'label 123456789012' - write label\n" -" 'label --' - write an empty label\n" -"\n" -"The print function checks the label in each SB and will warn if the labels\n" -"differ between AGs. The write commands will set the label in all AGs to the\n" -"specified value. The maximum length of a label is 12 characters - use of a\n" -"longer label will result in truncation and a warning will be issued.\n" -"\n" +#: .././fsr/xfs_fsr.c:620 +msgid "couldn't fork sub process:" msgstr "" -#: .././db/sb.c:461 +#: .././fsr/xfs_fsr.c:655 #, c-format -msgid "%s: truncating label length from %d to %d\n" +msgid "%s startpass %d, endpass %d, time %d seconds\n" msgstr "" -#: .././db/sb.c:503 +#: .././fsr/xfs_fsr.c:662 #, c-format -msgid "failed to set label in AG %d\n" +msgid "open(%s) failed: %s\n" msgstr "" -#: .././db/sb.c:506 +#: .././fsr/xfs_fsr.c:668 #, c-format -msgid "new label = \"%s\"\n" +msgid "write(%s) failed: %s\n" msgstr "" -#: .././db/sb.c:513 +#: .././fsr/xfs_fsr.c:692 #, c-format -msgid "failed to read label in AG %d\n" +msgid "%s start inode=%llu\n" msgstr "" -#: .././db/sb.c:519 +#: .././fsr/xfs_fsr.c:697 #, c-format -msgid "warning: AG %d label differs\n" +msgid "unable to get handle: %s: %s\n" msgstr "" -#: .././db/sb.c:521 +#: .././fsr/xfs_fsr.c:703 #, c-format -msgid "label = \"%s\"\n" -msgstr "" - -#: .././db/sb.c:531 -msgid "" -"\n" -" set/print feature bits in sb version\n" -"\n" -" Example:\n" -"\n" -" 'version' - print current feature bits\n" -" 'version extflg' - enable unwritten extents\n" -" 'version attr1' - enable v1 inline extended attributes\n" -" 'version attr2' - enable v2 inline extended attributes\n" -" 'version log2' - enable v2 log format\n" -"\n" -"The version function prints currently enabled features for a filesystem\n" -"according to the version field of its primary superblock.\n" -"It can also be used to enable selected features, such as support for\n" -"unwritten extents. The updated version is written into all AGs.\n" -"\n" -msgstr "" - -#: .././db/sb.c:560 -msgid "Superblock has mismatched features2 fields, skipping modification\n" -msgstr "" - -#: .././db/sb.c:659 -msgid "unwritten extents flag is already enabled\n" -msgstr "" - -#: .././db/sb.c:679 -msgid "version 2 log format is already in use\n" +msgid "unable to open: %s: %s\n" msgstr "" -#: .././db/sb.c:706 +#: .././fsr/xfs_fsr.c:709 #, c-format -msgid "%s: invalid version change command \"%s\"\n" +msgid "Skipping %s: could not get XFS geometry\n" msgstr "" -#: .././db/sb.c:715 +#: .././fsr/xfs_fsr.c:743 #, c-format -msgid "failed to set versionnum in AG %d\n" +msgid "could not open: inode %llu\n" msgstr "" -#: .././db/sb.c:733 +#: .././fsr/xfs_fsr.c:773 #, c-format -msgid "versionnum [0x%x+0x%x] = %s\n" -msgstr "" - -#: .././db/bmap.c:39 -msgid "[-ad] [block [len]]" -msgstr "" - -#: .././db/bmap.c:40 -msgid "show block map for current file" -msgstr "" - -#: .././db/bmap.c:166 -msgid "bad option for bmap command\n" +msgid "%s: xfs_bulkstat: %s\n" msgstr "" -#: .././db/bmap.c:183 +#: .././fsr/xfs_fsr.c:799 #, c-format -msgid "bad block number for bmap %s\n" +msgid "%s: Directory defragmentation not supported\n" msgstr "" -#: .././db/bmap.c:191 +#: .././fsr/xfs_fsr.c:818 #, c-format -msgid "bad len for bmap %s\n" +msgid "unable to construct sys handle for %s: %s\n" msgstr "" -#: .././db/bmap.c:214 +#: .././fsr/xfs_fsr.c:829 #, c-format -msgid "%s offset %lld startblock %llu (%u/%u) count %llu flag %u\n" +msgid "unable to open sys handle for %s: %s\n" msgstr "" -#: .././estimate/xfs_estimate.c:76 +#: .././fsr/xfs_fsr.c:835 #, c-format -msgid "" -"Usage: %s [opts] directory [directory ...]\n" -"\t-b blocksize (fundamental filesystem blocksize)\n" -"\t-i logsize (internal log size)\n" -"\t-e logsize (external log size)\n" -"\t-v prints more verbose messages\n" -"\t-h prints this usage message\n" -"\n" -"Note:\tblocksize may have 'k' appended to indicate x1024\n" -"\tlogsize may also have 'm' appended to indicate (1024 x 1024)\n" +msgid "unable to get bstat on %s: %s\n" msgstr "" -#: .././estimate/xfs_estimate.c:106 +#: .././fsr/xfs_fsr.c:843 #, c-format -msgid "blocksize %llu too small\n" +msgid "unable to open handle %s: %s\n" msgstr "" -#: .././estimate/xfs_estimate.c:111 +#: .././fsr/xfs_fsr.c:851 #, c-format -msgid "blocksize %llu too large\n" +msgid "Unable to get geom on fs for: %s\n" msgstr "" -#: .././estimate/xfs_estimate.c:118 +#: .././fsr/xfs_fsr.c:900 #, c-format -msgid "already have external log noted, can't have both\n" +msgid "sync failed: %s: %s\n" msgstr "" -#: .././estimate/xfs_estimate.c:127 +#: .././fsr/xfs_fsr.c:906 #, c-format -msgid "already have internal log noted, can't have both\n" +msgid "%s: zero size, ignoring\n" msgstr "" -#: .././estimate/xfs_estimate.c:157 +#: .././fsr/xfs_fsr.c:925 #, c-format -msgid "" -"directory bsize blocks megabytes " -"logsize\n" +msgid "locking check failed: %s\n" msgstr "" -#: .././estimate/xfs_estimate.c:171 +#: .././fsr/xfs_fsr.c:932 #, c-format -msgid "dirsize=%llu\n" +msgid "mandatory lock: %s: ignoring\n" msgstr "" -#: .././estimate/xfs_estimate.c:172 +#: .././fsr/xfs_fsr.c:945 #, c-format -msgid "fullblocks=%llu\n" +msgid "unable to get fs stat on %s: %s\n" msgstr "" -#: .././estimate/xfs_estimate.c:173 +#: .././fsr/xfs_fsr.c:952 #, c-format -msgid "isize=%llu\n" +msgid "insufficient freespace for: %s: size=%lld: ignoring\n" msgstr "" -#: .././estimate/xfs_estimate.c:175 +#: .././fsr/xfs_fsr.c:959 #, c-format -msgid "%llu regular files\n" +msgid "failed to get inode attrs: %s\n" msgstr "" -#: .././estimate/xfs_estimate.c:176 +#: .././fsr/xfs_fsr.c:964 #, c-format -msgid "%llu symbolic links\n" +msgid "%s: immutable/append, ignoring\n" msgstr "" -#: .././estimate/xfs_estimate.c:177 +#: .././fsr/xfs_fsr.c:969 #, c-format -msgid "%llu directories\n" +msgid "%s: marked as don't defrag, ignoring\n" msgstr "" -#: .././estimate/xfs_estimate.c:178 +#: .././fsr/xfs_fsr.c:975 #, c-format -msgid "%llu special files\n" +msgid "cannot get realtime geometry for: %s\n" msgstr "" -#: .././estimate/xfs_estimate.c:191 +#: .././fsr/xfs_fsr.c:980 #, c-format -msgid "%s will take about %.1f megabytes\n" +msgid "low on realtime free space: %s: ignoring file\n" msgstr "" -#: .././estimate/xfs_estimate.c:198 +#: .././fsr/xfs_fsr.c:987 #, c-format -msgid "%-39s %5llu %8llu %10.1fMB %10llu\n" +msgid "cannot open: %s: Permission denied\n" msgstr "" -#: .././estimate/xfs_estimate.c:204 -#, c-format -msgid "\twith the external log using %llu blocks " +#: .././fsr/xfs_fsr.c:1045 .././fsr/xfs_fsr.c:1095 .././fsr/xfs_fsr.c:1187 +msgid "could not set ATTR\n" msgstr "" -#: .././estimate/xfs_estimate.c:206 +#: .././fsr/xfs_fsr.c:1054 #, c-format -msgid "or about %.1f megabytes\n" +msgid "unable to stat temp file: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:196 +#: .././fsr/xfs_fsr.c:1072 #, c-format -msgid "%s: cannot read %s\n" +msgid "unable to get bstat on temp file: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:275 +#: .././fsr/xfs_fsr.c:1077 #, c-format -msgid "%s: Stats not yet supported for XFS\n" +msgid "orig forkoff %d, temp forkoff %d\n" msgstr "" -#: .././fsr/xfs_fsr.c:339 -#, c-format -msgid "%s: could not stat: %s: %s\n" +#: .././fsr/xfs_fsr.c:1126 +msgid "FSGETXATTRA failed on target\n" msgstr "" -#: .././fsr/xfs_fsr.c:358 -#, c-format -msgid "%s: char special not supported: %s\n" +#: .././fsr/xfs_fsr.c:1142 +msgid "big ATTR set failed\n" msgstr "" -#: .././fsr/xfs_fsr.c:364 +#: .././fsr/xfs_fsr.c:1163 #, c-format -msgid "%s: cannot defragment: %s: Not XFS\n" +msgid "forkoff diff %d too large!\n" msgstr "" -#: .././fsr/xfs_fsr.c:374 +#: .././fsr/xfs_fsr.c:1180 #, c-format -msgid "%s: not fsys dev, dir, or reg file, ignoring\n" +msgid "data fork growth unimplemented\n" msgstr "" -#: .././fsr/xfs_fsr.c:389 -#, c-format -msgid "" -"Usage: %s [-d] [-v] [-n] [-s] [-g] [-t time] [-p passes] [-f leftf] [-m " -"mtab]\n" -" %s [-d] [-v] [-n] [-s] [-g] xfsdev | dir | file ...\n" -"\n" -"Options:\n" -" -n Do nothing, only interesting with -v. Not\n" -" effective with in mtab mode.\n" -" -s\t\tPrint statistics only.\n" -" -g Print to syslog (default if stdout not a tty).\n" -" -t time How long to run in seconds.\n" -" -p passes\tNumber of passes before terminating global re-org.\n" -" -f leftoff Use this instead of %s.\n" -" -m mtab Use something other than /etc/mtab.\n" -" -d Debug, print even more.\n" -" -v\t\tVerbose, more -v's more verbose.\n" +#: .././fsr/xfs_fsr.c:1195 +msgid "set temp attr\n" msgstr "" -#: .././fsr/xfs_fsr.c:420 -#, c-format -msgid "could not open mtab file: %s\n" +#: .././fsr/xfs_fsr.c:1198 +msgid "failed to match fork offset\n" msgstr "" -#: .././fsr/xfs_fsr.c:426 .././fsr/xfs_fsr.c:458 +#: .././fsr/xfs_fsr.c:1244 #, c-format -msgid "out of memory: %s\n" +msgid "%s already fully defragmented.\n" msgstr "" -#: .././fsr/xfs_fsr.c:449 +#: .././fsr/xfs_fsr.c:1250 #, c-format -msgid "Skipping %s: not mounted rw\n" +msgid "%s extents=%d can_save=%d tmp=%s\n" msgstr "" -#: .././fsr/xfs_fsr.c:463 +#: .././fsr/xfs_fsr.c:1256 #, c-format -msgid "out of memory on realloc: %s\n" +msgid "could not open tmp file: %s: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:474 +#: .././fsr/xfs_fsr.c:1264 #, c-format -msgid "strdup(%s) failed\n" +msgid "failed to set ATTR fork on tmp: %s:\n" msgstr "" -#: .././fsr/xfs_fsr.c:484 +#: .././fsr/xfs_fsr.c:1271 #, c-format -msgid "no rw xfs file systems in mtab: %s\n" +msgid "could not set inode attrs on tmp: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:488 +#: .././fsr/xfs_fsr.c:1278 #, c-format -msgid "Found %d mounted, writable, XFS filesystems\n" +msgid "could not get DirectIO info on tmp: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:518 +#: .././fsr/xfs_fsr.c:1293 #, c-format -msgid "%s: open failed\n" +msgid "DEBUG: fsize=%lld blsz_dio=%d d_min=%d d_max=%d pgsz=%d\n" msgstr "" -#: .././fsr/xfs_fsr.c:533 +#: .././fsr/xfs_fsr.c:1300 #, c-format -msgid "Can't use %s: mode=0%o own=%d nlink=%d\n" +msgid "could not allocate buf: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:553 +#: .././fsr/xfs_fsr.c:1310 #, c-format -msgid "could not read %s, starting with %s\n" +msgid "could not open fragfile: %s : %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:590 +#: .././fsr/xfs_fsr.c:1325 #, c-format -msgid "START: pass=%d ino=%llu %s %s\n" +msgid "could not trunc tmp %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:607 +#: .././fsr/xfs_fsr.c:1329 .././fsr/xfs_fsr.c:1349 .././fsr/xfs_fsr.c:1377 #, c-format -msgid "Completed all %d passes\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:617 -msgid "couldn't fork sub process:" +msgid "could not lseek in tmpfile: %s : %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:654 +#: .././fsr/xfs_fsr.c:1344 #, c-format -msgid "open(%s) failed: %s\n" +msgid "could not pre-allocate tmp space: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:661 -#, c-format -msgid "write(%s) failed: %s\n" +#: .././fsr/xfs_fsr.c:1357 +msgid "Couldn't rewind on temporary file\n" msgstr "" -#: .././fsr/xfs_fsr.c:668 +#: .././fsr/xfs_fsr.c:1364 #, c-format -msgid "%s startpass %d, endpass %d, time %d seconds\n" +msgid "Temporary file has %d extents (%d in original)\n" msgstr "" -#: .././fsr/xfs_fsr.c:690 +#: .././fsr/xfs_fsr.c:1367 #, c-format -msgid "%s start inode=%llu\n" +msgid "No improvement will be made (skipping): %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:695 +#: .././fsr/xfs_fsr.c:1382 #, c-format -msgid "unable to get handle: %s: %s\n" +msgid "could not lseek in file: %s : %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:701 +#: .././fsr/xfs_fsr.c:1418 #, c-format -msgid "unable to open: %s: %s\n" +msgid "bad read of %d bytes from %s: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:707 +#: .././fsr/xfs_fsr.c:1422 .././fsr/xfs_fsr.c:1454 #, c-format -msgid "Skipping %s: could not get XFS geometry\n" +msgid "bad write of %d bytes to %s: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:739 +#: .././fsr/xfs_fsr.c:1439 #, c-format -msgid "could not open: inode %llu\n" +msgid "bad write2 of %d bytes to %s: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:769 +#: .././fsr/xfs_fsr.c:1444 #, c-format -msgid "%s: xfs_bulkstat: %s\n" +msgid "bad copy to %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:795 +#: .././fsr/xfs_fsr.c:1462 #, c-format -msgid "%s: Directory defragmentation not supported\n" +msgid "could not truncate tmpfile: %s : %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:814 +#: .././fsr/xfs_fsr.c:1467 #, c-format -msgid "unable to construct sys handle for %s: %s\n" +msgid "could not fsync tmpfile: %s : %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:825 +#: .././fsr/xfs_fsr.c:1482 #, c-format -msgid "unable to open sys handle for %s: %s\n" +msgid "failed to fchown tmpfile %s: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:831 +#: .././fsr/xfs_fsr.c:1492 #, c-format -msgid "unable to get bstat on %s: %s\n" +msgid "%s: file type not supported\n" msgstr "" -#: .././fsr/xfs_fsr.c:839 +#: .././fsr/xfs_fsr.c:1496 #, c-format -msgid "unable to open handle %s: %s\n" +msgid "%s: file modified defrag aborted\n" msgstr "" -#: .././fsr/xfs_fsr.c:847 +#: .././fsr/xfs_fsr.c:1501 #, c-format -msgid "Unable to get geom on fs for: %s\n" +msgid "%s: file busy\n" msgstr "" -#: .././fsr/xfs_fsr.c:896 +#: .././fsr/xfs_fsr.c:1503 #, c-format -msgid "sync failed: %s: %s\n" +msgid "XFS_IOC_SWAPEXT failed: %s: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:902 +#: .././fsr/xfs_fsr.c:1511 #, c-format -msgid "%s: zero size, ignoring\n" +msgid "extents before:%d after:%d %s %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:921 +#: .././fsr/xfs_fsr.c:1545 #, c-format -msgid "locking check failed: %s\n" +msgid "tmp file name too long: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:928 +#: .././fsr/xfs_fsr.c:1595 #, c-format -msgid "mandatory lock: %s: ignoring\n" +msgid "realloc failed: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:941 +#: .././fsr/xfs_fsr.c:1608 #, c-format -msgid "unable to get fs stat on %s: %s\n" +msgid "malloc failed: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:948 +#: .././fsr/xfs_fsr.c:1638 #, c-format -msgid "insufficient freespace for: %s: size=%lld: ignoring\n" +msgid "failed reading extents: inode %llu" msgstr "" -#: .././fsr/xfs_fsr.c:955 -#, c-format -msgid "failed to get inode attrs: %s\n" +#: .././fsr/xfs_fsr.c:1688 +msgid "failed reading extents" msgstr "" -#: .././fsr/xfs_fsr.c:960 +#: .././fsr/xfs_fsr.c:1776 .././fsr/xfs_fsr.c:1790 #, c-format -msgid "%s: immutable/append, ignoring\n" +msgid "tmpdir already exists: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:965 +#: .././fsr/xfs_fsr.c:1779 #, c-format -msgid "%s: marked as don't defrag, ignoring\n" +msgid "could not create tmpdir: %s: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:971 +#: .././fsr/xfs_fsr.c:1792 #, c-format -msgid "cannot get realtime geometry for: %s\n" +msgid "cannot create tmpdir: %s: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:976 +#: .././fsr/xfs_fsr.c:1830 .././fsr/xfs_fsr.c:1838 #, c-format -msgid "low on realtime free space: %s: ignoring file\n" +msgid "could not remove tmpdir: %s: %s\n" msgstr "" -#: .././fsr/xfs_fsr.c:983 -#, c-format -msgid "cannot open: %s: Permission denied\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1040 .././fsr/xfs_fsr.c:1085 .././fsr/xfs_fsr.c:1131 -msgid "could not set ATTR\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1049 -#, c-format -msgid "unable to stat temp file: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1068 -#, c-format -msgid "unable to get bstat on temp file: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1073 -#, c-format -msgid "orig forkoff %d, temp forkoff %d\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1105 -#, c-format -msgid "forkoff diff %d too large!\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1139 -msgid "set temp attr\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1178 -#, c-format -msgid "%s already fully defragmented.\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1183 -#, c-format -msgid "%s extents=%d can_save=%d tmp=%s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1189 -#, c-format -msgid "could not open tmp file: %s: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1197 -#, c-format -msgid "failed to set ATTR fork on tmp: %s:\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1205 -#, c-format -msgid "could not set inode attrs on tmp: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1213 -#, c-format -msgid "could not get DirectIO info on tmp: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1229 -#, c-format -msgid "DEBUG: fsize=%lld blsz_dio=%d d_min=%d d_max=%d pgsz=%d\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1236 -#, c-format -msgid "could not allocate buf: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1247 -#, c-format -msgid "could not open fragfile: %s : %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1264 -#, c-format -msgid "could not trunc tmp %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1279 -#, c-format -msgid "could not pre-allocate tmp space: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1290 -msgid "Couldn't rewind on temporary file\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1299 -#, c-format -msgid "Temporary file has %d extents (%d in original)\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1302 -#, c-format -msgid "No improvement will be made (skipping): %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1346 -#, c-format -msgid "bad read of %d bytes from %s: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1350 .././fsr/xfs_fsr.c:1384 -#, c-format -msgid "bad write of %d bytes to %s: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1367 -#, c-format -msgid "bad write2 of %d bytes to %s: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1372 -#, c-format -msgid "bad copy to %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1407 -#, c-format -msgid "failed to fchown tmpfile %s: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1418 -#, c-format -msgid "%s: file type not supported\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1422 -#, c-format -msgid "%s: file modified defrag aborted\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1427 -#, c-format -msgid "%s: file busy\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1429 -#, c-format -msgid "XFS_IOC_SWAPEXT failed: %s: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1438 -#, c-format -msgid "extents before:%d after:%d %s %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1464 -#, c-format -msgid "tmp file name too long: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1513 -#, c-format -msgid "realloc failed: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1526 -#, c-format -msgid "malloc failed: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1556 -#, c-format -msgid "failed reading extents: inode %llu" -msgstr "" - -#: .././fsr/xfs_fsr.c:1606 -msgid "failed reading extents" -msgstr "" - -#: .././fsr/xfs_fsr.c:1694 .././fsr/xfs_fsr.c:1708 -#, c-format -msgid "tmpdir already exists: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1697 -#, c-format -msgid "could not create tmpdir: %s: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1710 -#, c-format -msgid "cannot create tmpdir: %s: %s\n" -msgstr "" - -#: .././fsr/xfs_fsr.c:1748 .././fsr/xfs_fsr.c:1756 -#, c-format -msgid "could not remove tmpdir: %s: %s\n" -msgstr "" - -#: .././growfs/xfs_growfs.c:34 +#: .././growfs/xfs_growfs.c:26 #, c-format msgid "" "Usage: %s [options] mountpoint\n" @@ -3210,7 +3269,6 @@ "\t-l grow log section\n" "\t-r grow realtime section\n" "\t-n don't change anything, just show geometry\n" -"\t-I allow inode numbers to exceed %d significant bits\n" "\t-i convert log from external to internal format\n" "\t-t alternate location for mount table (/etc/mtab)\n" "\t-x convert log from internal to external format\n" @@ -3222,26 +3280,27 @@ "\t-V print version information\n" msgstr "" -#: .././growfs/xfs_growfs.c:68 +#: .././growfs/xfs_growfs.c:63 #, c-format msgid "" "meta-data=%-22s isize=%-6u agcount=%u, agsize=%u blks\n" -" =%-22s sectsz=%-5u attr=%u\n" +" =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" +" =%-22s crc=%-8u finobt=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" -"naming =version %-14u bsize=%-6u ascii-ci=%d\n" +"naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n" "log =%-22s bsize=%-6u blocks=%u, version=%u\n" " =%-22s sectsz=%-5u sunit=%u blks, lazy-count=%u\n" "realtime =%-22s extsz=%-6u blocks=%llu, rtextents=%llu\n" msgstr "" -#: .././growfs/xfs_growfs.c:83 .././growfs/xfs_growfs.c:444 -#: .././growfs/xfs_growfs.c:445 +#: .././growfs/xfs_growfs.c:80 .././growfs/xfs_growfs.c:453 +#: .././growfs/xfs_growfs.c:454 msgid "internal" msgstr "" -#: .././growfs/xfs_growfs.c:83 .././growfs/xfs_growfs.c:86 -#: .././growfs/xfs_growfs.c:444 .././growfs/xfs_growfs.c:445 +#: .././growfs/xfs_growfs.c:80 .././growfs/xfs_growfs.c:83 +#: .././growfs/xfs_growfs.c:453 .././growfs/xfs_growfs.c:454 msgid "external" msgstr "" @@ -3260,770 +3319,792 @@ msgid "%s: cannot determine geometry of filesystem mounted at %s: %s\n" msgstr "" -#: .././growfs/xfs_growfs.c:268 +#: .././growfs/xfs_growfs.c:273 #, c-format msgid "%s: failed to access data device for %s\n" msgstr "" -#: .././growfs/xfs_growfs.c:273 +#: .././growfs/xfs_growfs.c:278 #, c-format msgid "%s: failed to access external log for %s\n" msgstr "" -#: .././growfs/xfs_growfs.c:279 +#: .././growfs/xfs_growfs.c:284 #, c-format msgid "%s: failed to access realtime device for %s\n" msgstr "" -#: .././growfs/xfs_growfs.c:314 +#: .././growfs/xfs_growfs.c:323 #, c-format msgid "data size %lld too large, maximum is %lld\n" msgstr "" -#: .././growfs/xfs_growfs.c:321 +#: .././growfs/xfs_growfs.c:330 #, c-format msgid "data size %lld too small, old size is %lld\n" msgstr "" -#: .././growfs/xfs_growfs.c:329 +#: .././growfs/xfs_growfs.c:338 #, c-format msgid "data size unchanged, skipping\n" msgstr "" -#: .././growfs/xfs_growfs.c:332 +#: .././growfs/xfs_growfs.c:341 #, c-format msgid "inode max pct unchanged, skipping\n" msgstr "" -#: .././growfs/xfs_growfs.c:339 .././growfs/xfs_growfs.c:378 -#: .././growfs/xfs_growfs.c:413 +#: .././growfs/xfs_growfs.c:348 .././growfs/xfs_growfs.c:387 +#: .././growfs/xfs_growfs.c:422 #, c-format msgid "%s: growfs operation in progress already\n" msgstr "" -#: .././growfs/xfs_growfs.c:343 +#: .././growfs/xfs_growfs.c:352 #, c-format msgid "%s: XFS_IOC_FSGROWFSDATA xfsctl failed: %s\n" msgstr "" -#: .././growfs/xfs_growfs.c:359 +#: .././growfs/xfs_growfs.c:368 #, c-format msgid "realtime size %lld too large, maximum is %lld\n" msgstr "" -#: .././growfs/xfs_growfs.c:365 +#: .././growfs/xfs_growfs.c:374 #, c-format msgid "realtime size %lld too small, old size is %lld\n" msgstr "" -#: .././growfs/xfs_growfs.c:371 +#: .././growfs/xfs_growfs.c:380 #, c-format msgid "realtime size unchanged, skipping\n" msgstr "" -#: .././growfs/xfs_growfs.c:382 +#: .././growfs/xfs_growfs.c:391 #, c-format msgid "%s: realtime growth not implemented\n" msgstr "" -#: .././growfs/xfs_growfs.c:386 +#: .././growfs/xfs_growfs.c:395 #, c-format msgid "%s: XFS_IOC_FSGROWFSRT xfsctl failed: %s\n" msgstr "" -#: .././growfs/xfs_growfs.c:407 +#: .././growfs/xfs_growfs.c:416 #, c-format msgid "log size unchanged, skipping\n" msgstr "" -#: .././growfs/xfs_growfs.c:417 +#: .././growfs/xfs_growfs.c:426 #, c-format msgid "%s: log growth not supported yet\n" msgstr "" -#: .././growfs/xfs_growfs.c:421 +#: .././growfs/xfs_growfs.c:430 #, c-format msgid "%s: XFS_IOC_FSGROWFSLOG xfsctl failed: %s\n" msgstr "" -#: .././growfs/xfs_growfs.c:429 +#: .././growfs/xfs_growfs.c:438 #, c-format msgid "%s: XFS_IOC_FSGEOMETRY xfsctl failed: %s\n" msgstr "" -#: .././growfs/xfs_growfs.c:434 +#: .././growfs/xfs_growfs.c:443 #, c-format msgid "data blocks changed from %lld to %lld\n" msgstr "" -#: .././growfs/xfs_growfs.c:437 +#: .././growfs/xfs_growfs.c:446 #, c-format msgid "inode max percent changed from %d to %d\n" msgstr "" -#: .././growfs/xfs_growfs.c:440 +#: .././growfs/xfs_growfs.c:449 #, c-format msgid "log blocks changed from %d to %d\n" msgstr "" -#: .././growfs/xfs_growfs.c:443 +#: .././growfs/xfs_growfs.c:452 #, c-format msgid "log changed from %s to %s\n" msgstr "" -#: .././growfs/xfs_growfs.c:447 +#: .././growfs/xfs_growfs.c:456 #, c-format msgid "realtime blocks changed from %lld to %lld\n" msgstr "" -#: .././growfs/xfs_growfs.c:450 +#: .././growfs/xfs_growfs.c:459 #, c-format msgid "realtime extent size changed from %d to %d\n" msgstr "" -#: .././io/open.c:53 -msgid "socket" -msgstr "" - -#: .././io/open.c:55 -msgid "directory" -msgstr "" - -#: .././io/open.c:57 -msgid "char device" +#: .././io/attr.c:59 +#, c-format +msgid "" +"\n" +" displays the set of extended inode flags associated with the current file\n" +"\n" +" Each individual flag is displayed as a single character, in this order:\n" +" r -- file data is stored in the realtime section\n" +" p -- file has preallocated extents (cannot be changed using chattr)\n" +" i -- immutable, file cannot be modified\n" +" a -- append-only, file can only be appended to\n" +" s -- all updates are synchronous\n" +" A -- the access time is not updated for this inode\n" +" d -- do not include this file in a dump of the filesystem\n" +" t -- child created in this directory has realtime bit set by default\n" +" P -- child created in this directory has parents project ID by default\n" +" n -- symbolic links cannot be created in this directory\n" +" e -- for non-realtime files, observe the inode extent size value\n" +" E -- children created in this directory inherit the extent size value\n" +" f -- do not include this file when defragmenting the filesystem\n" +" S -- enable filestreams allocator for this directory\n" +"\n" +" Options:\n" +" -R -- recursively descend (useful when current file is a directory)\n" +" -D -- recursively descend, but only list attributes on directories\n" +" -a -- show all flags which can be set alongside those which are set\n" +" -v -- verbose mode; show long names of flags, not single characters\n" +"\n" msgstr "" -#: .././io/open.c:59 -msgid "block device" +#: .././io/attr.c:90 +#, c-format +msgid "" +"\n" +" modifies the set of extended inode flags associated with the current file\n" +"\n" +" Examples:\n" +" 'chattr +a' - sets the append-only flag\n" +" 'chattr -a' - clears the append-only flag\n" +"\n" +" -R -- recursively descend (useful when current file is a directory)\n" +" -D -- recursively descend, only modifying attributes on directories\n" +" +/-r -- set/clear the realtime flag\n" +" +/-i -- set/clear the immutable flag\n" +" +/-a -- set/clear the append-only flag\n" +" +/-s -- set/clear the sync flag\n" +" +/-A -- set/clear the no-atime flag\n" +" +/-d -- set/clear the no-dump flag\n" +" +/-t -- set/clear the realtime inheritance flag\n" +" +/-P -- set/clear the project ID inheritance flag\n" +" +/-n -- set/clear the no-symbolic-links flag\n" +" +/-e -- set/clear the extent-size flag\n" +" +/-E -- set/clear the extent-size inheritance flag\n" +" +/-f -- set/clear the no-defrag flag\n" +" +/-S -- set/clear the filestreams allocator flag\n" +" Note1: user must have certain capabilities to modify immutable/append-" +"only.\n" +" Note2: immutable/append-only files cannot be deleted; removing these files\n" +" requires the immutable/append-only flag to be cleared first.\n" +" Note3: the realtime flag can only be set if the filesystem has a realtime\n" +" section, and the (regular) file must be empty when the flag is set.\n" +"\n" msgstr "" -#: .././io/open.c:61 -msgid "regular file" +#: .././io/attr.c:171 .././io/attr.c:247 .././io/open.c:424 .././io/open.c:496 +#: .././io/open.c:620 .././io/open.c:642 .././libxfs/init.c:109 +#: .././mkfs/proto.c:293 .././quota/project.c:118 .././quota/project.c:163 +#: .././quota/project.c:210 +#, c-format +msgid "%s: cannot open %s: %s\n" msgstr "" -#: .././io/open.c:63 -msgid "symbolic link" +#: .././io/attr.c:174 .././io/attr.c:221 .././io/attr.c:250 .././io/attr.c:321 +#: .././quota/project.c:122 .././quota/project.c:168 .././quota/project.c:215 +#, c-format +msgid "%s: cannot get flags on %s: %s\n" msgstr "" -#: .././io/open.c:65 -msgid "fifo" +#: .././io/attr.c:256 .././io/attr.c:327 +#, c-format +msgid "%s: cannot set flags on %s: %s\n" msgstr "" -#: .././io/open.c:80 .././io/open.c:718 +#: .././io/attr.c:291 .././io/attr.c:305 #, c-format -msgid "fd.path = \"%s\"\n" +msgid "%s: unknown flag\n" msgstr "" -#: .././io/open.c:81 +#: .././io/attr.c:311 #, c-format -msgid "fd.flags = %s,%s,%s%s%s%s\n" +msgid "%s: bad chattr command, not +/-X\n" msgstr "" -#: .././io/open.c:82 .././io/file.c:42 -msgid "sync" +#: .././io/attr.c:338 +msgid "[-R|-D] [+/-" msgstr "" -#: .././io/open.c:82 .././io/file.c:42 -msgid "non-sync" +#: .././io/attr.c:343 +msgid "change extended inode flags on the currently open file" msgstr "" -#: .././io/open.c:83 .././io/file.c:43 -msgid "direct" -msgstr "" - -#: .././io/open.c:83 .././io/file.c:43 -msgid "non-direct" -msgstr "" - -#: .././io/open.c:84 .././io/file.c:44 -msgid "read-only" -msgstr "" - -#: .././io/open.c:84 .././io/file.c:44 -msgid "read-write" +#: .././io/attr.c:348 +msgid "[-R|-D|-a|-v]" msgstr "" -#: .././io/open.c:85 .././io/file.c:45 -msgid ",real-time" +#: .././io/attr.c:353 +msgid "list extended inode flags set on the currently open file" msgstr "" -#: .././io/open.c:86 .././io/file.c:46 -msgid ",append-only" +#: .././io/bmap.c:30 +#, c-format +msgid "" +"\n" +" prints the block mapping for an XFS file's data or attribute forks\n" +" Example:\n" +" 'bmap -vp' - tabular format verbose map, including unwritten extents\n" +"\n" +" bmap prints the map of disk blocks used by the current file.\n" +" The map lists each extent used by the file, as well as regions in the\n" +" file that do not have any corresponding blocks (holes).\n" +" By default, each line of the listing takes the following form:\n" +" extent: [startoffset..endoffset]: startblock..endblock\n" +" Holes are marked by replacing the startblock..endblock with 'hole'.\n" +" All the file offsets and disk blocks are in units of 512-byte blocks.\n" +" -a -- prints the attribute fork map instead of the data fork.\n" +" -d -- suppresses a DMAPI read event, offline portions shown as holes.\n" +" -l -- also displays the length of each extent in 512-byte blocks.\n" +" -n -- query n extents.\n" +" -p -- obtain all unwritten extents as well (w/ -v show which are " +"unwritten.)\n" +" -v -- Verbose information, specify ag info. Show flags legend on 2nd -v\n" +" Note: the bmap for non-regular files can be obtained provided the file\n" +" was opened appropriately (in particular, must be opened read-only).\n" +"\n" msgstr "" -#: .././io/open.c:87 .././io/file.c:47 -msgid ",non-block" +#: .././io/bmap.c:123 +#, c-format +msgid "%s: can't get geometry [\"%s\"]: %s\n" msgstr "" -#: .././io/open.c:91 +#: .././io/bmap.c:131 #, c-format -msgid "stat.ino = %lld\n" +msgid "%s: cannot read attrs on \"%s\": %s\n" msgstr "" -#: .././io/open.c:92 +#: .././io/bmap.c:149 .././io/fiemap.c:259 #, c-format -msgid "stat.type = %s\n" +msgid "%s: malloc of %d bytes failed.\n" msgstr "" -#: .././io/open.c:93 +#: .././io/bmap.c:197 #, c-format -msgid "stat.size = %lld\n" +msgid "%s: xfsctl(XFS_IOC_GETBMAPX) iflags=0x%x [\"%s\"]: %s\n" msgstr "" -#: .././io/open.c:94 +#: .././io/bmap.c:228 #, c-format -msgid "stat.blocks = %lld\n" +msgid "%s: cannot realloc %d bytes\n" msgstr "" -#: .././io/open.c:96 +#: .././io/bmap.c:237 #, c-format -msgid "stat.atime = %s" +msgid "%s: no extents\n" msgstr "" -#: .././io/open.c:97 +#: .././io/bmap.c:251 .././io/bmap.c:379 .././io/fiemap.c:105 +#: .././io/fiemap.c:340 .././io/fiemap.c:344 #, c-format -msgid "stat.mtime = %s" +msgid "hole" msgstr "" -#: .././io/open.c:98 +#: .././io/bmap.c:260 #, c-format -msgid "stat.ctime = %s" +msgid " %lld blocks\n" msgstr "" -#: .././io/open.c:107 -#, c-format -msgid "fsxattr.xflags = 0x%x " +#: .././io/bmap.c:339 .././io/fiemap.c:94 +msgid "EXT" msgstr "" -#: .././io/open.c:109 -#, c-format -msgid "fsxattr.projid = %u\n" +#: .././io/bmap.c:340 .././io/fiemap.c:95 +msgid "FILE-OFFSET" msgstr "" -#: .././io/open.c:110 -#, c-format -msgid "fsxattr.extsize = %u\n" +#: .././io/bmap.c:341 +msgid "RT-BLOCK-RANGE" msgstr "" -#: .././io/open.c:111 -#, c-format -msgid "fsxattr.nextents = %u\n" +#: .././io/bmap.c:341 .././io/fiemap.c:96 +msgid "BLOCK-RANGE" msgstr "" -#: .././io/open.c:112 -#, c-format -msgid "fsxattr.naextents = %u\n" +#: .././io/bmap.c:342 +msgid "AG" msgstr "" -#: .././io/open.c:117 -#, c-format -msgid "dioattr.mem = 0x%x\n" +#: .././io/bmap.c:343 +msgid "AG-OFFSET" msgstr "" -#: .././io/open.c:118 -#, c-format -msgid "dioattr.miniosz = %u\n" +#: .././io/bmap.c:344 .././io/fiemap.c:97 +msgid "TOTAL" msgstr "" -#: .././io/open.c:119 -#, c-format -msgid "dioattr.maxiosz = %u\n" +#: .././io/bmap.c:345 +msgid " FLAGS" msgstr "" -#: .././io/open.c:235 +#: .././io/bmap.c:413 #, c-format -msgid "" -"\n" -" opens a new file in the requested mode\n" -"\n" -" Example:\n" -" 'open -cd /tmp/data' - creates/opens data file read-write for direct IO\n" -"\n" -" Opens a file for subsequent use by all of the other xfs_io commands.\n" -" With no arguments, open uses the stat command to show the current file.\n" -" -a -- open with the O_APPEND flag (append-only mode)\n" -" -d -- open with O_DIRECT (non-buffered IO, note alignment constraints)\n" -" -f -- open with O_CREAT (create the file if it doesn't exist)\n" -" -m -- permissions to use in case a new file is created (default 0600)\n" -" -n -- open with O_NONBLOCK\n" -" -r -- open with O_RDONLY, the default is O_RDWR\n" -" -s -- open with O_SYNC\n" -" -t -- open with O_TRUNC (truncate the file to zero length if it exists)\n" -" -R -- mark the file as a realtime XFS file immediately after opening it\n" -" Note1: usually read/write direct IO requests must be blocksize aligned;\n" -" some kernels, however, allow sectorsize alignment for direct IO.\n" -" Note2: the bmap for non-regular files can be obtained provided the file\n" -" was opened correctly (in particular, must be opened read-only).\n" -"\n" +msgid " FLAG Values:\n" msgstr "" -#: .././io/open.c:272 .././io/mmap.c:168 .././io/mmap.c:175 .././io/mmap.c:178 -#: .././io/init.c:102 +#: .././io/bmap.c:414 #, c-format -msgid "no files are open, try 'help open'\n" +msgid " %*.*o Unwritten preallocated extent\n" msgstr "" -#: .././io/open.c:294 .././io/init.c:157 +#: .././io/bmap.c:416 #, c-format -msgid "non-numeric mode -- %s\n" +msgid " %*.*o Doesn't begin on stripe unit\n" msgstr "" -#: .././io/open.c:373 +#: .././io/bmap.c:418 #, c-format -msgid "" -"\n" -" displays the project identifier associated with the current path\n" -"\n" -" Options:\n" -" -R -- recursively descend (useful when current path is a directory)\n" -" -D -- recursively descend, but only list projects on directories\n" -"\n" +msgid " %*.*o Doesn't end on stripe unit\n" msgstr "" -#: .././io/open.c:396 .././io/open.c:468 .././io/open.c:592 .././io/open.c:614 -#: .././io/attr.c:171 .././io/attr.c:247 .././libxfs/init.c:110 -#: .././mkfs/proto.c:284 .././quota/project.c:118 .././quota/project.c:163 -#: .././quota/project.c:210 +#: .././io/bmap.c:420 #, c-format -msgid "%s: cannot open %s: %s\n" +msgid " %*.*o Doesn't begin on stripe width\n" msgstr "" -#: .././io/open.c:439 +#: .././io/bmap.c:422 #, c-format -msgid "projid = %u\n" +msgid " %*.*o Doesn't end on stripe width\n" msgstr "" -#: .././io/open.c:447 -#, c-format -msgid "" -"\n" -" modifies the project identifier associated with the current path\n" -"\n" -" -R -- recursively descend (useful when current path is a directory)\n" -" -D -- recursively descend, only modifying projects on directories\n" -"\n" +#: .././io/bmap.c:438 +msgid "[-adlpv] [-n nx]" msgstr "" -#: .././io/open.c:506 -#, c-format -msgid "invalid project ID -- %s\n" +#: .././io/bmap.c:439 +msgid "print block mapping for an XFS file" msgstr "" -#: .././io/open.c:522 +#: .././io/fadvise.c:31 #, c-format msgid "" "\n" -" report or modify preferred extent size (in bytes) for the current path\n" +" advise the page cache about expected I/O patterns on the current file\n" "\n" -" -R -- recursively descend (useful when current path is a directory)\n" -" -D -- recursively descend, only modifying extsize on directories\n" +" Modifies kernel page cache behaviour when operating on the current file.\n" +" The range arguments are required by some advise commands ([*] below).\n" +" With no arguments, the POSIX_FADV_NORMAL advice is implied.\n" +" -d -- don't need these pages (POSIX_FADV_DONTNEED) [*]\n" +" -n -- data will be accessed once (POSIX_FADV_NOREUSE) [*]\n" +" -r -- expect random page references (POSIX_FADV_RANDOM)\n" +" -s -- expect sequential page references (POSIX_FADV_SEQUENTIAL)\n" +" -w -- will need these pages (POSIX_FADV_WILLNEED) [*]\n" +" Notes: these interfaces are not supported in Linux kernels before 2.6.\n" +" NORMAL sets the default readahead setting on the file.\n" +" RANDOM sets the readahead setting on the file to zero.\n" +" SEQUENTIAL sets double the default readahead setting on the file.\n" +" WILLNEED and NOREUSE are equivalent, and force the maximum readahead.\n" "\n" msgstr "" -#: .././io/open.c:565 -#, c-format -msgid "invalid target file type - file %s\n" -msgstr "" - -#: .././io/open.c:651 -#, c-format -msgid "non-numeric extsize argument -- %s\n" -msgstr "" - -#: .././io/open.c:698 +#: .././io/fadvise.c:92 .././io/madvise.c:87 .././io/mincore.c:48 +#: .././io/mmap.c:206 .././io/mmap.c:301 .././io/mmap.c:387 .././io/mmap.c:546 +#: .././io/sendfile.c:126 .././io/sync_file_range.c:75 .././io/prealloc.c:65 +#: .././io/pwrite.c:344 #, c-format -msgid "invalid setfl argument -- '%c'\n" +msgid "non-numeric offset argument -- %s\n" msgstr "" -#: .././io/open.c:722 +#: .././io/fadvise.c:99 .././io/madvise.c:94 .././io/mincore.c:54 +#: .././io/mmap.c:212 .././io/mmap.c:308 .././io/mmap.c:394 .././io/mmap.c:553 +#: .././io/sendfile.c:133 .././io/sync_file_range.c:82 .././io/pread.c:452 +#: .././io/pread.c:460 .././io/prealloc.c:70 .././io/pwrite.c:350 #, c-format -msgid "statfs.f_bsize = %lld\n" +msgid "non-numeric length argument -- %s\n" msgstr "" -#: .././io/open.c:723 -#, c-format -msgid "statfs.f_blocks = %lld\n" +#: .././io/fadvise.c:122 +msgid "[-dnrsw] [off len]" msgstr "" -#: .././io/open.c:725 -#, c-format -msgid "statfs.f_frsize = %lld\n" +#: .././io/fadvise.c:123 +msgid "advisory commands for sections of a file" msgstr "" -#: .././io/open.c:727 +#: .././io/freeze.c:37 #, c-format -msgid "statfs.f_bavail = %lld\n" +msgid "%s: cannot freeze filesystem at %s: %s\n" msgstr "" -#: .././io/open.c:729 +#: .././io/freeze.c:54 #, c-format -msgid "statfs.f_files = %lld\n" +msgid "%s: cannot unfreeze filesystem mounted at %s: %s\n" msgstr "" -#: .././io/open.c:730 -#, c-format -msgid "statfs.f_ffree = %lld\n" +#: .././io/freeze.c:70 +msgid "freeze filesystem of current file" msgstr "" -#: .././io/open.c:737 -#, c-format -msgid "geom.bsize = %u\n" +#: .././io/freeze.c:77 +msgid "unfreeze filesystem of current file" msgstr "" -#: .././io/open.c:738 -#, c-format -msgid "geom.agcount = %u\n" +#: .././io/fsync.c:59 +msgid "calls fsync(2) to flush all in-core file state to disk" msgstr "" -#: .././io/open.c:739 -#, c-format -msgid "geom.agblocks = %u\n" +#: .././io/fsync.c:66 +msgid "calls fdatasync(2) to flush the files in-core data to disk" msgstr "" -#: .././io/open.c:740 -#, c-format -msgid "geom.datablocks = %llu\n" +#: .././io/getrusage.c:118 +msgid "report process resource usage" msgstr "" -#: .././io/open.c:742 +#: .././io/inject.c:109 #, c-format -msgid "geom.rtblocks = %llu\n" +msgid "" +"\n" +" inject errors into the filesystem of the currently open file\n" +"\n" +" Example:\n" +" 'inject readagf' - cause errors on allocation group freespace reads\n" +"\n" +" Causes the kernel to generate and react to errors within XFS, provided\n" +" the XFS kernel code has been built with debugging features enabled.\n" +" With no arguments, displays the list of error injection tags.\n" +"\n" msgstr "" -#: .././io/open.c:744 +#: .././io/inject.c:135 #, c-format -msgid "geom.rtextents = %llu\n" +msgid "no such tag -- %s\n" msgstr "" -#: .././io/open.c:746 -#, c-format -msgid "geom.rtextsize = %u\n" +#: .././io/inject.c:156 +msgid "[tag ...]" msgstr "" -#: .././io/open.c:747 -#, c-format -msgid "geom.sunit = %u\n" +#: .././io/inject.c:157 +msgid "inject errors into a filesystem" msgstr "" -#: .././io/open.c:748 +#: .././io/madvise.c:32 #, c-format -msgid "geom.swidth = %u\n" +msgid "" +"\n" +" advise the page cache about access patterns expected for a mapping\n" +"\n" +" Modifies page cache behavior when operating on the current mapping.\n" +" The range arguments are required by some advise commands ([*] below).\n" +" With no arguments, the POSIX_MADV_NORMAL advice is implied.\n" +" -d -- don't need these pages (POSIX_MADV_DONTNEED) [*]\n" +" -r -- expect random page references (POSIX_MADV_RANDOM)\n" +" -s -- expect sequential page references (POSIX_MADV_SEQUENTIAL)\n" +" -w -- will need these pages (POSIX_MADV_WILLNEED) [*]\n" +" Notes:\n" +" NORMAL sets the default readahead setting on the file.\n" +" RANDOM sets the readahead setting on the file to zero.\n" +" SEQUENTIAL sets double the default readahead setting on the file.\n" +" WILLNEED forces the maximum readahead.\n" +"\n" msgstr "" -#: .././io/open.c:753 +#: .././io/madvise.c:98 .././io/mincore.c:58 #, c-format -msgid "counts.freedata = %llu\n" +msgid "length argument too large -- %lld\n" msgstr "" -#: .././io/open.c:755 -#, c-format -msgid "counts.freertx = %llu\n" +#: .././io/madvise.c:127 +msgid "[-drsw] [off len]" msgstr "" -#: .././io/open.c:757 -#, c-format -msgid "counts.freeino = %llu\n" +#: .././io/madvise.c:128 +msgid "give advice about use of memory" msgstr "" -#: .././io/open.c:759 +#: .././io/mincore.c:92 .././io/mincore.c:102 #, c-format -msgid "counts.allocino = %llu\n" -msgstr "" - -#: .././io/open.c:774 -msgid "[-acdrstx] [path]" -msgstr "" - -#: .././io/open.c:775 -msgid "open the file specified by path" -msgstr "" - -#: .././io/open.c:783 -msgid "[-v]" +msgid "0x%lx %lu pages (%llu : %lu)\n" msgstr "" -#: .././io/open.c:784 -msgid "statistics on the currently open file" +#: .././io/mincore.c:122 +msgid "[off len]" msgstr "" -#: .././io/open.c:792 -msgid "close the current open file" +#: .././io/mincore.c:123 +msgid "find mapping pages that are memory resident" msgstr "" -#: .././io/open.c:796 -msgid "[-adx]" +#: .././io/mmap.c:76 +#, c-format +msgid "offset (%lld) is before start of mapping (%lld)\n" msgstr "" -#: .././io/open.c:799 -msgid "set/clear append/direct flags on the open file" +#: .././io/mmap.c:82 +#, c-format +msgid "offset (%lld) is beyond end of mapping (%lld)\n" msgstr "" -#: .././io/open.c:805 -msgid "statistics on the filesystem of the currently open file" +#: .././io/mmap.c:87 +#, c-format +msgid "range (%lld:%lld) is beyond mapping (%lld:%ld)\n" msgstr "" -#: .././io/open.c:809 -msgid "[-D | -R] projid" +#: .././io/mmap.c:93 +#, c-format +msgid "offset address (%p) is not page aligned\n" msgstr "" -#: .././io/open.c:814 -msgid "change project identifier on the currently open file" +#: .././io/mmap.c:133 +#, c-format +msgid "" +"\n" +" maps a range within the current file into memory\n" +"\n" +" Example:\n" +" 'mmap -rw 0 1m' - maps one megabyte from the start of the current file\n" +"\n" +" Memory maps a range of a file for subsequent use by other xfs_io commands.\n" +" With no arguments, mmap shows the current mappings. The current mapping\n" +" can be set by using the single argument form (mapping number or address).\n" +" If two arguments are specified (a range), a new mapping is created and the\n" +" following options are available:\n" +" -r -- map with PROT_READ protection\n" +" -w -- map with PROT_WRITE protection\n" +" -x -- map with PROT_EXEC protection\n" +" If no protection mode is specified, all are used by default.\n" +"\n" msgstr "" -#: .././io/open.c:819 -msgid "[-D | -R]" +#: .././io/mmap.c:167 .././io/mmap.c:174 .././io/init.c:109 +#, c-format +msgid "no mapped regions, try 'help mmap'\n" msgstr "" -#: .././io/open.c:824 -msgid "list project identifier set on the currently open file" +#: .././io/mmap.c:168 .././io/mmap.c:175 .././io/mmap.c:178 .././io/init.c:105 +#: .././io/open.c:292 +#, c-format +msgid "no files are open, try 'help open'\n" msgstr "" -#: .././io/open.c:829 -msgid "[-D | -R] [extsize]" +#: .././io/mmap.c:254 +#, c-format +msgid "" +"\n" +" flushes a range of bytes in the current memory mapping\n" +"\n" +" Writes all modified copies of pages over the specified range (or entire\n" +" mapping if no range specified) to their backing storage locations. Also,\n" +" optionally invalidates so that subsequent references to the pages will be\n" +" obtained from their backing storage locations (instead of cached copies).\n" +" -a -- perform asynchronous writes (MS_ASYNC)\n" +" -i -- invalidate mapped pages (MS_INVALIDATE)\n" +" -s -- perform synchronous writes (MS_SYNC)\n" +"\n" msgstr "" -#: .././io/open.c:834 -msgid "get/set preferred extent size (in bytes) for the open file" +#: .././io/mmap.c:330 +#, c-format +msgid "" +"\n" +" reads a range of bytes in the current memory mapping\n" +"\n" +" Example:\n" +" 'mread -v 512 20' - dumps 20 bytes read from 512 bytes into the mapping\n" +"\n" +" Accesses a range of the current memory mapping, optionally dumping it to\n" +" the standard output stream (with -v option) for subsequent inspection.\n" +" -f -- verbose mode, dump bytes with offsets relative to start of file.\n" +" -r -- reverse order; start accessing from the end of range, moving " +"backward\n" +" -v -- verbose mode, dump bytes with offsets relative to start of mapping.\n" +" The accesses are performed sequentially from the start offset by default.\n" +" Notes:\n" +" References to whole pages following the end of the backing file results\n" +" in delivery of the SIGBUS signal. SIGBUS signals may also be delivered\n" +" on various filesystem conditions, including quota exceeded errors, and\n" +" for physical device errors (such as unreadable disk blocks). No attempt\n" +" has been made to catch signals at this stage...\n" +"\n" msgstr "" -#: .././io/pread.c:33 +#: .././io/mmap.c:494 #, c-format msgid "" "\n" -" reads a range of bytes in a specified block size from the given offset\n" +" dirties a range of bytes in the current memory mapping\n" "\n" " Example:\n" -" 'pread -v 512 20' - dumps 20 bytes read from 512 bytes into the file\n" -"\n" -" Reads a segment of the currently open file, optionally dumping it to the\n" -" standard output stream (with -v option) for subsequent inspection.\n" -" The reads are performed in sequential blocks starting at offset, with the\n" -" blocksize tunable using the -b option (default blocksize is 4096 bytes),\n" -" unless a different pattern is requested.\n" -" -B -- read backwards through the range from offset (backwards N bytes)\n" -" -F -- read forwards through the range of bytes from offset (default)\n" -" -v -- be verbose, dump out buffers (used when reading forwards)\n" -" -R -- read at random offsets in the range of bytes\n" -" -Z N -- zeed the random number generator (used when reading randomly)\n" -" (heh, zorry, the -s/-S arguments were already in use in pwrite)\n" -" -V N -- use vectored IO with N iovecs of blocksize each (preadv)\n" +" 'mwrite 512 20 - writes 20 bytes at 512 bytes into the current mapping.\n" "\n" -" When in \"random\" mode, the number of read operations will equal the\n" -" number required to do a complete forward/backward scan of the range.\n" -" Note that the offset within the range is chosen at random each time\n" -" (an offset may be read more than once when operating in this mode).\n" +" Stores a byte into memory for a range within a mapping.\n" +" The default stored value is 'X', repeated to fill the range specified.\n" +" -S -- use an alternate seed character\n" +" -r -- reverse order; start storing from the end of range, moving backward\n" +" The stores are performed sequentially from the start offset by default.\n" "\n" msgstr "" -#: .././io/pread.c:398 .././io/pwrite.c:269 +#: .././io/mmap.c:530 .././io/pread.c:437 .././io/pwrite.c:303 +#: .././io/pwrite.c:330 #, c-format -msgid "non-numeric bsize -- %s\n" +msgid "non-numeric seed -- %s\n" msgstr "" -#: .././io/pread.c:428 .././io/pwrite.c:316 -#, c-format -msgid "non-numeric vector count == %s\n" +#: .././io/mmap.c:586 +msgid "[N] | [-rwx] [off len]" msgstr "" -#: .././io/pread.c:437 .././io/pwrite.c:303 .././io/pwrite.c:330 -#: .././io/mmap.c:530 -#, c-format -msgid "non-numeric seed -- %s\n" +#: .././io/mmap.c:588 +msgid "mmap a range in the current file, show mappings" msgstr "" -#: .././io/pread.c:452 .././io/pread.c:460 .././io/pwrite.c:350 -#: .././io/fadvise.c:99 .././io/madvise.c:94 .././io/mincore.c:54 -#: .././io/mmap.c:212 .././io/mmap.c:308 .././io/mmap.c:394 .././io/mmap.c:553 -#: .././io/prealloc.c:60 .././io/sendfile.c:133 .././io/sync_file_range.c:82 -#, c-format -msgid "non-numeric length argument -- %s\n" +#: .././io/mmap.c:597 +msgid "[-r] [off len]" msgstr "" -#: .././io/pread.c:497 -#, c-format -msgid "read %lld/%lld bytes at offset %lld\n" +#: .././io/mmap.c:599 +msgid "reads data from a region in the current memory mapping" msgstr "" -#: .././io/pread.c:499 .././io/pwrite.c:396 .././io/sendfile.c:163 -#, c-format -msgid "%s, %d ops; %s (%s/sec and %.4f ops/sec)\n" +#: .././io/mmap.c:608 +msgid "[-ais] [off len]" msgstr "" -#: .././io/pread.c:518 -msgid "[-b bs] [-v] [-i N] [-FBR [-Z N]] off len" +#: .././io/mmap.c:609 +msgid "flush a region in the current memory mapping" msgstr "" -#: .././io/pread.c:519 -msgid "reads a number of bytes at a specified offset" +#: .././io/mmap.c:618 +msgid "unmaps the current memory mapping" msgstr "" -#: .././io/pwrite.c:32 -#, c-format -msgid "" -"\n" -" writes a range of bytes (in block size increments) from the given offset\n" -"\n" -" Example:\n" -" 'pwrite 512 20' - writes 20 bytes at 512 bytes into the open file\n" -"\n" -" Writes into a segment of the currently open file, using either a buffer\n" -" filled with a set pattern (0xcdcdcdcd) or data read from an input file.\n" -" The writes are performed in sequential blocks starting at offset, with the\n" -" blocksize tunable using the -b option (default blocksize is 4096 bytes),\n" -" unless a different write pattern is requested.\n" -" -S -- use an alternate seed number for filling the write buffer\n" -" -i -- input file, source of data to write (used when writing forward)\n" -" -d -- open the input file for direct IO\n" -" -s -- skip a number of bytes at the start of the input file\n" -" -w -- call fdatasync(2) at the end (included in timing results)\n" -" -W -- call fsync(2) at the end (included in timing results)\n" -" -B -- write backwards through the range from offset (backwards N bytes)\n" -" -F -- write forwards through the range of bytes from offset (default)\n" -" -R -- write at random offsets in the specified range of bytes\n" -" -Z N -- zeed the random number generator (used when writing randomly)\n" -" (heh, zorry, the -s/-S arguments were already in use in pwrite)\n" -" -V N -- use vectored IO with N iovecs of blocksize each (pwritev)\n" -"\n" +#: .././io/mmap.c:626 +msgid "[-r] [-S seed] [off len]" msgstr "" -#: .././io/pwrite.c:296 +#: .././io/mmap.c:628 +msgid "writes data into a region in the current memory mapping" +msgstr "" + +#: .././io/resblks.c:39 #, c-format -msgid "non-numeric skip -- %s\n" +msgid "non-numeric argument -- %s\n" msgstr "" -#: .././io/pwrite.c:344 .././io/fadvise.c:92 .././io/madvise.c:87 -#: .././io/mincore.c:48 .././io/mmap.c:206 .././io/mmap.c:301 -#: .././io/mmap.c:387 .././io/mmap.c:546 .././io/prealloc.c:55 -#: .././io/sendfile.c:126 .././io/sync_file_range.c:75 +#: .././io/resblks.c:51 #, c-format -msgid "non-numeric offset argument -- %s\n" +msgid "reserved blocks = %llu\n" msgstr "" -#: .././io/pwrite.c:394 +#: .././io/resblks.c:53 #, c-format -msgid "wrote %lld/%lld bytes at offset %lld\n" +msgid "available reserved blocks = %llu\n" msgstr "" -#: .././io/pwrite.c:419 -msgid "" -"[-i infile [-d] [-s skip]] [-b bs] [-S seed] [-wW] [-FBR [-Z N]] [-V N] off " -"len" +#: .././io/resblks.c:66 +msgid "[blocks]" msgstr "" -#: .././io/pwrite.c:421 -msgid "writes a number of bytes at a specified offset" +#: .././io/resblks.c:68 +msgid "get and/or set count of reserved filesystem blocks" msgstr "" -#: .././io/attr.c:59 +#: .././io/sendfile.c:32 #, c-format msgid "" "\n" -" displays the set of extended inode flags associated with the current file\n" +" transfer a range of bytes from the given offset between files\n" "\n" -" Each individual flag is displayed as a single character, in this order:\n" -" r -- file data is stored in the realtime section\n" -" p -- file has preallocated extents (cannot be changed using chattr)\n" -" i -- immutable, file cannot be modified\n" -" a -- append-only, file can only be appended to\n" -" s -- all updates are synchronous\n" -" A -- the access time is not updated for this inode\n" -" d -- do not include this file in a dump of the filesystem\n" -" t -- child created in this directory has realtime bit set by default\n" -" P -- child created in this directory has parents project ID by default\n" -" n -- symbolic links cannot be created in this directory\n" -" e -- for non-realtime files, observe the inode extent size value\n" -" E -- children created in this directory inherit the extent size value\n" -" f -- do not include this file when defragmenting the filesystem\n" -" S -- enable filestreams allocator for this directory\n" +" Example:\n" +" 'send -f 2 512 20' - writes 20 bytes at 512 bytes into the open file\n" "\n" -" Options:\n" -" -R -- recursively descend (useful when current file is a directory)\n" -" -D -- recursively descend, but only list attributes on directories\n" -" -a -- show all flags which can be set alongside those which are set\n" -" -v -- verbose mode; show long names of flags, not single characters\n" +" Copies data between one file descriptor and another. Because this copying\n" +" is done within the kernel, sendfile does not need to transfer data to and\n" +" from user space.\n" +" -f -- specifies an input file from which to source data to write\n" +" -i -- specifies an input file name from which to source data to write.\n" +" An offset and length in the source file can be optionally specified.\n" "\n" msgstr "" -#: .././io/attr.c:90 +#: .././io/sendfile.c:103 .././io/file.c:82 .././quota/path.c:112 #, c-format -msgid "" -"\n" -" modifies the set of extended inode flags associated with the current file\n" -"\n" -" Examples:\n" -" 'chattr +a' - sets the append-only flag\n" -" 'chattr -a' - clears the append-only flag\n" -"\n" -" -R -- recursively descend (useful when current file is a directory)\n" -" -D -- recursively descend, only modifying attributes on directories\n" -" +/-r -- set/clear the realtime flag\n" -" +/-i -- set/clear the immutable flag\n" -" +/-a -- set/clear the append-only flag\n" -" +/-s -- set/clear the sync flag\n" -" +/-A -- set/clear the no-atime flag\n" -" +/-d -- set/clear the no-dump flag\n" -" +/-t -- set/clear the realtime inheritance flag\n" -" +/-P -- set/clear the project ID inheritance flag\n" -" +/-n -- set/clear the no-symbolic-links flag\n" -" +/-e -- set/clear the extent-size flag\n" -" +/-E -- set/clear the extent-size inheritance flag\n" -" +/-f -- set/clear the no-defrag flag\n" -" +/-S -- set/clear the filestreams allocator flag\n" -" Note1: user must have certain capabilities to modify immutable/append-" -"only.\n" -" Note2: immutable/append-only files cannot be deleted; removing these files\n" -" requires the immutable/append-only flag to be cleared first.\n" -" Note3: the realtime flag can only be set if the filesystem has a realtime\n" -" section, and the (regular) file must be empty when the flag is set.\n" -"\n" +msgid "value %d is out of range (0-%d)\n" msgstr "" -#: .././io/attr.c:174 .././io/attr.c:221 .././io/attr.c:250 .././io/attr.c:321 -#: .././quota/project.c:122 .././quota/project.c:168 .././quota/project.c:215 +#: .././io/sendfile.c:161 #, c-format -msgid "%s: cannot get flags on %s: %s\n" +msgid "sent %lld/%lld bytes from offset %lld\n" msgstr "" -#: .././io/attr.c:256 .././io/attr.c:327 +#: .././io/sendfile.c:163 .././io/pread.c:499 .././io/pwrite.c:396 #, c-format -msgid "%s: cannot set flags on %s: %s\n" +msgid "%s, %d ops; %s (%s/sec and %.4f ops/sec)\n" msgstr "" -#: .././io/attr.c:291 .././io/attr.c:305 -#, c-format -msgid "%s: unknown flag\n" +#: .././io/sendfile.c:186 +msgid "-i infile | -f N [off len]" msgstr "" -#: .././io/attr.c:311 +#: .././io/sendfile.c:188 +msgid "Transfer data directly between file descriptors" +msgstr "" + +#: .././io/shutdown.c:59 +msgid "[-f]" +msgstr "" + +#: .././io/shutdown.c:61 +msgid "shuts down the filesystem where the current file resides" +msgstr "" + +#: .././io/sync_file_range.c:31 #, c-format -msgid "%s: bad chattr command, not +/-X\n" +msgid "" +"\n" +" Trigger specific writeback commands on a range of the current file\n" +"\n" +" With no options, the SYNC_FILE_RANGE_WRITE is implied.\n" +" -a -- wait for IO to finish after writing (SYNC_FILE_RANGE_WAIT_AFTER).\n" +" -b -- wait for IO to finish before writing (SYNC_FILE_RANGE_WAIT_BEFORE).\n" +" -w -- write dirty data in range (SYNC_FILE_RANGE_WRITE).\n" +"\n" msgstr "" -#: .././io/attr.c:338 -msgid "[-R|-D] [+/-" +#: .././io/sync_file_range.c:102 +msgid "[-abw] off len" msgstr "" -#: .././io/attr.c:343 -msgid "change extended inode flags on the currently open file" +#: .././io/sync_file_range.c:103 +msgid "Control writeback on a range of a file" msgstr "" -#: .././io/attr.c:348 -msgid "[-R|-D|-a|-v]" +#: .././io/truncate.c:38 +#, c-format +msgid "non-numeric truncate argument -- %s\n" msgstr "" -#: .././io/attr.c:353 -msgid "list extended inode flags set on the currently open file" +#: .././io/truncate.c:58 +msgid "off" msgstr "" -#: .././io/bmap.c:30 +#: .././io/truncate.c:60 +msgid "truncates the current file at the given offset" +msgstr "" + +#: .././io/fiemap.c:32 #, c-format msgid "" "\n" -" prints the block mapping for an XFS file's data or attribute forks\n" +" prints the block mapping for a file's data or attribute forks\n" " Example:\n" -" 'bmap -vp' - tabular format verbose map, including unwritten extents\n" +" 'fiemap -v' - tabular format verbose map\n" "\n" -" bmap prints the map of disk blocks used by the current file.\n" +" fiemap prints the map of disk blocks used by the current file.\n" " The map lists each extent used by the file, as well as regions in the\n" " file that do not have any corresponding blocks (holes).\n" " By default, each line of the listing takes the following form:\n" @@ -4031,556 +4112,509 @@ " Holes are marked by replacing the startblock..endblock with 'hole'.\n" " All the file offsets and disk blocks are in units of 512-byte blocks.\n" " -a -- prints the attribute fork map instead of the data fork.\n" -" -d -- suppresses a DMAPI read event, offline portions shown as holes.\n" " -l -- also displays the length of each extent in 512-byte blocks.\n" " -n -- query n extents.\n" -" -p -- obtain all unwritten extents as well (w/ -v show which are " -"unwritten.)\n" -" -v -- Verbose information, specify ag info. Show flags legend on 2nd -v\n" -" Note: the bmap for non-regular files can be obtained provided the file\n" -" was opened appropriately (in particular, must be opened read-only).\n" +" -v -- Verbose information\n" "\n" msgstr "" -#: .././io/bmap.c:123 -#, c-format -msgid "%s: can't get geometry [\"%s\"]: %s\n" +#: .././io/fiemap.c:98 +msgid "FLAGS" msgstr "" -#: .././io/bmap.c:131 +#: .././io/fiemap.c:147 .././io/fiemap.c:161 .././io/fiemap.c:346 #, c-format -msgid "%s: cannot read attrs on \"%s\": %s\n" +msgid " %llu blocks\n" msgstr "" -#: .././io/bmap.c:149 .././io/fiemap.c:210 -#, c-format -msgid "%s: malloc of %d bytes failed.\n" +#: .././io/fiemap.c:366 +msgid "[-alv] [-n nx]" msgstr "" -#: .././io/bmap.c:197 -#, c-format -msgid "%s: xfsctl(XFS_IOC_GETBMAPX) iflags=0x%x [\"%s\"]: %s\n" +#: .././io/fiemap.c:367 +msgid "print block mapping for a file" msgstr "" -#: .././io/bmap.c:228 +#: .././io/seek.c:33 #, c-format -msgid "%s: cannot realloc %d bytes\n" +msgid "" +"\n" +" returns the next hole and/or data offset at or after the requested offset\n" +"\n" +" Example:\n" +" 'seek -d 512'\t\t- offset of data at or following offset 512\n" +" 'seek -a -r 0'\t- offsets of all data and hole in entire file\n" +"\n" +" Returns the offset of the next data and/or hole. There is an implied hole\n" +" at the end of file. If the specified offset is past end of file, or there\n" +" is no data past the specified offset, EOF is returned.\n" +" -a\t-- return the next data and hole starting at the specified offset.\n" +" -d\t-- return the next data starting at the specified offset.\n" +" -h\t-- return the next hole starting at the specified offset.\n" +" -r\t-- return all remaining type(s) starting at the specified offset.\n" +" -s\t-- also print the starting offset.\n" +"\n" msgstr "" -#: .././io/bmap.c:237 -#, c-format -msgid "%s: no extents\n" +#: .././io/seek.c:219 +msgid "-a | -d | -h [-r] off" msgstr "" -#: .././io/bmap.c:251 .././io/bmap.c:379 .././io/fiemap.c:97 -#: .././io/fiemap.c:317 .././io/fiemap.c:321 -#, c-format -msgid "hole" +#: .././io/seek.c:220 +msgid "locate the next data and/or hole" msgstr "" -#: .././io/bmap.c:260 +#: .././io/file.c:39 #, c-format -msgid " %lld blocks\n" +msgid "%c%03d%c %-14s (%s,%s,%s,%s%s%s%s%s)\n" msgstr "" -#: .././io/bmap.c:339 .././io/fiemap.c:243 -msgid "EXT" -msgstr "" - -#: .././io/bmap.c:340 .././io/fiemap.c:244 -msgid "FILE-OFFSET" -msgstr "" - -#: .././io/bmap.c:341 -msgid "RT-BLOCK-RANGE" -msgstr "" - -#: .././io/bmap.c:341 .././io/fiemap.c:245 -msgid "BLOCK-RANGE" +#: .././io/file.c:41 +msgid "foreign" msgstr "" -#: .././io/bmap.c:342 -msgid "AG" +#: .././io/file.c:41 +msgid "xfs" msgstr "" -#: .././io/bmap.c:343 -msgid "AG-OFFSET" +#: .././io/file.c:42 .././io/open.c:97 +msgid "sync" msgstr "" -#: .././io/bmap.c:344 .././io/fiemap.c:246 -msgid "TOTAL" +#: .././io/file.c:42 .././io/open.c:97 +msgid "non-sync" msgstr "" -#: .././io/bmap.c:345 -msgid " FLAGS" +#: .././io/file.c:43 .././io/open.c:98 +msgid "direct" msgstr "" -#: .././io/bmap.c:413 -#, c-format -msgid " FLAG Values:\n" +#: .././io/file.c:43 .././io/open.c:98 +msgid "non-direct" msgstr "" -#: .././io/bmap.c:414 -#, c-format -msgid " %*.*o Unwritten preallocated extent\n" +#: .././io/file.c:44 .././io/open.c:99 +msgid "read-only" msgstr "" -#: .././io/bmap.c:416 -#, c-format -msgid " %*.*o Doesn't begin on stripe unit\n" +#: .././io/file.c:44 .././io/open.c:99 +msgid "read-write" msgstr "" -#: .././io/bmap.c:418 -#, c-format -msgid " %*.*o Doesn't end on stripe unit\n" +#: .././io/file.c:45 .././io/open.c:100 +msgid ",real-time" msgstr "" -#: .././io/bmap.c:420 -#, c-format -msgid " %*.*o Doesn't begin on stripe width\n" +#: .././io/file.c:46 .././io/open.c:101 +msgid ",append-only" msgstr "" -#: .././io/bmap.c:422 -#, c-format -msgid " %*.*o Doesn't end on stripe width\n" +#: .././io/file.c:47 .././io/open.c:102 +msgid ",non-block" msgstr "" -#: .././io/bmap.c:438 -msgid "[-adlpv] [-n nx]" +#: .././io/file.c:48 .././io/open.c:103 +msgid ",tmpfile" msgstr "" -#: .././io/bmap.c:439 -msgid "print block mapping for an XFS file" +#: .././io/file.c:95 .././quota/path.c:126 +msgid "[N]" msgstr "" -#: .././io/fadvise.c:31 -#, c-format -msgid "" -"\n" -" advise the page cache about expected I/O patterns on the current file\n" -"\n" -" Modifies kernel page cache behaviour when operating on the current file.\n" -" The range arguments are required by some advise commands ([*] below).\n" -" With no arguments, the POSIX_FADV_NORMAL advice is implied.\n" -" -d -- don't need these pages (POSIX_FADV_DONTNEED) [*]\n" -" -n -- data will be accessed once (POSIX_FADV_NOREUSE) [*]\n" -" -r -- expect random page references (POSIX_FADV_RANDOM)\n" -" -s -- expect sequential page references (POSIX_FADV_SEQUENTIAL)\n" -" -w -- will need these pages (POSIX_FADV_WILLNEED) [*]\n" -" Notes: these interfaces are not supported in Linux kernels before 2.6.\n" -" NORMAL sets the default readahead setting on the file.\n" -" RANDOM sets the readahead setting on the file to zero.\n" -" SEQUENTIAL sets double the default readahead setting on the file.\n" -" WILLNEED and NOREUSE are equivalent, and force the maximum readahead.\n" -"\n" +#: .././io/file.c:100 +msgid "set the current file" msgstr "" -#: .././io/fadvise.c:122 -msgid "[-dnrsw] [off len]" +#: .././io/file.c:109 +msgid "list current open files and memory mappings" msgstr "" -#: .././io/fadvise.c:123 -msgid "advisory commands for sections of a file" +#: .././io/imap.c:53 +#, c-format +msgid "ino %10llu count %2d mask %016llx\n" msgstr "" -#: .././io/file.c:39 -#, c-format -msgid "%c%03d%c %-14s (%s,%s,%s,%s%s%s%s)\n" +#: .././io/imap.c:71 +msgid "[nentries]" msgstr "" -#: .././io/file.c:41 -msgid "foreign" +#: .././io/imap.c:73 +msgid "inode map for filesystem of current file" msgstr "" -#: .././io/file.c:41 -msgid "xfs" +#: .././io/init.c:35 +#, c-format +msgid "Usage: %s [-adfmnrRstVx] [-p prog] [-c cmd]... file\n" msgstr "" -#: .././io/file.c:81 .././io/sendfile.c:103 .././quota/path.c:112 +#: .././io/init.c:115 #, c-format -msgid "value %d is out of range (0-%d)\n" +msgid "foreign file active, %s command is for XFS filesystems only\n" msgstr "" -#: .././io/file.c:94 .././quota/path.c:126 -msgid "[N]" +#: .././io/init.c:160 .././io/open.c:314 +#, c-format +msgid "non-numeric mode -- %s\n" msgstr "" -#: .././io/file.c:99 -msgid "set the current file" +#: .././io/link.c:35 +#, c-format +msgid "" +"\n" +"link the open file descriptor to the supplied filename\n" +"\n" +"\n" msgstr "" -#: .././io/file.c:108 -msgid "list current open files and memory mappings" +#: .././io/link.c:64 +msgid "filename" msgstr "" -#: .././io/freeze.c:37 -#, c-format -msgid "%s: cannot freeze filesystem at %s: %s\n" +#: .././io/link.c:66 +msgid "link the open file descriptor to the supplied filename" msgstr "" -#: .././io/freeze.c:54 -#, c-format -msgid "%s: cannot unfreeze filesystem mounted at %s: %s\n" +#: .././io/open.c:68 +msgid "socket" msgstr "" -#: .././io/freeze.c:70 -msgid "freeze filesystem of current file" +#: .././io/open.c:70 +msgid "directory" msgstr "" -#: .././io/freeze.c:77 -msgid "unfreeze filesystem of current file" +#: .././io/open.c:72 +msgid "char device" msgstr "" -#: .././io/fsync.c:59 -msgid "calls fsync(2) to flush all in-core file state to disk" +#: .././io/open.c:74 +msgid "block device" msgstr "" -#: .././io/fsync.c:66 -msgid "calls fdatasync(2) to flush the files in-core data to disk" +#: .././io/open.c:76 +msgid "regular file" msgstr "" -#: .././io/getrusage.c:118 -msgid "report process resource usage" +#: .././io/open.c:78 +msgid "symbolic link" msgstr "" -#: .././io/imap.c:53 -#, c-format -msgid "ino %10llu count %2d mask %016llx\n" +#: .././io/open.c:80 +msgid "fifo" msgstr "" -#: .././io/imap.c:71 -msgid "[nentries]" +#: .././io/open.c:95 .././io/open.c:707 +#, c-format +msgid "fd.path = \"%s\"\n" msgstr "" -#: .././io/imap.c:73 -msgid "inode map for filesystem of current file" +#: .././io/open.c:96 +#, c-format +msgid "fd.flags = %s,%s,%s%s%s%s%s\n" msgstr "" -#: .././io/inject.c:109 +#: .././io/open.c:107 #, c-format -msgid "" -"\n" -" inject errors into the filesystem of the currently open file\n" -"\n" -" Example:\n" -" 'inject readagf' - cause errors on allocation group freespace reads\n" -"\n" -" Causes the kernel to generate and react to errors within XFS, provided\n" -" the XFS kernel code has been built with debugging features enabled.\n" -" With no arguments, displays the list of error injection tags.\n" -"\n" +msgid "stat.ino = %lld\n" msgstr "" -#: .././io/inject.c:135 +#: .././io/open.c:108 #, c-format -msgid "no such tag -- %s\n" +msgid "stat.type = %s\n" msgstr "" -#: .././io/inject.c:156 -msgid "[tag ...]" +#: .././io/open.c:109 +#, c-format +msgid "stat.size = %lld\n" msgstr "" -#: .././io/inject.c:157 -msgid "inject errors into a filesystem" +#: .././io/open.c:110 +#, c-format +msgid "stat.blocks = %lld\n" msgstr "" -#: .././io/madvise.c:32 +#: .././io/open.c:112 #, c-format -msgid "" -"\n" -" advise the page cache about access patterns expected for a mapping\n" -"\n" -" Modifies page cache behavior when operating on the current mapping.\n" -" The range arguments are required by some advise commands ([*] below).\n" -" With no arguments, the POSIX_MADV_NORMAL advice is implied.\n" -" -d -- don't need these pages (POSIX_MADV_DONTNEED) [*]\n" -" -r -- expect random page references (POSIX_MADV_RANDOM)\n" -" -s -- expect sequential page references (POSIX_MADV_SEQUENTIAL)\n" -" -w -- will need these pages (POSIX_MADV_WILLNEED) [*]\n" -" Notes:\n" -" NORMAL sets the default readahead setting on the file.\n" -" RANDOM sets the readahead setting on the file to zero.\n" -" SEQUENTIAL sets double the default readahead setting on the file.\n" -" WILLNEED forces the maximum readahead.\n" -"\n" +msgid "stat.atime = %s" msgstr "" -#: .././io/madvise.c:98 .././io/mincore.c:58 +#: .././io/open.c:113 #, c-format -msgid "length argument too large -- %lld\n" +msgid "stat.mtime = %s" msgstr "" -#: .././io/madvise.c:127 -msgid "[-drsw] [off len]" +#: .././io/open.c:114 +#, c-format +msgid "stat.ctime = %s" msgstr "" -#: .././io/madvise.c:128 -msgid "give advice about use of memory" +#: .././io/open.c:123 +#, c-format +msgid "fsxattr.xflags = 0x%x " msgstr "" -#: .././io/mincore.c:92 .././io/mincore.c:102 +#: .././io/open.c:125 #, c-format -msgid "0x%lx %lu pages (%llu : %lu)\n" +msgid "fsxattr.projid = %u\n" msgstr "" -#: .././io/mincore.c:122 -msgid "[off len]" +#: .././io/open.c:126 +#, c-format +msgid "fsxattr.extsize = %u\n" msgstr "" -#: .././io/mincore.c:123 -msgid "find mapping pages that are memory resident" +#: .././io/open.c:127 +#, c-format +msgid "fsxattr.nextents = %u\n" msgstr "" -#: .././io/mmap.c:76 +#: .././io/open.c:128 #, c-format -msgid "offset (%lld) is before start of mapping (%lld)\n" +msgid "fsxattr.naextents = %u\n" msgstr "" -#: .././io/mmap.c:82 +#: .././io/open.c:133 #, c-format -msgid "offset (%lld) is beyond end of mapping (%lld)\n" +msgid "dioattr.mem = 0x%x\n" msgstr "" -#: .././io/mmap.c:87 +#: .././io/open.c:134 #, c-format -msgid "range (%lld:%lld) is beyond mapping (%lld:%ld)\n" +msgid "dioattr.miniosz = %u\n" msgstr "" -#: .././io/mmap.c:93 +#: .././io/open.c:135 #, c-format -msgid "offset address (%p) is not page aligned\n" +msgid "dioattr.maxiosz = %u\n" msgstr "" -#: .././io/mmap.c:133 +#: .././io/open.c:254 #, c-format msgid "" "\n" -" maps a range within the current file into memory\n" +" opens a new file in the requested mode\n" "\n" " Example:\n" -" 'mmap -rw 0 1m' - maps one megabyte from the start of the current file\n" +" 'open -cd /tmp/data' - creates/opens data file read-write for direct IO\n" "\n" -" Memory maps a range of a file for subsequent use by other xfs_io commands.\n" -" With no arguments, mmap shows the current mappings. The current mapping\n" -" can be set by using the single argument form (mapping number or address).\n" -" If two arguments are specified (a range), a new mapping is created and the\n" -" following options are available:\n" -" -r -- map with PROT_READ protection\n" -" -w -- map with PROT_WRITE protection\n" -" -x -- map with PROT_EXEC protection\n" -" If no protection mode is specified, all are used by default.\n" +" Opens a file for subsequent use by all of the other xfs_io commands.\n" +" With no arguments, open uses the stat command to show the current file.\n" +" -a -- open with the O_APPEND flag (append-only mode)\n" +" -d -- open with O_DIRECT (non-buffered IO, note alignment constraints)\n" +" -f -- open with O_CREAT (create the file if it doesn't exist)\n" +" -m -- permissions to use in case a new file is created (default 0600)\n" +" -n -- open with O_NONBLOCK\n" +" -r -- open with O_RDONLY, the default is O_RDWR\n" +" -s -- open with O_SYNC\n" +" -t -- open with O_TRUNC (truncate the file to zero length if it exists)\n" +" -R -- mark the file as a realtime XFS file immediately after opening it\n" +" -T -- open with O_TMPFILE (create a file not visible in the namespace)\n" +" Note1: usually read/write direct IO requests must be blocksize aligned;\n" +" some kernels, however, allow sectorsize alignment for direct IO.\n" +" Note2: the bmap for non-regular files can be obtained provided the file\n" +" was opened correctly (in particular, must be opened read-only).\n" "\n" msgstr "" -#: .././io/mmap.c:167 .././io/mmap.c:174 .././io/init.c:106 +#: .././io/open.c:346 #, c-format -msgid "no mapped regions, try 'help mmap'\n" +msgid "-T and -r options are incompatible\n" msgstr "" -#: .././io/mmap.c:254 +#: .././io/open.c:401 #, c-format msgid "" "\n" -" flushes a range of bytes in the current memory mapping\n" +" displays the project identifier associated with the current path\n" "\n" -" Writes all modified copies of pages over the specified range (or entire\n" -" mapping if no range specified) to their backing storage locations. Also,\n" -" optionally invalidates so that subsequent references to the pages will be\n" -" obtained from their backing storage locations (instead of cached copies).\n" -" -a -- perform asynchronous writes (MS_ASYNC)\n" -" -i -- invalidate mapped pages (MS_INVALIDATE)\n" -" -s -- perform synchronous writes (MS_SYNC)\n" +" Options:\n" +" -R -- recursively descend (useful when current path is a directory)\n" +" -D -- recursively descend, but only list projects on directories\n" "\n" msgstr "" -#: .././io/mmap.c:330 +#: .././io/open.c:467 +#, c-format +msgid "projid = %u\n" +msgstr "" + +#: .././io/open.c:475 #, c-format msgid "" "\n" -" reads a range of bytes in the current memory mapping\n" -"\n" -" Example:\n" -" 'mread -v 512 20' - dumps 20 bytes read from 512 bytes into the mapping\n" +" modifies the project identifier associated with the current path\n" "\n" -" Accesses a range of the current memory mapping, optionally dumping it to\n" -" the standard output stream (with -v option) for subsequent inspection.\n" -" -f -- verbose mode, dump bytes with offsets relative to start of file.\n" -" -r -- reverse order; start accessing from the end of range, moving " -"backward\n" -" -v -- verbose mode, dump bytes with offsets relative to start of mapping.\n" -" The accesses are performed sequentially from the start offset by default.\n" -" Notes:\n" -" References to whole pages following the end of the backing file results\n" -" in delivery of the SIGBUS signal. SIGBUS signals may also be delivered\n" -" on various filesystem conditions, including quota exceeded errors, and\n" -" for physical device errors (such as unreadable disk blocks). No attempt\n" -" has been made to catch signals at this stage...\n" +" -R -- recursively descend (useful when current path is a directory)\n" +" -D -- recursively descend, only modifying projects on directories\n" "\n" msgstr "" -#: .././io/mmap.c:494 +#: .././io/open.c:534 +#, c-format +msgid "invalid project ID -- %s\n" +msgstr "" + +#: .././io/open.c:550 #, c-format msgid "" "\n" -" dirties a range of bytes in the current memory mapping\n" -"\n" -" Example:\n" -" 'mwrite 512 20 - writes 20 bytes at 512 bytes into the current mapping.\n" +" report or modify preferred extent size (in bytes) for the current path\n" "\n" -" Stores a byte into memory for a range within a mapping.\n" -" The default stored value is 'X', repeated to fill the range specified.\n" -" -S -- use an alternate seed character\n" -" -r -- reverse order; start storing from the end of range, moving backward\n" -" The stores are performed sequentially from the start offset by default.\n" +" -R -- recursively descend (useful when current path is a directory)\n" +" -D -- recursively descend, only modifying extsize on directories\n" "\n" msgstr "" -#: .././io/mmap.c:586 -msgid "[N] | [-rwx] [off len]" +#: .././io/open.c:593 +#, c-format +msgid "invalid target file type - file %s\n" msgstr "" -#: .././io/mmap.c:588 -msgid "mmap a range in the current file, show mappings" +#: .././io/open.c:679 +#, c-format +msgid "non-numeric extsize argument -- %s\n" msgstr "" -#: .././io/mmap.c:597 -msgid "[-r] [off len]" +#: .././io/open.c:711 +#, c-format +msgid "statfs.f_bsize = %lld\n" msgstr "" -#: .././io/mmap.c:599 -msgid "reads data from a region in the current memory mapping" +#: .././io/open.c:712 +#, c-format +msgid "statfs.f_blocks = %lld\n" msgstr "" -#: .././io/mmap.c:608 -msgid "[-ais] [off len]" +#: .././io/open.c:714 +#, c-format +msgid "statfs.f_frsize = %lld\n" msgstr "" -#: .././io/mmap.c:609 -msgid "flush a region in the current memory mapping" +#: .././io/open.c:716 +#, c-format +msgid "statfs.f_bavail = %lld\n" msgstr "" -#: .././io/mmap.c:618 -msgid "unmaps the current memory mapping" +#: .././io/open.c:718 +#, c-format +msgid "statfs.f_files = %lld\n" msgstr "" -#: .././io/mmap.c:626 -msgid "[-r] [-S seed] [off len]" +#: .././io/open.c:719 +#, c-format +msgid "statfs.f_ffree = %lld\n" msgstr "" -#: .././io/mmap.c:628 -msgid "writes data into a region in the current memory mapping" +#: .././io/open.c:726 +#, c-format +msgid "geom.bsize = %u\n" msgstr "" -#: .././io/prealloc.c:216 .././io/prealloc.c:224 .././io/prealloc.c:232 -#: .././io/prealloc.c:240 .././io/prealloc.c:250 .././io/prealloc.c:276 -msgid "off len" +#: .././io/open.c:727 +#, c-format +msgid "geom.agcount = %u\n" msgstr "" -#: .././io/prealloc.c:217 -msgid "allocates zeroed space for part of a file" +#: .././io/open.c:728 +#, c-format +msgid "geom.agblocks = %u\n" msgstr "" -#: .././io/prealloc.c:225 -msgid "frees space associated with part of a file" +#: .././io/open.c:729 +#, c-format +msgid "geom.datablocks = %llu\n" msgstr "" -#: .././io/prealloc.c:234 -msgid "reserves space associated with part of a file" +#: .././io/open.c:731 +#, c-format +msgid "geom.rtblocks = %llu\n" msgstr "" -#: .././io/prealloc.c:243 -msgid "frees reserved space associated with part of a file" +#: .././io/open.c:733 +#, c-format +msgid "geom.rtextents = %llu\n" msgstr "" -#: .././io/prealloc.c:252 -msgid "Converts the given range of a file to allocated zeros" +#: .././io/open.c:735 +#, c-format +msgid "geom.rtextsize = %u\n" msgstr "" -#: .././io/prealloc.c:266 -msgid "[-k] [-p] off len" +#: .././io/open.c:736 +#, c-format +msgid "geom.sunit = %u\n" msgstr "" -#: .././io/prealloc.c:268 -msgid "allocates space associated with part of a file via fallocate" +#: .././io/open.c:737 +#, c-format +msgid "geom.swidth = %u\n" msgstr "" -#: .././io/prealloc.c:278 -msgid "de-allocates space assocated with part of a file via fallocate" +#: .././io/open.c:742 +#, c-format +msgid "counts.freedata = %llu\n" msgstr "" -#: .././io/resblks.c:39 +#: .././io/open.c:744 #, c-format -msgid "non-numeric argument -- %s\n" +msgid "counts.freertx = %llu\n" msgstr "" -#: .././io/resblks.c:51 +#: .././io/open.c:746 #, c-format -msgid "reserved blocks = %llu\n" +msgid "counts.freeino = %llu\n" msgstr "" -#: .././io/resblks.c:53 +#: .././io/open.c:748 #, c-format -msgid "available reserved blocks = %llu\n" +msgid "counts.allocino = %llu\n" msgstr "" -#: .././io/resblks.c:66 -msgid "[blocks]" +#: .././io/open.c:763 +msgid "[-acdrstxT] [path]" msgstr "" -#: .././io/resblks.c:68 -msgid "get and/or set count of reserved filesystem blocks" +#: .././io/open.c:764 +msgid "open the file specified by path" msgstr "" -#: .././io/sendfile.c:32 -#, c-format -msgid "" -"\n" -" transfer a range of bytes from the given offset between files\n" -"\n" -" Example:\n" -" 'send -f 2 512 20' - writes 20 bytes at 512 bytes into the open file\n" -"\n" -" Copies data between one file descriptor and another. Because this copying\n" -" is done within the kernel, sendfile does not need to transfer data to and\n" -" from user space.\n" -" -f -- specifies an input file from which to source data to write\n" -" -i -- specifies an input file name from which to source data to write.\n" -" An offset and length in the source file can be optionally specified.\n" -"\n" +#: .././io/open.c:772 +msgid "[-v]" msgstr "" -#: .././io/sendfile.c:161 -#, c-format -msgid "sent %lld/%lld bytes from offset %lld\n" +#: .././io/open.c:773 +msgid "statistics on the currently open file" msgstr "" -#: .././io/sendfile.c:186 -msgid "-i infile | -f N [off len]" +#: .././io/open.c:781 +msgid "close the current open file" msgstr "" -#: .././io/sendfile.c:188 -msgid "Transfer data directly between file descriptors" +#: .././io/open.c:787 +msgid "statistics on the filesystem of the currently open file" msgstr "" -#: .././io/shutdown.c:59 -msgid "[-f]" +#: .././io/open.c:791 +msgid "[-D | -R] projid" msgstr "" -#: .././io/shutdown.c:61 -msgid "shuts down the filesystem where the current file resides" +#: .././io/open.c:796 +msgid "change project identifier on the currently open file" msgstr "" -#: .././io/truncate.c:38 -#, c-format -msgid "non-numeric truncate argument -- %s\n" +#: .././io/open.c:801 +msgid "[-D | -R]" msgstr "" -#: .././io/truncate.c:58 -msgid "off" +#: .././io/open.c:806 +msgid "list project identifier set on the currently open file" msgstr "" -#: .././io/truncate.c:60 -msgid "truncates the current file at the given offset" +#: .././io/open.c:811 +msgid "[-D | -R] [extsize]" +msgstr "" + +#: .././io/open.c:816 +msgid "get/set preferred extent size (in bytes) for the open file" msgstr "" #: .././io/parent.c:49 @@ -4678,72 +4712,72 @@ msgid "unable to allocate buffers: %s\n" msgstr "" -#: .././io/parent.c:268 +#: .././io/parent.c:270 #, c-format msgid "num errors: %d\n" msgstr "" -#: .././io/parent.c:270 +#: .././io/parent.c:272 #, c-format msgid "succeeded checking %llu inodes\n" msgstr "" -#: .././io/parent.c:281 +#: .././io/parent.c:283 #, c-format msgid "p_ino = %llu\n" msgstr "" -#: .././io/parent.c:282 +#: .././io/parent.c:284 #, c-format msgid "p_gen = %u\n" msgstr "" -#: .././io/parent.c:283 +#: .././io/parent.c:285 #, c-format msgid "p_reclen = %u\n" msgstr "" -#: .././io/parent.c:285 +#: .././io/parent.c:287 #, c-format msgid "p_name = \"%s%s\"\n" msgstr "" -#: .././io/parent.c:287 +#: .././io/parent.c:289 #, c-format msgid "p_name = \"%s\"\n" msgstr "" -#: .././io/parent.c:309 +#: .././io/parent.c:311 #, c-format msgid "%s: failed path_to_fshandle \"%s\": %s\n" msgstr "" -#: .././io/parent.c:316 +#: .././io/parent.c:318 #, c-format msgid "%s: path_to_handle failed for \"%s\"\n" msgstr "" -#: .././io/parent.c:323 +#: .././io/parent.c:325 #, c-format msgid "%s: unable to allocate parent buffer: %s\n" msgstr "" -#: .././io/parent.c:344 +#: .././io/parent.c:346 #, c-format msgid "%s: %s call failed for \"%s\": %s\n" msgstr "" -#: .././io/parent.c:353 +#: .././io/parent.c:355 #, c-format msgid "%s: inode-path is missing\n" msgstr "" -#: .././io/parent.c:384 +#: .././io/parent.c:386 #, c-format msgid "file argument, \"%s\", is not in a mounted XFS filesystem\n" msgstr "" -#: .././io/parent.c:424 +#: .././io/parent.c:426 #, c-format msgid "" "\n" @@ -4755,82 +4789,201 @@ "\n" msgstr "" -#: .././io/parent.c:440 +#: .././io/parent.c:442 msgid "[-cpv]" msgstr "" -#: .././io/parent.c:442 +#: .././io/parent.c:444 msgid "print or check parent inodes" msgstr "" -#: .././io/fiemap.c:32 +#: .././io/pread.c:33 #, c-format msgid "" "\n" -" prints the block mapping for a file's data or attribute forks\n" +" reads a range of bytes in a specified block size from the given offset\n" +"\n" " Example:\n" -" 'fiemap -v' - tabular format verbose map\n" +" 'pread -v 512 20' - dumps 20 bytes read from 512 bytes into the file\n" "\n" -" fiemap prints the map of disk blocks used by the current file.\n" -" The map lists each extent used by the file, as well as regions in the\n" -" file that do not have any corresponding blocks (holes).\n" -" By default, each line of the listing takes the following form:\n" -" extent: [startoffset..endoffset]: startblock..endblock\n" -" Holes are marked by replacing the startblock..endblock with 'hole'.\n" -" All the file offsets and disk blocks are in units of 512-byte blocks.\n" -" -a -- prints the attribute fork map instead of the data fork.\n" -" -l -- also displays the length of each extent in 512-byte blocks.\n" -" -n -- query n extents.\n" -" -v -- Verbose information\n" +" Reads a segment of the currently open file, optionally dumping it to the\n" +" standard output stream (with -v option) for subsequent inspection.\n" +" The reads are performed in sequential blocks starting at offset, with the\n" +" blocksize tunable using the -b option (default blocksize is 4096 bytes),\n" +" unless a different pattern is requested.\n" +" -B -- read backwards through the range from offset (backwards N bytes)\n" +" -F -- read forwards through the range of bytes from offset (default)\n" +" -v -- be verbose, dump out buffers (used when reading forwards)\n" +" -R -- read at random offsets in the range of bytes\n" +" -Z N -- zeed the random number generator (used when reading randomly)\n" +" (heh, zorry, the -s/-S arguments were already in use in pwrite)\n" +" -V N -- use vectored IO with N iovecs of blocksize each (preadv)\n" +"\n" +" When in \"random\" mode, the number of read operations will equal the\n" +" number required to do a complete forward/backward scan of the range.\n" +" Note that the offset within the range is chosen at random each time\n" +" (an offset may be read more than once when operating in this mode).\n" "\n" msgstr "" -#: .././io/fiemap.c:139 .././io/fiemap.c:153 .././io/fiemap.c:323 +#: .././io/pread.c:398 .././io/pwrite.c:269 +#, c-format +msgid "non-numeric bsize -- %s\n" +msgstr "" + +#: .././io/pread.c:428 .././io/pwrite.c:316 #, c-format -msgid " %llu blocks\n" +msgid "non-numeric vector count == %s\n" +msgstr "" + +#: .././io/pread.c:497 +#, c-format +msgid "read %lld/%lld bytes at offset %lld\n" +msgstr "" + +#: .././io/pread.c:518 +msgid "[-b bs] [-v] [-i N] [-FBR [-Z N]] off len" +msgstr "" + +#: .././io/pread.c:519 +msgid "reads a number of bytes at a specified offset" +msgstr "" + +#: .././io/prealloc.c:273 .././io/prealloc.c:281 .././io/prealloc.c:289 +#: .././io/prealloc.c:297 .././io/prealloc.c:307 .././io/prealloc.c:333 +#: .././io/prealloc.c:343 +msgid "off len" +msgstr "" + +#: .././io/prealloc.c:274 +msgid "allocates zeroed space for part of a file" +msgstr "" + +#: .././io/prealloc.c:282 +msgid "frees space associated with part of a file" +msgstr "" + +#: .././io/prealloc.c:291 +msgid "reserves space associated with part of a file" +msgstr "" + +#: .././io/prealloc.c:300 +msgid "frees reserved space associated with part of a file" +msgstr "" + +#: .././io/prealloc.c:309 +msgid "Converts the given range of a file to allocated zeros" +msgstr "" + +#: .././io/prealloc.c:323 +msgid "[-c] [-k] [-p] off len" +msgstr "" + +#: .././io/prealloc.c:325 +msgid "allocates space associated with part of a file via fallocate" +msgstr "" + +#: .././io/prealloc.c:335 +msgid "de-allocates space assocated with part of a file via fallocate" +msgstr "" + +#: .././io/prealloc.c:345 +msgid "de-allocates space and eliminates the hole by shifting extents" +msgstr "" + +#: .././io/prealloc.c:353 +msgid "[-k] off len" +msgstr "" + +#: .././io/prealloc.c:355 +msgid "zeroes space and eliminates holes by preallocating" +msgstr "" + +#: .././io/pwrite.c:32 +#, c-format +msgid "" +"\n" +" writes a range of bytes (in block size increments) from the given offset\n" +"\n" +" Example:\n" +" 'pwrite 512 20' - writes 20 bytes at 512 bytes into the open file\n" +"\n" +" Writes into a segment of the currently open file, using either a buffer\n" +" filled with a set pattern (0xcdcdcdcd) or data read from an input file.\n" +" The writes are performed in sequential blocks starting at offset, with the\n" +" blocksize tunable using the -b option (default blocksize is 4096 bytes),\n" +" unless a different write pattern is requested.\n" +" -S -- use an alternate seed number for filling the write buffer\n" +" -i -- input file, source of data to write (used when writing forward)\n" +" -d -- open the input file for direct IO\n" +" -s -- skip a number of bytes at the start of the input file\n" +" -w -- call fdatasync(2) at the end (included in timing results)\n" +" -W -- call fsync(2) at the end (included in timing results)\n" +" -B -- write backwards through the range from offset (backwards N bytes)\n" +" -F -- write forwards through the range of bytes from offset (default)\n" +" -R -- write at random offsets in the specified range of bytes\n" +" -Z N -- zeed the random number generator (used when writing randomly)\n" +" (heh, zorry, the -s/-S arguments were already in use in pwrite)\n" +" -V N -- use vectored IO with N iovecs of blocksize each (pwritev)\n" +"\n" +msgstr "" + +#: .././io/pwrite.c:296 +#, c-format +msgid "non-numeric skip -- %s\n" +msgstr "" + +#: .././io/pwrite.c:394 +#, c-format +msgid "wrote %lld/%lld bytes at offset %lld\n" +msgstr "" + +#: .././io/pwrite.c:419 +msgid "" +"[-i infile [-d] [-s skip]] [-b bs] [-S seed] [-wW] [-FBR [-Z N]] [-V N] off " +"len" +msgstr "" + +#: .././io/pwrite.c:421 +msgid "writes a number of bytes at a specified offset" +msgstr "" + +#: .././io/readdir.c:182 +#, c-format +msgid "read %llu bytes from offset %lld\n" msgstr "" -#: .././io/fiemap.c:247 -msgid "FLAGS" +#: .././io/readdir.c:183 +#, c-format +msgid "%s, %d ops, %s (%s/sec and %.4f ops/sec)\n" msgstr "" -#: .././io/fiemap.c:343 -msgid "[-alv] [-n nx]" +#: .././io/readdir.c:196 +msgid "[-v][-o offset][-l length]" msgstr "" -#: .././io/fiemap.c:344 -msgid "print block mapping for a file" +#: .././io/readdir.c:197 +msgid "read directory entries" msgstr "" -#: .././io/init.c:35 +#: .././libdisk/dm.c:57 #, c-format -msgid "Usage: %s [-adfmrRstx] [-p prog] [-c cmd]... file\n" +msgid "Warning - device mapper device, but no dmsetup(8) found\n" msgstr "" -#: .././io/init.c:112 +#: .././libdisk/dm.c:73 .././libdisk/lvm.c:70 #, c-format -msgid "foreign file active, %s command is for XFS filesystems only\n" +msgid "Could not open pipe\n" msgstr "" -#: .././io/sync_file_range.c:31 +#: .././libdisk/dm.c:88 .././libdisk/lvm.c:85 #, c-format -msgid "" -"\n" -" Trigger specific writeback commands on a range of the current file\n" -"\n" -" With no options, the SYNC_FILE_RANGE_WRITE is implied.\n" -" -a -- wait for IO to finish after writing (SYNC_FILE_RANGE_WAIT_AFTER).\n" -" -b -- wait for IO to finish before writing (SYNC_FILE_RANGE_WAIT_BEFORE).\n" -" -w -- write dirty data in range (SYNC_FILE_RANGE_WRITE).\n" -"\n" -msgstr "" - -#: .././io/sync_file_range.c:102 -msgid "[-abw] off len" +msgid "Failed to execute %s\n" msgstr "" -#: .././io/sync_file_range.c:103 -msgid "Control writeback on a range of a file" +#: .././libdisk/dm.c:92 +#, c-format +msgid "Failed forking dmsetup process\n" msgstr "" #: .././libdisk/drivers.c:35 @@ -4843,16 +4996,6 @@ msgid "Warning - LVM device, but no lvdisplay(8) found\n" msgstr "" -#: .././libdisk/lvm.c:70 .././libdisk/dm.c:73 -#, c-format -msgid "Could not open pipe\n" -msgstr "" - -#: .././libdisk/lvm.c:85 .././libdisk/dm.c:88 -#, c-format -msgid "Failed to execute %s\n" -msgstr "" - #: .././libdisk/lvm.c:89 #, c-format msgid "Failed forking lvdisplay process\n" @@ -4873,16 +5016,6 @@ msgid "Error getting MD array info from %s\n" msgstr "" -#: .././libdisk/dm.c:57 -#, c-format -msgid "Warning - device mapper device, but no dmsetup(8) found\n" -msgstr "" - -#: .././libdisk/dm.c:92 -#, c-format -msgid "Failed forking dmsetup process\n" -msgstr "" - #: .././libxcmd/command.c:85 #, c-format msgid "bad argument count %d to %s, expected at least %d arguments\n" @@ -4912,321 +5045,351 @@ msgid "exit the program" msgstr "" -#: .././libxcmd/paths.c:263 +#: .././libxcmd/paths.c:264 #, c-format msgid "%s: unable to extract mount options for \"%s\"\n" msgstr "" -#: .././libxcmd/paths.c:324 +#: .././libxcmd/paths.c:344 #, c-format msgid "%s: getmntinfo() failed: %s\n" msgstr "" -#: .././libxcmd/paths.c:385 +#: .././libxcmd/paths.c:413 #, c-format msgid "%s: cannot setup path for mount %s: %s\n" msgstr "" -#: .././libxcmd/paths.c:407 +#: .././libxcmd/paths.c:435 #, c-format msgid "%s: cannot find mount point for path `%s': %s\n" msgstr "" -#: .././libxcmd/paths.c:435 +#: .././libxcmd/paths.c:463 #, c-format msgid "%s: cannot setup path for project %s: %s\n" msgstr "" -#: .././libxcmd/paths.c:476 +#: .././libxcmd/paths.c:504 #, c-format msgid "%s: cannot initialise path table: %s\n" msgstr "" -#: .././libxcmd/paths.c:496 +#: .././libxcmd/paths.c:524 #, c-format msgid "%s: cannot setup path for project dir %s: %s\n" msgstr "" -#: .././libxfs/darwin.c:41 -#, c-format -msgid "%s: error opening the device special file \"%s\": %s\n" -msgstr "" - -#: .././libxfs/darwin.c:48 +#: .././libxfs/init.c:79 .././libxfs/init.c:178 #, c-format -msgid "%s: can't tell if \"%s\" is writable: %s\n" +msgid "%s: %s: device %lld is not open\n" msgstr "" -#: .././libxfs/darwin.c:76 .././libxfs/irix.c:58 .././libxfs/linux.c:138 -#: .././libxfs/freebsd.c:116 +#: .././libxfs/init.c:115 #, c-format -msgid "%s: cannot stat the device file \"%s\": %s\n" +msgid "%s: cannot stat %s: %s\n" msgstr "" -#: .././libxfs/darwin.c:86 +#: .././libxfs/init.c:140 #, c-format -msgid "%s: can't determine device size: %s\n" +msgid "%s: device %lld is already open\n" msgstr "" -#: .././libxfs/darwin.c:139 .././libxfs/irix.c:106 .././libxfs/linux.c:216 -#: .././libxfs/freebsd.c:196 +#: .././libxfs/init.c:153 #, c-format -msgid "%s: can't determine memory size\n" +msgid "%s: %s: too many open devices\n" msgstr "" -#: .././libxfs/kmem.c:15 +#: .././libxfs/init.c:196 #, c-format -msgid "%s: zone init failed (%s, %d bytes): %s\n" +msgid "%s: can't find a character device matching %s\n" msgstr "" -#: .././libxfs/kmem.c:32 +#: .././libxfs/init.c:202 #, c-format -msgid "%s: zone alloc failed (%s, %d bytes): %s\n" +msgid "%s: can't find a block device matching %s\n" msgstr "" -#: .././libxfs/kmem.c:56 +#: .././libxfs/init.c:319 #, c-format -msgid "%s: malloc failed (%d bytes): %s\n" +msgid "%s: can't get size for data subvolume\n" msgstr "" -#: .././libxfs/kmem.c:77 +#: .././libxfs/init.c:324 #, c-format -msgid "%s: realloc failed (%d bytes): %s\n" +msgid "%s: can't get size for log subvolume\n" msgstr "" -#: .././libxfs/linux.c:67 .././libxfs/freebsd.c:60 +#: .././libxfs/init.c:329 #, c-format -msgid "%s: %s contains a mounted filesystem\n" +msgid "%s: can't get size for realtime subvolume\n" msgstr "" -#: .././libxfs/linux.c:85 .././libxfs/freebsd.c:75 +#: .././libxfs/init.c:423 #, c-format -msgid "%s: %s contains a possibly writable, mounted filesystem\n" +msgid "%s: filesystem has a realtime subvolume\n" msgstr "" -#: .././libxfs/linux.c:99 .././libxfs/freebsd.c:89 +#: .././libxfs/init.c:445 #, c-format -msgid "%s: %s contains a mounted and writable filesystem\n" +msgid "%s: realtime init - %llu != %llu\n" msgstr "" -#: .././libxfs/linux.c:114 +#: .././libxfs/init.c:453 #, c-format -msgid "%s: %s - cannot set blocksize %d on block device %s: %s\n" +msgid "%s: realtime size check failed\n" msgstr "" -#: .././libxfs/linux.c:161 +#: .././libxfs/init.c:573 #, c-format -msgid "%s: can't determine device size\n" +msgid "%s: buftarg init failed\n" msgstr "" -#: .././libxfs/linux.c:169 +#: .././libxfs/init.c:594 #, c-format -msgid "%s: warning - cannot get sector size from block device %s: %s\n" +msgid "%s: bad buftarg reinit, ddev\n" msgstr "" -#: .././libxfs/init.c:80 .././libxfs/init.c:179 +#: .././libxfs/init.c:601 #, c-format -msgid "%s: %s: device %lld is not open\n" +msgid "%s: bad buftarg reinit, ldev mismatch\n" msgstr "" -#: .././libxfs/init.c:116 +#: .././libxfs/init.c:608 #, c-format -msgid "%s: cannot stat %s: %s\n" +msgid "%s: bad buftarg reinit, logdev\n" msgstr "" -#: .././libxfs/init.c:141 +#: .././libxfs/init.c:615 #, c-format -msgid "%s: device %lld is already open\n" +msgid "%s: bad buftarg reinit, rtdev\n" msgstr "" -#: .././libxfs/init.c:154 +#: .././libxfs/init.c:707 #, c-format -msgid "%s: %s: too many open devices\n" +msgid "%s: size check failed\n" msgstr "" -#: .././libxfs/init.c:197 +#: .././libxfs/init.c:716 #, c-format -msgid "%s: can't find a character device matching %s\n" +msgid "%s: V1 directories unsupported. Please try an older xfsprogs.\n" msgstr "" -#: .././libxfs/init.c:203 +#: .././libxfs/init.c:737 #, c-format -msgid "%s: can't find a block device matching %s\n" +msgid "%s: data size check failed\n" msgstr "" -#: .././libxfs/init.c:320 +#: .././libxfs/init.c:751 #, c-format -msgid "%s: can't get size for data subvolume\n" +msgid "%s: log size checks failed\n" msgstr "" -#: .././libxfs/init.c:325 +#: .././libxfs/init.c:762 #, c-format -msgid "%s: can't get size for log subvolume\n" +msgid "%s: realtime device init failed\n" msgstr "" -#: .././libxfs/init.c:330 +#: .././libxfs/init.c:769 #, c-format -msgid "%s: can't get size for realtime subvolume\n" +msgid "%s: perag init failed\n" msgstr "" -#: .././libxfs/init.c:430 +#: .././libxfs/darwin.c:41 #, c-format -msgid "%s: cannot read realtime bitmap inode (%d)\n" +msgid "%s: error opening the device special file \"%s\": %s\n" msgstr "" -#: .././libxfs/init.c:440 +#: .././libxfs/darwin.c:48 #, c-format -msgid "%s: cannot read realtime summary inode (%d)\n" +msgid "%s: can't tell if \"%s\" is writable: %s\n" msgstr "" -#: .././libxfs/init.c:464 +#: .././libxfs/darwin.c:76 .././libxfs/freebsd.c:116 .././libxfs/linux.c:138 +#: .././libxfs/irix.c:58 #, c-format -msgid "%s: filesystem has a realtime subvolume\n" +msgid "%s: cannot stat the device file \"%s\": %s\n" msgstr "" -#: .././libxfs/init.c:486 +#: .././libxfs/darwin.c:86 #, c-format -msgid "%s: realtime init - %llu != %llu\n" +msgid "%s: can't determine device size: %s\n" msgstr "" -#: .././libxfs/init.c:494 +#: .././libxfs/darwin.c:139 .././libxfs/freebsd.c:196 .././libxfs/linux.c:226 +#: .././libxfs/irix.c:106 #, c-format -msgid "%s: realtime size check failed\n" +msgid "%s: can't determine memory size\n" msgstr "" -#: .././libxfs/init.c:699 +#: .././libxfs/freebsd.c:49 #, c-format -msgid "%s: size check failed\n" +msgid "%s: %s possibly contains a mounted filesystem\n" msgstr "" -#: .././libxfs/init.c:708 +#: .././libxfs/freebsd.c:60 .././libxfs/linux.c:67 #, c-format -msgid "%s: WARNING - filesystem uses v1 dirs,limited functionality provided.\n" +msgid "%s: %s contains a mounted filesystem\n" msgstr "" -#: .././libxfs/init.c:728 +#: .././libxfs/freebsd.c:75 .././libxfs/linux.c:85 #, c-format -msgid "%s: data size check failed\n" +msgid "%s: %s contains a possibly writable, mounted filesystem\n" msgstr "" -#: .././libxfs/init.c:741 +#: .././libxfs/freebsd.c:89 .././libxfs/linux.c:99 #, c-format -msgid "%s: log size checks failed\n" +msgid "%s: %s contains a mounted and writable filesystem\n" msgstr "" -#: .././libxfs/init.c:752 +#: .././libxfs/freebsd.c:129 #, c-format -msgid "%s: realtime device init failed\n" +msgid "%s: Not a device or file: \"%s\"\n" msgstr "" -#: .././libxfs/init.c:759 +#: .././libxfs/freebsd.c:135 #, c-format -msgid "%s: perag init failed\n" +msgid "%s: DIOCGMEDIASIZE failed on \"%s\": %s\n" msgstr "" -#: .././libxfs/init.c:771 +#: .././libxfs/freebsd.c:141 #, c-format -msgid "%s: cannot read root inode (%d)\n" +msgid "%s: DIOCGSECTORSIZE failed on \"%s\": %s\n" msgstr "" -#: .././libxfs/init.c:791 +#: .././libxfs/linux.c:114 #, c-format -msgid "%s: cannot init perag data (%d)\n" +msgid "%s: %s - cannot set blocksize %d on block device %s: %s\n" msgstr "" -#: .././libxfs/trans.c:33 +#: .././libxfs/linux.c:171 #, c-format -msgid "%s: xact calloc failed (%d bytes): %s\n" +msgid "%s: can't determine device size\n" msgstr "" -#: .././libxfs/trans.c:602 +#: .././libxfs/linux.c:179 #, c-format -msgid "%s: warning - itobp failed (%d)\n" +msgid "%s: warning - cannot get sector size from block device %s: %s\n" msgstr "" -#: .././libxfs/trans.c:610 +#: .././libxfs/kmem.c:15 #, c-format -msgid "%s: warning - iflush_int failed (%d)\n" +msgid "%s: zone init failed (%s, %d bytes): %s\n" msgstr "" -#: .././libxfs/trans.c:682 .././libxfs/trans.c:741 +#: .././libxfs/kmem.c:32 #, c-format -msgid "%s: unrecognised log item type\n" +msgid "%s: zone alloc failed (%s, %d bytes): %s\n" msgstr "" -#: .././libxfs/util.c:707 +#: .././libxfs/kmem.c:56 #, c-format -msgid "%s: cannot reserve space: %s\n" +msgid "%s: malloc failed (%d bytes): %s\n" msgstr "" -#: .././libxfs/freebsd.c:49 +#: .././libxfs/kmem.c:77 #, c-format -msgid "%s: %s possibly contains a mounted filesystem\n" +msgid "%s: realloc failed (%d bytes): %s\n" msgstr "" -#: .././libxfs/freebsd.c:129 +#: .././libxfs/rdwr.c:68 #, c-format -msgid "%s: Not a device or file: \"%s\"\n" +msgid "%s: %s can't memalign %d bytes: %s\n" msgstr "" -#: .././libxfs/freebsd.c:135 +#: .././libxfs/rdwr.c:78 #, c-format -msgid "%s: DIOCGMEDIASIZE failed on \"%s\": %s\n" +msgid "%s: %s seek to offset %llu failed: %s\n" msgstr "" -#: .././libxfs/freebsd.c:141 +#: .././libxfs/rdwr.c:88 #, c-format -msgid "%s: DIOCGSECTORSIZE failed on \"%s\": %s\n" +msgid "%s: %s write failed: %s\n" msgstr "" -#: .././libxfs/rdwr.c:40 +#: .././libxfs/rdwr.c:92 #, c-format -msgid "%s: %s can't memalign %d bytes: %s\n" +msgid "%s: %s not progressing?\n" msgstr "" -#: .././libxfs/rdwr.c:50 +#: .././libxfs/rdwr.c:409 #, c-format -msgid "%s: %s seek to offset %llu failed: %s\n" +msgid "%s: %s can't memalign %u bytes: %s\n" msgstr "" -#: .././libxfs/rdwr.c:60 +#: .././libxfs/rdwr.c:441 #, c-format -msgid "%s: %s write failed: %s\n" +msgid "%s: %s can't malloc %u bytes: %s\n" msgstr "" -#: .././libxfs/rdwr.c:64 +#: .././libxfs/rdwr.c:522 #, c-format -msgid "%s: %s not progressing?\n" +msgid "%s: %s invalid map %p or nmaps %d\n" msgstr "" -#: .././libxfs/rdwr.c:336 +#: .././libxfs/rdwr.c:529 #, c-format -msgid "%s: %s can't memalign %u bytes: %s\n" +msgid "%s: %s map blkno 0x%llx doesn't match key 0x%llx\n" msgstr "" -#: .././libxfs/rdwr.c:425 +#: .././libxfs/rdwr.c:574 #, c-format msgid "Warning: recursive buffer locking at block % detected\n" msgstr "" -#: .././libxfs/rdwr.c:519 +#: .././libxfs/rdwr.c:711 #, c-format msgid "%s: read failed: %s\n" msgstr "" -#: .././libxfs/rdwr.c:525 +#: .././libxfs/rdwr.c:717 #, c-format msgid "%s: error - read only %d of %d bytes\n" msgstr "" -#: .././libxfs/rdwr.c:568 +#: .././libxfs/rdwr.c:879 #, c-format msgid "%s: pwrite64 failed: %s\n" msgstr "" -#: .././libxfs/rdwr.c:574 +#: .././libxfs/rdwr.c:885 +#, c-format +msgid "%s: error - pwrite64 only %d of %d bytes\n" +msgstr "" + +#: .././libxfs/rdwr.c:921 +#, c-format +msgid "%s: write verifer failed on bno 0x%llx/0x%x\n" +msgstr "" + +#: .././libxfs/trans.c:56 +#, c-format +msgid "%s: lidp calloc failed (%d bytes): %s\n" +msgstr "" + +#: .././libxfs/trans.c:151 +#, c-format +msgid "%s: xact calloc failed (%d bytes): %s\n" +msgstr "" + +#: .././libxfs/trans.c:676 +#, c-format +msgid "%s: warning - imap_to_bp failed (%d)\n" +msgstr "" + +#: .././libxfs/trans.c:684 +#, c-format +msgid "%s: warning - iflush_int failed (%d)\n" +msgstr "" + +#: .././libxfs/trans.c:744 .././libxfs/trans.c:799 #, c-format -msgid "%s: error - wrote only %d of %d bytes\n" +msgid "%s: unrecognised log item type\n" +msgstr "" + +#: .././libxfs/util.c:691 +#, c-format +msgid "%s: cannot reserve space: %s\n" msgstr "" #: .././libxlog/util.c:37 @@ -5293,6 +5456,39 @@ msgid "[%05lld - %05lld] Cycle 0x%08x New Cycle 0x%08x\n" msgstr "" +#: .././logprint/log_print_trans.c:25 +#, c-format +msgid "TRANS: tid:0x%x type:%s #items:%d trans:0x%x q:0x%lx\n" +msgstr "" + +#: .././logprint/log_print_trans.c:51 +#, c-format +msgid "%s: failed to find head and tail, error: %d\n" +msgstr "" + +#: .././logprint/log_print_trans.c:56 +#, c-format +msgid " log tail: %lld head: %lld state: %s\n" +msgstr "" + +#: .././logprint/log_print_trans.c:62 +#, c-format +msgid " override tail: %d\n" +msgstr "" + +#: .././logprint/log_print_trans.c:82 +#, c-format +msgid "" +"Superblock has unknown incompatible log features (0x%x) enabled.\n" +"Output may be incomplete or inaccurate. It is recommended that you\n" +"upgrade your xfsprogs installation to match the filesystem features.\n" +msgstr "" + +#: .././logprint/log_print_trans.c:90 +#, c-format +msgid "%s: failed in xfs_do_recovery_pass, error: %d\n" +msgstr "" + #: .././logprint/logprint.c:42 #, c-format msgid "" @@ -5302,6 +5498,7 @@ " -c\t try to continue if error found in log\n" " -C copy the log from the filesystem to filename\n" " -d\t dump the log in log-record format\n" +" -e\t exit when an error is found in the log\n" " -f\t specified device is actually a file\n" " -l filename of external log\n" " -n\t don't try and interpret log data\n" @@ -5316,806 +5513,806 @@ " -V print version information\n" msgstr "" -#: .././logprint/logprint.c:75 +#: .././logprint/logprint.c:76 #, c-format msgid " Can't open device %s: %s\n" msgstr "" -#: .././logprint/logprint.c:81 +#: .././logprint/logprint.c:82 #, c-format msgid " read of XFS superblock failed\n" msgstr "" -#: .././logprint/logprint.c:97 +#: .././logprint/logprint.c:102 #, c-format msgid "" " external log device not specified\n" "\n" msgstr "" -#: .././logprint/logprint.c:112 +#: .././logprint/logprint.c:118 #, c-format msgid "Can't open file %s: %s\n" msgstr "" -#: .././logprint/logprint.c:212 +#: .././logprint/logprint.c:219 #, c-format msgid "xfs_logprint:\n" msgstr "" -#: .././logprint/logprint.c:220 +#: .././logprint/logprint.c:228 #, c-format msgid " data device: 0x%llx\n" msgstr "" -#: .././logprint/logprint.c:223 +#: .././logprint/logprint.c:231 #, c-format msgid " log file: \"%s\" " msgstr "" -#: .././logprint/logprint.c:225 +#: .././logprint/logprint.c:233 #, c-format msgid " log device: 0x%llx " msgstr "" -#: .././logprint/logprint.c:228 +#: .././logprint/logprint.c:236 #, c-format msgid "" "daddr: %lld length: %lld\n" "\n" msgstr "" -#: .././logprint/log_misc.c:132 -#, c-format -msgid "Oper (%d): tid: %x len: %d clientid: %s " -msgstr "" - -#: .././logprint/log_misc.c:137 +#: .././logprint/log_print_all.c:94 #, c-format -msgid "flags: " +msgid "" +"BUF: #regs:%d start blkno:0x%llx len:%d bmap size:%d flags:0x%x\n" msgstr "" -#: .././logprint/log_misc.c:231 +#: .././logprint/log_print_all.c:104 #, c-format -msgid " Not enough data to decode further\n" +msgid "\tSUPER Block Buffer:\n" msgstr "" -#: .././logprint/log_misc.c:235 +#: .././logprint/log_print_all.c:107 #, c-format -msgid " type: %s tid: %x num_items: %d\n" +msgid " icount:%llu ifree:%llu " msgstr "" -#: .././logprint/log_misc.c:277 +#: .././logprint/log_print_all.c:112 #, c-format -msgid "" -"#regs: %d start blkno: %lld (0x%llx) len: %d bmap size: %d flags: 0x%x\n" +msgid "fdblks:%llu frext:%llu\n" msgstr "" -#: .././logprint/log_misc.c:283 +#: .././logprint/log_print_all.c:117 #, c-format -msgid "#regs: %d Not printing rest of data\n" +msgid "\t\tsunit:%u swidth:%u\n" msgstr "" -#: .././logprint/log_misc.c:300 +#: .././logprint/log_print_all.c:123 #, c-format -msgid "SUPER BLOCK Buffer: " +msgid "\tAGI Buffer: (XAGI)\n" msgstr "" -#: .././logprint/log_misc.c:302 .././logprint/log_misc.c:366 -#: .././logprint/log_misc.c:392 +#: .././logprint/log_print_all.c:126 #, c-format -msgid "Out of space\n" +msgid "\t\tver:%d " msgstr "" -#: .././logprint/log_misc.c:310 +#: .././logprint/log_print_all.c:128 #, c-format -msgid "icount: %llu ifree: %llu " +msgid "seq#:%d len:%d cnt:%d root:%d\n" msgstr "" -#: .././logprint/log_misc.c:315 +#: .././logprint/log_print_all.c:133 #, c-format -msgid "fdblks: %llu frext: %llu\n" +msgid "\t\tlevel:%d free#:0x%x newino:0x%x\n" msgstr "" -#: .././logprint/log_misc.c:322 +#: .././logprint/log_print_all.c:146 .././logprint/log_misc.c:357 #, c-format -msgid "AGI Buffer: XAGI " +msgid "bucket[%d - %d]: " msgstr "" -#: .././logprint/log_misc.c:325 +#: .././logprint/log_print_all.c:157 #, c-format -msgid "out of space\n" +msgid "\tAGF Buffer: (XAGF)\n" msgstr "" -#: .././logprint/log_misc.c:328 +#: .././logprint/log_print_all.c:160 #, c-format -msgid "ver: %d " +msgid "\t\tver:%d seq#:%d len:%d \n" msgstr "" -#: .././logprint/log_misc.c:330 +#: .././logprint/log_print_all.c:164 #, c-format -msgid "seq#: %d len: %d cnt: %d root: %d\n" +msgid "\t\troot BNO:%d CNT:%d\n" msgstr "" -#: .././logprint/log_misc.c:335 +#: .././logprint/log_print_all.c:167 #, c-format -msgid "level: %d free#: 0x%x newino: 0x%x\n" +msgid "\t\tlevel BNO:%d CNT:%d\n" msgstr "" -#: .././logprint/log_misc.c:345 +#: .././logprint/log_print_all.c:170 #, c-format -msgid "AGI unlinked data skipped " +msgid "\t\t1st:%d last:%d cnt:%d freeblks:%d longest:%d\n" msgstr "" -#: .././logprint/log_misc.c:346 +#: .././logprint/log_print_all.c:179 #, c-format -msgid "(CONTINUE set, no space)\n" +msgid "\tDQUOT Buffer:\n" msgstr "" -#: .././logprint/log_misc.c:352 +#: .././logprint/log_print_all.c:182 #, c-format -msgid "bucket[%d - %d]: " +msgid "\t\tUIDs 0x%lx-0x%lx\n" msgstr "" -#: .././logprint/log_misc.c:364 +#: .././logprint/log_print_all.c:187 #, c-format -msgid "AGF Buffer: XAGF " +msgid "\tBUF DATA\n" msgstr "" -#: .././logprint/log_misc.c:369 +#: .././logprint/log_print_all.c:209 #, c-format -msgid "ver: %d seq#: %d len: %d \n" +msgid "\tQUOTAOFF: #regs:%d type:%s\n" msgstr "" -#: .././logprint/log_misc.c:373 +#: .././logprint/log_print_all.c:224 #, c-format -msgid "root BNO: %d CNT: %d\n" +msgid "\tDQUOT: #regs:%d blkno:%lld boffset:%u id: %d\n" msgstr "" -#: .././logprint/log_misc.c:376 +#: .././logprint/log_print_all.c:228 #, c-format -msgid "level BNO: %d CNT: %d\n" +msgid "\t\tmagic 0x%x\tversion 0x%x\tID 0x%x (%d)\t\n" msgstr "" -#: .././logprint/log_misc.c:379 +#: .././logprint/log_print_all.c:233 #, c-format -msgid "1st: %d last: %d cnt: %d freeblks: %d longest: %d\n" +msgid "\t\tblk_hard 0x%x\tblk_soft 0x%x\tino_hard 0x%x\tino_soft 0x%x\n" msgstr "" -#: .././logprint/log_misc.c:389 +#: .././logprint/log_print_all.c:239 #, c-format -msgid "DQUOT Buffer: DQ " +msgid "\t\tbcount 0x%x (%d) icount 0x%x (%d)\n" msgstr "" -#: .././logprint/log_misc.c:396 +#: .././logprint/log_print_all.c:244 #, c-format -msgid "ver: %d flags: 0x%x id: %d \n" +msgid "\t\tbtimer 0x%x itimer 0x%x \n" msgstr "" -#: .././logprint/log_misc.c:399 +#: .././logprint/log_print_all.c:253 #, c-format -msgid "blk limits hard: %llu soft: %llu\n" +msgid "\tCORE inode:\n" msgstr "" -#: .././logprint/log_misc.c:404 +#: .././logprint/log_print_all.c:256 #, c-format -msgid "blk count: %llu warns: %d timer: %d\n" +msgid "\t\tmagic:%c%c mode:0x%x ver:%d format:%d onlink:%d\n" msgstr "" -#: .././logprint/log_misc.c:408 +#: .././logprint/log_print_all.c:260 #, c-format -msgid "ino limits hard: %llu soft: %llu\n" +msgid "\t\tuid:%d gid:%d nlink:%d projid:%u\n" msgstr "" -#: .././logprint/log_misc.c:413 +#: .././logprint/log_print_all.c:262 #, c-format -msgid "ino count: %llu warns: %d timer: %d\n" +msgid "\t\tatime:%d mtime:%d ctime:%d\n" msgstr "" -#: .././logprint/log_misc.c:419 +#: .././logprint/log_print_all.c:264 #, c-format -msgid "BUF DATA\n" +msgid "\t\tflushiter:%d\n" msgstr "" -#: .././logprint/log_misc.c:461 +#: .././logprint/log_print_all.c:265 #, c-format -msgid "EFD: #regs: %d num_extents: %d id: 0x%llx\n" +msgid "\t\tsize:0x%llx nblks:0x%llx exsize:%d nextents:%d anextents:%d\n" msgstr "" -#: .././logprint/log_misc.c:468 +#: .././logprint/log_print_all.c:269 #, c-format -msgid "EFD: Not enough data to decode further\n" +msgid "\t\tforkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x gen:%d\n" msgstr "" -#: .././logprint/log_misc.c:488 .././logprint/log_misc.c:497 +#: .././logprint/log_print_all.c:289 #, c-format -msgid "%s: xlog_print_trans_efi: malloc failed\n" +msgid "\tINODE: #regs:%d ino:0x%llx flags:0x%x dsize:%d\n" msgstr "" -#: .././logprint/log_misc.c:505 +#: .././logprint/log_print_all.c:305 #, c-format -msgid "EFI: #regs: %d num_extents: %d id: 0x%llx\n" +msgid "\t\tDATA FORK EXTENTS inode data:\n" msgstr "" -#: .././logprint/log_misc.c:532 +#: .././logprint/log_print_all.c:312 #, c-format -msgid "QOFF: #regs: %d flags: 0x%x\n" +msgid "\t\tDATA FORK BTREE inode data:\n" msgstr "" -#: .././logprint/log_misc.c:535 +#: .././logprint/log_print_all.c:319 #, c-format -msgid "QOFF: Not enough data to decode further\n" +msgid "\t\tDATA FORK LOCAL inode data:\n" msgstr "" -#: .././logprint/log_misc.c:544 +#: .././logprint/log_print_all.c:326 #, c-format -msgid "INODE CORE\n" +msgid "\t\tDEV inode: no extra region\n" msgstr "" -#: .././logprint/log_misc.c:545 +#: .././logprint/log_print_all.c:330 #, c-format -msgid "magic 0x%hx mode 0%ho version %d format %d\n" +msgid "\t\tUUID inode: no extra region\n" msgstr "" -#: .././logprint/log_misc.c:548 +#: .././logprint/log_print_all.c:345 #, c-format -msgid "nlink %hd uid %d gid %d\n" +msgid "\t\tATTR FORK EXTENTS inode data:\n" msgstr "" -#: .././logprint/log_misc.c:550 +#: .././logprint/log_print_all.c:353 #, c-format -msgid "atime 0x%x mtime 0x%x ctime 0x%x\n" +msgid "\t\tATTR FORK BTREE inode data:\n" msgstr "" -#: .././logprint/log_misc.c:552 +#: .././logprint/log_print_all.c:361 #, c-format -msgid "size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n" +msgid "\t\tATTR FORK LOCAL inode data:\n" msgstr "" -#: .././logprint/log_misc.c:555 +#: .././logprint/log_print_all.c:386 #, c-format -msgid "naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n" +msgid "\tEFD: #regs: %d num_extents: %d id: 0x%llx\n" msgstr "" -#: .././logprint/log_misc.c:558 +#: .././logprint/log_print_all.c:410 #, c-format -msgid "flags 0x%x gen 0x%x\n" +msgid "%s: xlog_recover_print_efi: malloc failed\n" msgstr "" -#: .././logprint/log_misc.c:574 +#: .././logprint/log_print_all.c:418 #, c-format -msgid "SHORTFORM DIRECTORY size %d\n" +msgid "\tEFI: #regs:%d num_extents:%d id:0x%llx\n" msgstr "" -#: .././logprint/log_misc.c:580 +#: .././logprint/log_print_all.c:442 #, c-format -msgid "SHORTFORM DIRECTORY size %d count %d\n" +msgid "" +"\tICR: #ag: %d agbno: 0x%x len: %d\n" +"\t cnt: %d isize: %d gen: 0x%x\n" msgstr "" -#: .././logprint/log_misc.c:583 +#: .././logprint/log_print_all.c:476 #, c-format -msgid ".. ino 0x%llx\n" +msgid "xlog_recover_print_logitem: illegal type\n" msgstr "" -#: .././logprint/log_misc.c:591 +#: .././logprint/log_print_all.c:510 #, c-format -msgid "%s ino 0x%llx namelen %d\n" +msgid "%s: illegal type" msgstr "" -#: .././logprint/log_misc.c:623 +#: .././logprint/log_print_all.c:518 #, c-format -msgid "INODE: " +msgid ": cnt:%d total:%d " msgstr "" -#: .././logprint/log_misc.c:624 +#: .././logprint/log_print_all.c:520 #, c-format -msgid "#regs: %d ino: 0x%llx flags: 0x%x dsize: %d\n" +msgid "a:0x%lx len:%d " msgstr "" -#: .././logprint/log_misc.c:627 +#: .././logprint/log_misc.c:131 #, c-format -msgid " blkno: %lld len: %d boff: %d\n" +msgid "Oper (%d): tid: %x len: %d clientid: %s " msgstr "" -#: .././logprint/log_misc.c:632 +#: .././logprint/log_misc.c:136 #, c-format -msgid "INODE: #regs: %d Not printing rest of data\n" +msgid "flags: " msgstr "" -#: .././logprint/log_misc.c:665 +#: .././logprint/log_misc.c:230 #, c-format -msgid "EXTENTS inode data\n" +msgid " Not enough data to decode further\n" msgstr "" -#: .././logprint/log_misc.c:676 +#: .././logprint/log_misc.c:234 #, c-format -msgid "BTREE inode data\n" +msgid " type: %s tid: %x num_items: %d\n" msgstr "" -#: .././logprint/log_misc.c:687 +#: .././logprint/log_misc.c:282 #, c-format -msgid "LOCAL inode data\n" +msgid "" +"#regs: %d start blkno: %lld (0x%llx) len: %d bmap size: %d flags: 0x%x\n" msgstr "" -#: .././logprint/log_misc.c:701 +#: .././logprint/log_misc.c:288 #, c-format -msgid "EXTENTS inode attr\n" +msgid "#regs: %d Not printing rest of data\n" msgstr "" -#: .././logprint/log_misc.c:712 +#: .././logprint/log_misc.c:305 #, c-format -msgid "BTREE inode attr\n" +msgid "SUPER BLOCK Buffer: " msgstr "" -#: .././logprint/log_misc.c:723 +#: .././logprint/log_misc.c:307 .././logprint/log_misc.c:371 +#: .././logprint/log_misc.c:397 #, c-format -msgid "LOCAL inode attr\n" +msgid "Out of space\n" msgstr "" -#: .././logprint/log_misc.c:735 +#: .././logprint/log_misc.c:315 #, c-format -msgid "DEV inode: no extra region\n" +msgid "icount: %llu ifree: %llu " msgstr "" -#: .././logprint/log_misc.c:740 +#: .././logprint/log_misc.c:320 #, c-format -msgid "UUID inode: no extra region\n" +msgid "fdblks: %llu frext: %llu\n" msgstr "" -#: .././logprint/log_misc.c:748 -msgid "xlog_print_trans_inode: illegal inode type" +#: .././logprint/log_misc.c:327 +#, c-format +msgid "AGI Buffer: XAGI " msgstr "" -#: .././logprint/log_misc.c:776 +#: .././logprint/log_misc.c:330 #, c-format -msgid "#regs: %d id: 0x%x" +msgid "out of space\n" msgstr "" -#: .././logprint/log_misc.c:777 +#: .././logprint/log_misc.c:333 #, c-format -msgid " blkno: %lld len: %d boff: %d\n" +msgid "ver: %d " msgstr "" -#: .././logprint/log_misc.c:781 +#: .././logprint/log_misc.c:335 #, c-format -msgid "DQUOT: #regs: %d Not printing rest of data\n" +msgid "seq#: %d len: %d cnt: %d root: %d\n" msgstr "" -#: .././logprint/log_misc.c:800 +#: .././logprint/log_misc.c:340 #, c-format -msgid "DQUOT: magic 0x%hx flags 0%ho\n" +msgid "level: %d free#: 0x%x newino: 0x%x\n" msgstr "" -#: .././logprint/log_misc.c:828 +#: .././logprint/log_misc.c:350 #, c-format -msgid "%s: lseek64 to %lld failed: %s\n" +msgid "AGI unlinked data skipped " msgstr "" -#: .././logprint/log_misc.c:871 +#: .././logprint/log_misc.c:351 #, c-format -msgid "%s: xlog_print_record: malloc failed\n" +msgid "(CONTINUE set, no space)\n" msgstr "" -#: .././logprint/log_misc.c:880 +#: .././logprint/log_misc.c:369 #, c-format -msgid "%s: xlog_print_record: read error\n" +msgid "AGF Buffer: XAGF " msgstr "" -#: .././logprint/log_misc.c:967 +#: .././logprint/log_misc.c:374 #, c-format -msgid "Left over region from split log item\n" +msgid "ver: %d seq#: %d len: %d \n" msgstr "" -#: .././logprint/log_misc.c:1011 +#: .././logprint/log_misc.c:378 #, c-format -msgid "Unmount filesystem\n" +msgid "root BNO: %d CNT: %d\n" msgstr "" -#: .././logprint/log_misc.c:1016 +#: .././logprint/log_misc.c:381 #, c-format -msgid "%s: unknown log operation type (%x)\n" +msgid "level BNO: %d CNT: %d\n" msgstr "" -#: .././logprint/log_misc.c:1051 +#: .././logprint/log_misc.c:384 #, c-format -msgid "Header 0x%x wanted 0x%x\n" +msgid "1st: %d last: %d cnt: %d freeblks: %d longest: %d\n" msgstr "" -#: .././logprint/log_misc.c:1065 +#: .././logprint/log_misc.c:394 #, c-format -msgid "cycle: %d\tversion: %d\t" +msgid "DQUOT Buffer: DQ " msgstr "" -#: .././logprint/log_misc.c:1071 +#: .././logprint/log_misc.c:401 #, c-format -msgid "length of Log Record: %d\tprev offset: %d\t\tnum ops: %d\n" +msgid "ver: %d flags: 0x%x id: %d \n" msgstr "" -#: .././logprint/log_misc.c:1077 .././logprint/log_misc.c:1119 +#: .././logprint/log_misc.c:404 #, c-format -msgid "cycle num overwrites: " +msgid "blk limits hard: %llu soft: %llu\n" msgstr "" -#: .././logprint/log_misc.c:1086 +#: .././logprint/log_misc.c:409 #, c-format -msgid "uuid: %s format: " +msgid "blk count: %llu warns: %d timer: %d\n" msgstr "" -#: .././logprint/log_misc.c:1089 +#: .././logprint/log_misc.c:413 #, c-format -msgid "unknown\n" +msgid "ino limits hard: %llu soft: %llu\n" msgstr "" -#: .././logprint/log_misc.c:1092 +#: .././logprint/log_misc.c:418 #, c-format -msgid "little endian linux\n" +msgid "ino count: %llu warns: %d timer: %d\n" msgstr "" -#: .././logprint/log_misc.c:1095 +#: .././logprint/log_misc.c:424 #, c-format -msgid "big endian linux\n" +msgid "BUF DATA\n" msgstr "" -#: .././logprint/log_misc.c:1098 +#: .././logprint/log_misc.c:466 #, c-format -msgid "big endian irix\n" +msgid "EFD: #regs: %d num_extents: %d id: 0x%llx\n" msgstr "" -#: .././logprint/log_misc.c:1104 +#: .././logprint/log_misc.c:473 #, c-format -msgid "h_size: %d\n" +msgid "EFD: Not enough data to decode further\n" msgstr "" -#: .././logprint/log_misc.c:1116 +#: .././logprint/log_misc.c:497 .././logprint/log_misc.c:513 #, c-format -msgid "extended-header: cycle: %d\n" +msgid "%s: xlog_print_trans_efi: malloc failed\n" msgstr "" -#: .././logprint/log_misc.c:1132 +#: .././logprint/log_misc.c:507 #, c-format -msgid "* ERROR: found data after zeroed blocks block=%-21lld *\n" +msgid "EFI: Not enough data to decode further\n" msgstr "" -#: .././logprint/log_misc.c:1143 +#: .././logprint/log_misc.c:521 #, c-format -msgid "* ERROR: header cycle=%-11d block=%-21lld *\n" +msgid "EFI: #regs: %d num_extents: %d id: 0x%llx\n" msgstr "" -#: .././logprint/log_misc.c:1154 +#: .././logprint/log_misc.c:525 #, c-format -msgid "* ERROR: data block=%-21lld *\n" +msgid "EFI free extent data skipped (CONTINUE set, no space)\n" msgstr "" -#: .././logprint/log_misc.c:1165 +#: .././logprint/log_misc.c:554 #, c-format -msgid "" -"* ERROR: for header block=%lld\n" -"* not enough hdrs for data length, required num = %d, hdr num = %d\n" +msgid "QOFF: #regs: %d flags: 0x%x\n" msgstr "" -#: .././logprint/log_misc.c:1171 -msgid "Not enough headers for data length." +#: .././logprint/log_misc.c:557 +#, c-format +msgid "QOFF: Not enough data to decode further\n" msgstr "" -#: .././logprint/log_misc.c:1181 +#: .././logprint/log_misc.c:566 #, c-format -msgid "%s: xlog_print: malloc failed for ext hdrs\n" +msgid "INODE CORE\n" msgstr "" -#: .././logprint/log_misc.c:1227 .././logprint/log_misc.c:1302 -#: .././logprint/log_misc.c:1368 .././logprint/log_misc.c:1405 +#: .././logprint/log_misc.c:567 #, c-format -msgid "%s: physical end of log\n" +msgid "magic 0x%hx mode 0%ho version %d format %d\n" msgstr "" -#: .././logprint/log_misc.c:1233 .././logprint/log_misc.c:1307 -#: .././logprint/log_misc.c:1420 +#: .././logprint/log_misc.c:570 #, c-format -msgid "BLKNO: %lld\n" +msgid "nlink %hd uid %d gid %d\n" msgstr "" -#: .././logprint/log_misc.c:1290 +#: .././logprint/log_misc.c:572 #, c-format -msgid "%s: problem finding oldest LR\n" +msgid "atime 0x%x mtime 0x%x ctime 0x%x\n" msgstr "" -#: .././logprint/log_misc.c:1316 +#: .././logprint/log_misc.c:574 #, c-format -msgid "%s: after %d zeroed blocks\n" +msgid "size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n" msgstr "" -#: .././logprint/log_misc.c:1380 -msgid "illegal value" +#: .././logprint/log_misc.c:577 +#, c-format +msgid "naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n" msgstr "" -#: .././logprint/log_misc.c:1386 +#: .././logprint/log_misc.c:580 #, c-format -msgid "%s: skipped %d cleared blocks in range: %lld - %lld\n" +msgid "flags 0x%x gen 0x%x\n" msgstr "" -#: .././logprint/log_misc.c:1391 +#: .././logprint/log_misc.c:596 #, c-format -msgid "%s: totally cleared log\n" +msgid "SHORTFORM DIRECTORY size %d\n" msgstr "" -#: .././logprint/log_misc.c:1396 +#: .././logprint/log_misc.c:602 #, c-format -msgid "%s: skipped %d zeroed blocks in range: %lld - %lld\n" +msgid "SHORTFORM DIRECTORY size %d count %d\n" msgstr "" -#: .././logprint/log_misc.c:1401 +#: .././logprint/log_misc.c:605 #, c-format -msgid "%s: totally zeroed log\n" +msgid ".. ino 0x%llx\n" msgstr "" -#: .././logprint/log_misc.c:1417 -msgid "xlog_find_head: bad read" +#: .././logprint/log_misc.c:613 +#, c-format +msgid "%s ino 0x%llx namelen %d\n" msgstr "" -#: .././logprint/log_misc.c:1473 +#: .././logprint/log_misc.c:652 #, c-format -msgid "%s: logical end of log\n" +msgid "INODE: " msgstr "" -#: .././logprint/log_misc.c:1565 +#: .././logprint/log_misc.c:653 #, c-format -msgid "%s: bad size of efi format: %u; expected %u or %u; nextents = %u\n" +msgid "#regs: %d ino: 0x%llx flags: 0x%x dsize: %d\n" msgstr "" -#: .././logprint/log_print_all.c:98 +#: .././logprint/log_misc.c:656 #, c-format -msgid "" -"BUF: #regs:%d start blkno:0x%llx len:%d bmap size:%d flags:0x%x\n" +msgid " blkno: %lld len: %d boff: %d\n" msgstr "" -#: .././logprint/log_print_all.c:108 +#: .././logprint/log_misc.c:661 #, c-format -msgid "\tSUPER Block Buffer:\n" +msgid "INODE: #regs: %d Not printing rest of data\n" msgstr "" -#: .././logprint/log_print_all.c:111 +#: .././logprint/log_misc.c:692 #, c-format -msgid " icount:%llu ifree:%llu " +msgid "DEV inode: no extra region\n" msgstr "" -#: .././logprint/log_print_all.c:116 +#: .././logprint/log_misc.c:695 #, c-format -msgid "fdblks:%llu frext:%llu\n" +msgid "UUID inode: no extra region\n" msgstr "" -#: .././logprint/log_print_all.c:121 +#: .././logprint/log_misc.c:712 #, c-format -msgid "\t\tsunit:%u swidth:%u\n" +msgid "EXTENTS inode data\n" msgstr "" -#: .././logprint/log_print_all.c:126 +#: .././logprint/log_misc.c:715 #, c-format -msgid "\tAGI Buffer: (XAGI)\n" +msgid "BTREE inode data\n" msgstr "" -#: .././logprint/log_print_all.c:129 +#: .././logprint/log_misc.c:718 #, c-format -msgid "\t\tver:%d " +msgid "LOCAL inode data\n" msgstr "" -#: .././logprint/log_print_all.c:131 +#: .././logprint/log_misc.c:739 #, c-format -msgid "seq#:%d len:%d cnt:%d root:%d\n" +msgid "EXTENTS attr data\n" msgstr "" -#: .././logprint/log_print_all.c:136 +#: .././logprint/log_misc.c:742 #, c-format -msgid "\t\tlevel:%d free#:0x%x newino:0x%x\n" +msgid "BTREE attr data\n" msgstr "" -#: .././logprint/log_print_all.c:142 +#: .././logprint/log_misc.c:745 #, c-format -msgid "\tAGF Buffer: (XAGF)\n" +msgid "LOCAL attr data\n" msgstr "" -#: .././logprint/log_print_all.c:145 +#: .././logprint/log_misc.c:783 #, c-format -msgid "\t\tver:%d seq#:%d len:%d \n" +msgid "#regs: %d id: 0x%x" msgstr "" -#: .././logprint/log_print_all.c:149 +#: .././logprint/log_misc.c:784 #, c-format -msgid "\t\troot BNO:%d CNT:%d\n" +msgid " blkno: %lld len: %d boff: %d\n" msgstr "" -#: .././logprint/log_print_all.c:152 +#: .././logprint/log_misc.c:788 #, c-format -msgid "\t\tlevel BNO:%d CNT:%d\n" +msgid "DQUOT: #regs: %d Not printing rest of data\n" msgstr "" -#: .././logprint/log_print_all.c:155 +#: .././logprint/log_misc.c:807 #, c-format -msgid "\t\t1st:%d last:%d cnt:%d freeblks:%d longest:%d\n" +msgid "DQUOT: magic 0x%hx flags 0%ho\n" msgstr "" -#: .././logprint/log_print_all.c:164 +#: .././logprint/log_misc.c:833 #, c-format -msgid "\tDQUOT Buffer:\n" +msgid "ICR: split header, not printing\n" msgstr "" -#: .././logprint/log_print_all.c:167 +#: .././logprint/log_misc.c:837 #, c-format -msgid "\t\tUIDs 0x%lx-0x%lx\n" +msgid "" +"ICR: #ag: %d agbno: 0x%x len: %d\n" +" cnt: %d isize: %d gen: 0x%x\n" msgstr "" -#: .././logprint/log_print_all.c:172 +#: .././logprint/log_misc.c:863 #, c-format -msgid "\tBUF DATA\n" +msgid "%s: lseek64 to %lld failed: %s\n" msgstr "" -#: .././logprint/log_print_all.c:194 +#: .././logprint/log_misc.c:909 #, c-format -msgid "\tQUOTAOFF: #regs:%d type:%s\n" +msgid "%s: xlog_print_record: malloc failed\n" msgstr "" -#: .././logprint/log_print_all.c:209 +#: .././logprint/log_misc.c:918 #, c-format -msgid "\tDQUOT: #regs:%d blkno:%lld boffset:%u id: %d\n" +msgid "%s: xlog_print_record: read error\n" msgstr "" -#: .././logprint/log_print_all.c:213 +#: .././logprint/log_misc.c:1013 .././logprint/log_misc.c:1083 #, c-format -msgid "\t\tmagic 0x%x\tversion 0x%x\tID 0x%x (%d)\t\n" +msgid "Left over region from split log item\n" msgstr "" -#: .././logprint/log_print_all.c:218 +#: .././logprint/log_misc.c:1068 #, c-format -msgid "\t\tblk_hard 0x%x\tblk_soft 0x%x\tino_hard 0x%x\tino_soft 0x%x\n" +msgid "Unmount filesystem\n" msgstr "" -#: .././logprint/log_print_all.c:224 +#: .././logprint/log_misc.c:1075 #, c-format -msgid "\t\tbcount 0x%x (%d) icount 0x%x (%d)\n" +msgid "%s: unknown log operation type (%x)\n" msgstr "" -#: .././logprint/log_print_all.c:229 +#: .././logprint/log_misc.c:1116 #, c-format -msgid "\t\tbtimer 0x%x itimer 0x%x \n" +msgid "Header 0x%x wanted 0x%x\n" msgstr "" -#: .././logprint/log_print_all.c:238 +#: .././logprint/log_misc.c:1130 #, c-format -msgid "\tCORE inode:\n" +msgid "cycle: %d\tversion: %d\t" msgstr "" -#: .././logprint/log_print_all.c:241 +#: .././logprint/log_misc.c:1136 #, c-format -msgid "\t\tmagic:%c%c mode:0x%x ver:%d format:%d onlink:%d\n" +msgid "length of Log Record: %d\tprev offset: %d\t\tnum ops: %d\n" msgstr "" -#: .././logprint/log_print_all.c:245 +#: .././logprint/log_misc.c:1142 .././logprint/log_misc.c:1184 #, c-format -msgid "\t\tuid:%d gid:%d nlink:%d projid:%u\n" +msgid "cycle num overwrites: " msgstr "" -#: .././logprint/log_print_all.c:247 +#: .././logprint/log_misc.c:1151 #, c-format -msgid "\t\tatime:%d mtime:%d ctime:%d\n" +msgid "uuid: %s format: " msgstr "" -#: .././logprint/log_print_all.c:249 +#: .././logprint/log_misc.c:1154 #, c-format -msgid "\t\tflushiter:%d\n" +msgid "unknown\n" msgstr "" -#: .././logprint/log_print_all.c:250 +#: .././logprint/log_misc.c:1157 #, c-format -msgid "\t\tsize:0x%llx nblks:0x%llx exsize:%d nextents:%d anextents:%d\n" +msgid "little endian linux\n" msgstr "" -#: .././logprint/log_print_all.c:254 +#: .././logprint/log_misc.c:1160 #, c-format -msgid "\t\tforkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x gen:%d\n" +msgid "big endian linux\n" msgstr "" -#: .././logprint/log_print_all.c:274 +#: .././logprint/log_misc.c:1163 #, c-format -msgid "\tINODE: #regs:%d ino:0x%llx flags:0x%x dsize:%d\n" +msgid "big endian irix\n" msgstr "" -#: .././logprint/log_print_all.c:289 +#: .././logprint/log_misc.c:1169 #, c-format -msgid "\t\tDATA FORK EXTENTS inode data:\n" +msgid "h_size: %d\n" msgstr "" -#: .././logprint/log_print_all.c:296 +#: .././logprint/log_misc.c:1181 #, c-format -msgid "\t\tDATA FORK BTREE inode data:\n" +msgid "extended-header: cycle: %d\n" msgstr "" -#: .././logprint/log_print_all.c:303 +#: .././logprint/log_misc.c:1197 #, c-format -msgid "\t\tDATA FORK LOCAL inode data:\n" +msgid "* ERROR: found data after zeroed blocks block=%-21lld *\n" msgstr "" -#: .././logprint/log_print_all.c:310 +#: .././logprint/log_misc.c:1208 #, c-format -msgid "\t\tDEV inode: no extra region\n" +msgid "* ERROR: header cycle=%-11d block=%-21lld *\n" msgstr "" -#: .././logprint/log_print_all.c:314 +#: .././logprint/log_misc.c:1219 #, c-format -msgid "\t\tUUID inode: no extra region\n" +msgid "* ERROR: data block=%-21lld *\n" msgstr "" -#: .././logprint/log_print_all.c:329 +#: .././logprint/log_misc.c:1230 #, c-format -msgid "\t\tATTR FORK EXTENTS inode data:\n" +msgid "" +"* ERROR: for header block=%lld\n" +"* not enough hdrs for data length, required num = %d, hdr num = %d\n" msgstr "" -#: .././logprint/log_print_all.c:337 -#, c-format -msgid "\t\tATTR FORK BTREE inode data:\n" +#: .././logprint/log_misc.c:1236 +msgid "Not enough headers for data length." msgstr "" -#: .././logprint/log_print_all.c:345 +#: .././logprint/log_misc.c:1246 #, c-format -msgid "\t\tATTR FORK LOCAL inode data:\n" +msgid "%s: xlog_print: malloc failed for ext hdrs\n" msgstr "" -#: .././logprint/log_print_all.c:370 +#: .././logprint/log_misc.c:1292 .././logprint/log_misc.c:1368 +#: .././logprint/log_misc.c:1439 .././logprint/log_misc.c:1476 #, c-format -msgid "\tEFD: #regs: %d num_extents: %d id: 0x%llx\n" +msgid "%s: physical end of log\n" msgstr "" -#: .././logprint/log_print_all.c:394 +#: .././logprint/log_misc.c:1298 .././logprint/log_misc.c:1373 +#: .././logprint/log_misc.c:1491 #, c-format -msgid "%s: xlog_recover_print_efi: malloc failed\n" +msgid "BLKNO: %lld\n" msgstr "" -#: .././logprint/log_print_all.c:402 +#: .././logprint/log_misc.c:1356 #, c-format -msgid "\tEFI: #regs:%d num_extents:%d id:0x%llx\n" +msgid "%s: problem finding oldest LR\n" msgstr "" -#: .././logprint/log_print_all.c:442 +#: .././logprint/log_misc.c:1382 #, c-format -msgid "xlog_recover_print_logitem: illegal type\n" +msgid "%s: after %d zeroed blocks\n" msgstr "" -#: .././logprint/log_print_all.c:473 -#, c-format -msgid "%s: illegal type" +#: .././logprint/log_misc.c:1451 +msgid "illegal value" msgstr "" -#: .././logprint/log_print_all.c:481 +#: .././logprint/log_misc.c:1457 #, c-format -msgid ": cnt:%d total:%d " +msgid "%s: skipped %d cleared blocks in range: %lld - %lld\n" msgstr "" -#: .././logprint/log_print_all.c:483 +#: .././logprint/log_misc.c:1462 #, c-format -msgid "a:0x%lx len:%d " +msgid "%s: totally cleared log\n" msgstr "" -#: .././logprint/log_print_trans.c:25 +#: .././logprint/log_misc.c:1467 #, c-format -msgid "TRANS: tid:0x%x type:%s #items:%d trans:0x%x q:0x%lx\n" +msgid "%s: skipped %d zeroed blocks in range: %lld - %lld\n" msgstr "" -#: .././logprint/log_print_trans.c:51 +#: .././logprint/log_misc.c:1472 #, c-format -msgid "%s: failed to find head and tail, error: %d\n" +msgid "%s: totally zeroed log\n" msgstr "" -#: .././logprint/log_print_trans.c:56 -#, c-format -msgid " log tail: %lld head: %lld state: %s\n" +#: .././logprint/log_misc.c:1488 +msgid "xlog_find_head: bad read" msgstr "" -#: .././logprint/log_print_trans.c:62 +#: .././logprint/log_misc.c:1540 #, c-format -msgid " override tail: %d\n" +msgid "%s: logical end of log\n" msgstr "" -#: .././logprint/log_print_trans.c:72 +#: .././logprint/log_misc.c:1636 #, c-format -msgid "%s: failed in xfs_do_recovery_pass, error: %d\n" +msgid "%s: bad size of efi format: %u; expected %u or %u; nextents = %u\n" msgstr "" #: .././mkfs/proto.c:60 @@ -6123,547 +6320,575 @@ msgid "%s: failed to open %s: %s\n" msgstr "" -#: .././mkfs/proto.c:66 .././mkfs/proto.c:291 +#: .././mkfs/proto.c:67 .././mkfs/proto.c:300 #, c-format msgid "%s: read failed on %s: %s\n" msgstr "" -#: .././mkfs/proto.c:71 +#: .././mkfs/proto.c:72 #, c-format msgid "%s: proto file %s premature EOF\n" msgstr "" -#: .././mkfs/proto.c:108 +#: .././mkfs/proto.c:116 msgid "cannot reserve space" msgstr "" -#: .././mkfs/proto.c:161 +#: .././mkfs/proto.c:171 #, c-format msgid "%s: premature EOF in prototype file\n" msgstr "" -#: .././mkfs/proto.c:180 +#: .././mkfs/proto.c:190 msgid "error reserving space for a file" msgstr "" -#: .././mkfs/proto.c:249 +#: .././mkfs/proto.c:258 msgid "error allocating space for a file" msgstr "" -#: .././mkfs/proto.c:253 +#: .././mkfs/proto.c:262 #, c-format msgid "%s: cannot allocate space for file\n" msgstr "" -#: .././mkfs/proto.c:316 +#: .././mkfs/proto.c:327 msgid "directory createname error" msgstr "" -#: .././mkfs/proto.c:330 +#: .././mkfs/proto.c:341 msgid "directory create error" msgstr "" -#: .././mkfs/proto.c:396 .././mkfs/proto.c:408 .././mkfs/proto.c:419 -#: .././mkfs/proto.c:426 +#: .././mkfs/proto.c:407 .././mkfs/proto.c:419 .././mkfs/proto.c:430 +#: .././mkfs/proto.c:437 #, c-format msgid "%s: bad format string %s\n" msgstr "" -#: .././mkfs/proto.c:447 .././mkfs/proto.c:486 .././mkfs/proto.c:501 -#: .././mkfs/proto.c:513 .././mkfs/proto.c:525 .././mkfs/proto.c:536 +#: .././mkfs/proto.c:459 .././mkfs/proto.c:499 .././mkfs/proto.c:514 +#: .././mkfs/proto.c:526 .././mkfs/proto.c:538 .././mkfs/proto.c:549 msgid "Inode allocation failed" msgstr "" -#: .././mkfs/proto.c:464 +#: .././mkfs/proto.c:476 msgid "Inode pre-allocation failed" msgstr "" -#: .././mkfs/proto.c:474 +#: .././mkfs/proto.c:486 msgid "Pre-allocated file creation failed" msgstr "" -#: .././mkfs/proto.c:556 +#: .././mkfs/proto.c:568 msgid "Directory creation failed" msgstr "" -#: .././mkfs/proto.c:580 +#: .././mkfs/proto.c:589 +msgid "Unknown format" +msgstr "" + +#: .././mkfs/proto.c:594 msgid "Error encountered creating file from prototype file" msgstr "" -#: .././mkfs/proto.c:630 +#: .././mkfs/proto.c:648 msgid "Realtime bitmap inode allocation failed" msgstr "" -#: .././mkfs/proto.c:648 +#: .././mkfs/proto.c:665 msgid "Realtime summary inode allocation failed" msgstr "" -#: .././mkfs/proto.c:675 +#: .././mkfs/proto.c:692 msgid "Allocation of the realtime bitmap failed" msgstr "" -#: .././mkfs/proto.c:688 +#: .././mkfs/proto.c:705 msgid "Completion of the realtime bitmap failed" msgstr "" -#: .././mkfs/proto.c:712 +#: .././mkfs/proto.c:728 msgid "Allocation of the realtime summary failed" msgstr "" -#: .././mkfs/proto.c:724 +#: .././mkfs/proto.c:740 msgid "Completion of the realtime summary failed" msgstr "" -#: .././mkfs/proto.c:741 +#: .././mkfs/proto.c:759 msgid "Error initializing the realtime space" msgstr "" -#: .././mkfs/proto.c:746 +#: .././mkfs/proto.c:764 msgid "Error completing the realtime space" msgstr "" -#: .././mkfs/xfs_mkfs.c:220 +#: .././mkfs/xfs_mkfs.c:230 #, c-format msgid "data su/sw must not be used in conjunction with data sunit/swidth\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:227 +#: .././mkfs/xfs_mkfs.c:237 #, c-format msgid "both data sunit and data swidth options must be specified\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:236 +#: .././mkfs/xfs_mkfs.c:246 #, c-format msgid "data sunit/swidth must not be used in conjunction with data su/sw\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:243 +#: .././mkfs/xfs_mkfs.c:253 #, c-format msgid "both data su and data sw options must be specified\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:250 +#: .././mkfs/xfs_mkfs.c:260 #, c-format msgid "data su must be a multiple of the sector size (%d)\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:261 +#: .././mkfs/xfs_mkfs.c:271 #, c-format msgid "" "data stripe width (%d) must be a multiple of the data stripe unit (%d)\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:271 +#: .././mkfs/xfs_mkfs.c:281 #, c-format msgid "log su should not be used in conjunction with log sunit\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:280 +#: .././mkfs/xfs_mkfs.c:290 #, c-format msgid "log sunit should not be used in conjunction with log su\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:350 .././mkfs/xfs_mkfs.c:474 +#: .././mkfs/xfs_mkfs.c:360 .././mkfs/xfs_mkfs.c:503 #, c-format msgid "%s: %s appears to contain an existing filesystem (%s).\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:354 .././mkfs/xfs_mkfs.c:480 +#: .././mkfs/xfs_mkfs.c:364 .././mkfs/xfs_mkfs.c:509 #, c-format msgid "%s: %s appears to contain a partition table (%s).\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:358 +#: .././mkfs/xfs_mkfs.c:368 #, c-format msgid "%s: %s appears to contain something weird according to blkid\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:368 +#: .././mkfs/xfs_mkfs.c:378 #, c-format msgid "%s: probe of %s failed, cannot detect existing filesystem.\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:421 +#: .././mkfs/xfs_mkfs.c:431 #, c-format msgid "warning: device is not properly aligned %s\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:426 +#: .././mkfs/xfs_mkfs.c:436 #, c-format msgid "Use -f to force usage of a misaligned device\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:440 +#: .././mkfs/xfs_mkfs.c:450 #, c-format msgid "warning: unable to probe device toplology for device %s\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:549 +#: .././mkfs/xfs_mkfs.c:578 #, c-format msgid "log size %lld is not a multiple of the log stripe unit %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:577 +#: .././mkfs/xfs_mkfs.c:606 #, c-format msgid "Due to stripe alignment, the internal log size (%lld) is too large.\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:579 +#: .././mkfs/xfs_mkfs.c:608 #, c-format msgid "Must fit within an allocation group.\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:590 +#: .././mkfs/xfs_mkfs.c:619 #, c-format msgid "log size %lld blocks too small, minimum size is %d blocks\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:596 +#: .././mkfs/xfs_mkfs.c:625 #, c-format msgid "log size %lld blocks too large, maximum size is %lld blocks\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:602 +#: .././mkfs/xfs_mkfs.c:631 #, c-format msgid "log size %lld bytes too large, maximum size is %lld bytes\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:710 +#: .././mkfs/xfs_mkfs.c:739 #, c-format msgid "agsize (%lld blocks) too small, need at least %lld blocks\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:718 +#: .././mkfs/xfs_mkfs.c:747 #, c-format msgid "agsize (%lld blocks) too big, maximum is %lld blocks\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:726 +#: .././mkfs/xfs_mkfs.c:755 #, c-format msgid "agsize (%lld blocks) too big, data area is %lld blocks\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:733 +#: .././mkfs/xfs_mkfs.c:762 #, c-format msgid "too many allocation groups for size = %lld\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:735 +#: .././mkfs/xfs_mkfs.c:764 #, c-format msgid "need at most %lld allocation groups\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:743 +#: .././mkfs/xfs_mkfs.c:772 #, c-format msgid "too few allocation groups for size = %lld\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:745 +#: .././mkfs/xfs_mkfs.c:774 #, c-format msgid "need at least %lld allocation groups\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:758 +#: .././mkfs/xfs_mkfs.c:787 #, c-format msgid "last AG size %lld blocks too small, minimum size is %lld blocks\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:769 +#: .././mkfs/xfs_mkfs.c:798 #, c-format msgid "%lld allocation groups is too many, maximum is %lld\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:793 +#: .././mkfs/xfs_mkfs.c:822 #, c-format msgid "error reading existing superblock -- failed to memalign buffer\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:799 +#: .././mkfs/xfs_mkfs.c:828 #, c-format msgid "existing superblock read failed: %s\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1098 +#: .././mkfs/xfs_mkfs.c:1133 #, c-format msgid "%s: Specify data sunit in 512-byte blocks, no unit suffix\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1114 +#: .././mkfs/xfs_mkfs.c:1149 #, c-format msgid "%s: Specify data swidth in 512-byte blocks, no unit suffix\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1141 +#: .././mkfs/xfs_mkfs.c:1176 #, c-format msgid "%s: Specify data sw as multiple of su, no unit suffix\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1370 +#: .././mkfs/xfs_mkfs.c:1405 #, c-format msgid "Specify log sunit in 512-byte blocks, no size suffix\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1630 +#: .././mkfs/xfs_mkfs.c:1508 .././mkfs/xfs_mkfs.c:1585 +#, c-format +msgid "cannot specify both crc and ftype\n" +msgstr "" + +#: .././mkfs/xfs_mkfs.c:1710 #, c-format msgid "extra arguments\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1636 +#: .././mkfs/xfs_mkfs.c:1716 #, c-format msgid "cannot specify both %s and -d name=%s\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1653 +#: .././mkfs/xfs_mkfs.c:1733 #, c-format msgid "illegal block size %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1688 +#: .././mkfs/xfs_mkfs.c:1768 #, c-format msgid "specified blocksize %d is less than device physical sector size %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1691 +#: .././mkfs/xfs_mkfs.c:1771 #, c-format msgid "switching to logical sector size %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1709 +#: .././mkfs/xfs_mkfs.c:1789 #, c-format msgid "illegal sector size %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1712 +#: .././mkfs/xfs_mkfs.c:1792 #, c-format msgid "block size %d cannot be smaller than logical sector size %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1717 +#: .././mkfs/xfs_mkfs.c:1797 #, c-format msgid "illegal sector size %d; hw sector is %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1723 +#: .././mkfs/xfs_mkfs.c:1803 #, c-format msgid "illegal log sector size %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1733 +#: .././mkfs/xfs_mkfs.c:1819 .././mkfs/xfs_mkfs.c:1924 +#, c-format +msgid "Minimum inode size for CRCs is %d bytes\n" +msgstr "" + +#: .././mkfs/xfs_mkfs.c:1827 +#, c-format +msgid "Inodes always aligned for CRC enabled filesytems\n" +msgstr "" + +#: .././mkfs/xfs_mkfs.c:1834 +#, c-format +msgid "Lazy superblock counted always enabled for CRC enabled filesytems\n" +msgstr "" + +#: .././mkfs/xfs_mkfs.c:1841 +#, c-format +msgid "V2 logs always enabled for CRC enabled filesytems\n" +msgstr "" + +#: .././mkfs/xfs_mkfs.c:1848 +#, c-format +msgid "V2 attribute format always enabled on CRC enabled filesytems\n" +msgstr "" + +#: .././mkfs/xfs_mkfs.c:1856 +#, c-format +msgid "32 bit Project IDs always enabled on CRC enabled filesytems\n" +msgstr "" + +#: .././mkfs/xfs_mkfs.c:1867 +#, c-format +msgid "warning: finobt not supported without CRC support, disabled.\n" +msgstr "" + +#: .././mkfs/xfs_mkfs.c:1874 #, c-format msgid "illegal directory block size %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1747 +#: .././mkfs/xfs_mkfs.c:1888 #, c-format msgid "both -d agcount= and agsize= specified, use one or the other\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1753 +#: .././mkfs/xfs_mkfs.c:1894 #, c-format msgid "if -d file then -d name and -d size are required\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1762 +#: .././mkfs/xfs_mkfs.c:1903 #, c-format msgid "illegal data length %lld, not a multiple of %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1768 +#: .././mkfs/xfs_mkfs.c:1909 #, c-format msgid "warning: data length %lld not a multiple of %d, truncated to %lld\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1782 +#: .././mkfs/xfs_mkfs.c:1931 #, c-format msgid "if -l file then -l name and -l size are required\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1791 +#: .././mkfs/xfs_mkfs.c:1940 #, c-format msgid "illegal log length %lld, not a multiple of %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1798 +#: .././mkfs/xfs_mkfs.c:1947 #, c-format msgid "warning: log length %lld not a multiple of %d, truncated to %lld\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1804 +#: .././mkfs/xfs_mkfs.c:1953 #, c-format msgid "if -r file then -r name and -r size are required\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1813 +#: .././mkfs/xfs_mkfs.c:1962 #, c-format msgid "illegal rt length %lld, not a multiple of %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1820 +#: .././mkfs/xfs_mkfs.c:1969 #, c-format msgid "warning: rt length %lld not a multiple of %d, truncated to %lld\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1833 +#: .././mkfs/xfs_mkfs.c:1982 #, c-format msgid "illegal rt extent size %lld, not a multiple of %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1839 +#: .././mkfs/xfs_mkfs.c:1988 #, c-format msgid "rt extent size %s too large, maximum %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1845 +#: .././mkfs/xfs_mkfs.c:1994 #, c-format msgid "rt extent size %s too small, minimum %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1890 +#: .././mkfs/xfs_mkfs.c:2037 #, c-format msgid "illegal inode size %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1895 +#: .././mkfs/xfs_mkfs.c:2042 #, c-format msgid "allowable inode size with %d byte blocks is %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1899 +#: .././mkfs/xfs_mkfs.c:2046 #, c-format msgid "allowable inode size with %d byte blocks is between %d and %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1907 +#: .././mkfs/xfs_mkfs.c:2054 #, c-format msgid "log stripe unit specified, using v2 logs\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1922 +#: .././mkfs/xfs_mkfs.c:2069 #, c-format msgid "no device name given in argument list\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1947 +#: .././mkfs/xfs_mkfs.c:2094 #, c-format msgid "%s: Use the -f option to force overwrite.\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1966 +#: .././mkfs/xfs_mkfs.c:2113 msgid "internal log" msgstr "" -#: .././mkfs/xfs_mkfs.c:1968 +#: .././mkfs/xfs_mkfs.c:2115 msgid "volume log" msgstr "" -#: .././mkfs/xfs_mkfs.c:1970 +#: .././mkfs/xfs_mkfs.c:2117 #, c-format msgid "no log subvolume or internal log\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1977 +#: .././mkfs/xfs_mkfs.c:2124 msgid "volume rt" msgstr "" -#: .././mkfs/xfs_mkfs.c:1982 +#: .././mkfs/xfs_mkfs.c:2129 #, c-format msgid "" "size %s specified for data subvolume is too large, maximum is %lld blocks\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1989 +#: .././mkfs/xfs_mkfs.c:2136 #, c-format msgid "can't get size of data subvolume\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:1994 +#: .././mkfs/xfs_mkfs.c:2141 #, c-format msgid "size %lld of data subvolume is too small, minimum %d blocks\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2001 +#: .././mkfs/xfs_mkfs.c:2148 #, c-format msgid "can't have both external and internal logs\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2005 +#: .././mkfs/xfs_mkfs.c:2152 #, c-format msgid "data and log sector sizes must be equal for internal logs\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2011 +#: .././mkfs/xfs_mkfs.c:2158 #, c-format msgid "" "Warning: the data subvolume sector size %u is less than the sector size \n" "reported by the device (%u).\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2017 +#: .././mkfs/xfs_mkfs.c:2164 #, c-format msgid "" "Warning: the log subvolume sector size %u is less than the sector size\n" "reported by the device (%u).\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2023 +#: .././mkfs/xfs_mkfs.c:2170 #, c-format msgid "" "Warning: the realtime subvolume sector size %u is less than the sector size\n" "reported by the device (%u).\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2037 -#, c-format -msgid "" -"size %s specified for log subvolume is too large, maximum is %lld blocks\n" -msgstr "" - -#: .././mkfs/xfs_mkfs.c:2044 -#, c-format -msgid "size specified for non-existent log subvolume\n" -msgstr "" - -#: .././mkfs/xfs_mkfs.c:2047 -#, c-format -msgid "size %lld too large for internal log\n" -msgstr "" - -#: .././mkfs/xfs_mkfs.c:2074 +#: .././mkfs/xfs_mkfs.c:2177 #, c-format msgid "" "size %s specified for rt subvolume is too large, maximum is %lld blocks\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2082 +#: .././mkfs/xfs_mkfs.c:2185 #, c-format msgid "size specified for non-existent rt subvolume\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2099 -#, c-format -msgid "agsize (%lld) not a multiple of fs blk size (%d)\n" -msgstr "" - -#: .././mkfs/xfs_mkfs.c:2116 +#: .././mkfs/xfs_mkfs.c:2200 #, c-format msgid "" -"%s: Specified data stripe unit %d is not the same as the volume stripe unit %" -"d\n" +"%s: Specified data stripe unit %d is not the same as the volume stripe unit " +"%d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2123 +#: .././mkfs/xfs_mkfs.c:2207 #, c-format msgid "" "%s: Specified data stripe width %d is not the same as the volume stripe " "width %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2171 +#: .././mkfs/xfs_mkfs.c:2225 +#, c-format +msgid "agsize (%lld) not a multiple of fs blk size (%d)\n" +msgstr "" + +#: .././mkfs/xfs_mkfs.c:2275 #, c-format msgid "agsize rounded to %lld, swidth = %d\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2203 +#: .././mkfs/xfs_mkfs.c:2307 #, c-format msgid "" "Warning: AG size is a multiple of stripe width. This can cause performance\n" @@ -6672,111 +6897,132 @@ "an AG size that is one stripe unit smaller, for example %llu.\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2228 +#: .././mkfs/xfs_mkfs.c:2332 #, c-format msgid "" -"%s: Stripe unit(%d) or stripe width(%d) is not a multiple of the block size(%" -"d)\n" +"%s: Stripe unit(%d) or stripe width(%d) is not a multiple of the block " +"size(%d)\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2260 +#: .././mkfs/xfs_mkfs.c:2364 #, c-format msgid "log stripe unit (%d) must be a multiple of the block size (%d)\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2273 +#: .././mkfs/xfs_mkfs.c:2377 #, c-format msgid "log stripe unit (%d bytes) is too large (maximum is 256KiB)\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2276 +#: .././mkfs/xfs_mkfs.c:2380 #, c-format msgid "log stripe unit adjusted to 32KiB\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2301 +#: .././mkfs/xfs_mkfs.c:2392 +#, c-format +msgid "" +"size %s specified for log subvolume is too large, maximum is %lld blocks\n" +msgstr "" + +#: .././mkfs/xfs_mkfs.c:2399 +#, c-format +msgid "size specified for non-existent log subvolume\n" +msgstr "" + +#: .././mkfs/xfs_mkfs.c:2402 +#, c-format +msgid "size %lld too large for internal log\n" +msgstr "" + +#: .././mkfs/xfs_mkfs.c:2495 #, c-format msgid "internal log size %lld too large, must fit in allocation group\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2308 +#: .././mkfs/xfs_mkfs.c:2503 #, c-format msgid "log ag number %d too large, must be less than %lld\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2338 +#: .././mkfs/xfs_mkfs.c:2541 #, c-format msgid "" "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n" " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" +" =%-22s crc=%-8u finobt=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" -"naming =version %-14u bsize=%-6u ascii-ci=%d\n" +"naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n" "log =%-22s bsize=%-6d blocks=%lld, version=%d\n" " =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n" "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2454 +#: .././mkfs/xfs_mkfs.c:2650 #, c-format msgid "%s: Growing the data section failed\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2484 +#: .././mkfs/xfs_mkfs.c:2679 #, c-format msgid "%s: filesystem failed to initialize\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2696 +#: .././mkfs/xfs_mkfs.c:2979 #, c-format msgid "%s: root inode created in AG %u, not AG 0\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2763 +#: .././mkfs/xfs_mkfs.c:3045 #, c-format msgid "Cannot specify both -%c %s and -%c %s\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2774 +#: .././mkfs/xfs_mkfs.c:3056 #, c-format msgid "Illegal value %s for -%s option\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2791 +#: .././mkfs/xfs_mkfs.c:3073 #, c-format msgid "-%c %s option requires a value\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2804 .././repair/xfs_repair.c:162 +#: .././mkfs/xfs_mkfs.c:3086 .././repair/xfs_repair.c:164 #, c-format msgid "option respecified\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2813 .././repair/xfs_repair.c:169 +#: .././mkfs/xfs_mkfs.c:3095 .././repair/xfs_repair.c:171 #, c-format msgid "unknown option -%c %s\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2852 +#: .././mkfs/xfs_mkfs.c:3134 #, c-format msgid "blocksize not available yet.\n" msgstr "" -#: .././mkfs/xfs_mkfs.c:2878 +#: .././mkfs/xfs_mkfs.c:3160 #, c-format msgid "" "Usage: %s\n" "/* blocksize */\t\t[-b log=n|size=num]\n" +"/* metadata */\t\t[-m crc=0|1,finobt=0|1]\n" "/* data subvol */\t[-d agcount=n,agsize=n,file,name=xxx,size=num,\n" -"\t\t\t (sunit=value,swidth=value|su=num,sw=num),\n" +"\t\t\t (sunit=value,swidth=value|su=num,sw=num|noalign),\n" "\t\t\t sectlog=n|sectsize=num\n" +"/* force overwrite */\t[-f]\n" "/* inode size */\t[-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,\n" "\t\t\t projid32bit=0|1]\n" +"/* no discard */\t[-K]\n" "/* log subvol */\t[-l agnum=n,internal,size=num,logdev=xxx,version=n\n" "\t\t\t sunit=value|su=num,sectlog=n|sectsize=num,\n" "\t\t\t lazy-count=0|1]\n" "/* label */\t\t[-L label (maximum 12 characters)]\n" -"/* naming */\t\t[-n log=n|size=num,version=2|ci]\n" +"/* naming */\t\t[-n log=n|size=num,version=2|ci,ftype=0|1]\n" +"/* no-op info only */\t[-N]\n" "/* prototype file */\t[-p fname]\n" "/* quiet */\t\t[-q]\n" "/* realtime subvol */\t[-r extsize=num,size=num,rtdev=xxx]\n" @@ -6789,393 +7035,379 @@ " is xxx (512 byte blocks).\n" msgstr "" -#: .././quota/path.c:39 -#, c-format -msgid "%sFilesystem Pathname\n" -msgstr "" - -#: .././quota/path.c:40 -msgid " " -msgstr "" - -#: .././quota/path.c:43 -#, c-format -msgid "%c%03d%c " -msgstr "" - -#: .././quota/path.c:45 -#, c-format -msgid "%-19s %s" -msgstr "" - -#: .././quota/path.c:48 -#, c-format -msgid " (project %u" -msgstr "" - -#: .././quota/path.c:50 -#, c-format -msgid ", %s" -msgstr "" - -#: .././quota/path.c:103 +#: .././quota/edit.c:36 #, c-format -msgid "No paths are available\n" -msgstr "" - -#: .././quota/path.c:131 -msgid "set current path, or show the list of paths" -msgstr "" - -#: .././quota/path.c:139 -msgid "list known mount points and projects" +msgid "" +"\n" +" modify quota limits for the specified user\n" +"\n" +" Example:\n" +" 'limit bsoft=100m bhard=110m tanya\n" +"\n" +" Changes the soft and/or hard block limits, inode limits and/or realtime\n" +" block limits that are currently being used for the specified user, group,\n" +" or project. The filesystem identified by the current path is modified.\n" +" -d -- set the default values, used the first time a file is created\n" +" -g -- modify group quota limits\n" +" -p -- modify project quota limits\n" +" -u -- modify user quota limits\n" +" The block limit values can be specified with a units suffix - accepted\n" +" units are: k (kilobytes), m (megabytes), g (gigabytes), and t (terabytes).\n" +" The user/group/project can be specified either by name or by number.\n" +"\n" msgstr "" -#: .././quota/project.c:45 +#: .././quota/edit.c:59 #, c-format msgid "" "\n" -" list projects or setup a project tree for tree quota management\n" +" modify quota enforcement timeout for the current filesystem\n" "\n" " Example:\n" -" 'project -c logfiles'\n" -" (match project 'logfiles' to a directory, and setup the directory tree)\n" -"\n" -" Without arguments, report all projects found in the /etc/projects file.\n" -" The project quota mechanism in XFS can be used to implement a form of\n" -" directory tree quota, where a specified directory and all of the files\n" -" and subdirectories below it (i.e. a tree) can be restricted to using a\n" -" subset of the available space in the filesystem.\n" -"\n" -" A managed tree must be setup initially using the -c option with a project.\n" -" The specified project name or identifier is matched to one or more trees\n" -" defined in /etc/projects, and these trees are then recursively descended\n" -" to mark the affected inodes as being part of that tree - which sets inode\n" -" flags and the project identifier on every file.\n" -" Once this has been done, new files created in the tree will automatically\n" -" be accounted to the tree based on their project identifier. An attempt to\n" -" create a hard link to a file in the tree will only succeed if the project\n" -" identifier matches the project identifier for the tree. The xfs_io " -"utility\n" -" can be used to set the project ID for an arbitrary file, but this can only\n" -" be done by a privileged user.\n" +" 'timer -i 3days'\n" +" (soft inode limit timer is changed to 3 days)\n" "\n" -" A previously setup tree can be cleared from project quota control through\n" -" use of the -C option, which will recursively descend the tree, clearing\n" -" the affected inodes from project quota control.\n" +" Changes the timeout value associated with the block limits, inode limits\n" +" and/or realtime block limits for all users, groups, or projects on the\n" +" current filesystem.\n" +" As soon as a user consumes the amount of space or number of inodes set as\n" +" the soft limit, a timer is started. If the timer expires and the user is\n" +" still over the soft limit, the soft limit is enforced as the hard limit.\n" +" The default timeout is 7 days.\n" +" -d -- set the default values, used the first time a file is created\n" +" -g -- modify group quota timer\n" +" -p -- modify project quota timer\n" +" -u -- modify user quota timer\n" +" -b -- modify the blocks-used timer\n" +" -i -- modify the inodes-used timer\n" +" -r -- modify the blocks-used timer for the (optional) realtime subvolume\n" +" The timeout value is specified as a number of seconds, by default.\n" +" However, a suffix may be used to alternatively specify minutes (m),\n" +" hours (h), days (d), or weeks (w) - either the full word or the first\n" +" letter of the word can be used.\n" "\n" -" The -c option can be used to check whether a tree is setup, it reports\n" -" nothing if the tree is correct, otherwise it reports the paths of inodes\n" -" which do not have the project ID of the rest of the tree, or if the inode\n" -" flag is not set.\n" +msgstr "" + +#: .././quota/edit.c:91 +#, c-format +msgid "" "\n" -" The -p option can be used to manually specify project path without\n" -" need to create /etc/projects file. This option can be used multiple times\n" -" to specify multiple paths. When using this option only one projid/name can\n" -" be specified at command line. Note that /etc/projects is also used if " -"exists.\n" +" modify the number of quota warnings sent to the specified user\n" "\n" -" The -d option allows to descend at most levels of " -"directories\n" -" below the command line arguments. -d 0 means only apply the actions\n" -" to the top level of the projects. -d -1 means no recursion limit " -"(default).\n" +" Example:\n" +" 'warn 2 jimmy'\n" +" (tell the quota system that two warnings have been sent to user jimmy)\n" "\n" -" The /etc/projid and /etc/projects file formats are simple, and described\n" -" on the xfs_quota man page.\n" +" Changes the warning count associated with the block limits, inode limits\n" +" and/or realtime block limits for the specified user, group, or project.\n" +" When a user has been warned the maximum number of times allowed, the soft\n" +" limit is enforced as the hard limit. It is intended as an alternative to\n" +" the timeout system, where the system administrator updates a count of the\n" +" number of warnings issued to people, and they are penalised if the " +"warnings\n" +" are ignored.\n" +" -d -- set maximum warning count, which triggers soft limit enforcement\n" +" -g -- set group quota warning count\n" +" -p -- set project quota warning count\n" +" -u -- set user quota warning count\n" +" -b -- set the blocks-used warning count\n" +" -i -- set the inodes-used warning count\n" +" -r -- set the blocks-used warn count for the (optional) realtime subvolume\n" +" The user/group/project can be specified either by name or by number.\n" "\n" msgstr "" -#: .././quota/project.c:108 .././quota/project.c:153 .././quota/project.c:200 +#: .././quota/edit.c:145 #, c-format -msgid "%s: cannot stat file %s\n" +msgid "%s: cannot set limits: %s\n" msgstr "" -#: .././quota/project.c:112 .././quota/project.c:157 .././quota/project.c:204 +#: .././quota/edit.c:166 .././quota/edit.c:569 #, c-format -msgid "%s: skipping special file %s\n" +msgid "%s: invalid user name: %s\n" msgstr "" -#: .././quota/project.c:126 +#: .././quota/edit.c:189 .././quota/edit.c:586 #, c-format -msgid "%s - project identifier is not set (inode=%u, tree=%u)\n" +msgid "%s: invalid group name: %s\n" msgstr "" -#: .././quota/project.c:130 +#: .././quota/edit.c:212 .././quota/edit.c:603 #, c-format -msgid "%s - project inheritance flag is not set\n" +msgid "%s: invalid project name: %s\n" msgstr "" -#: .././quota/project.c:178 +#: .././quota/edit.c:237 #, c-format -msgid "%s: cannot clear project on %s: %s\n" +msgid "%s: Error: could not parse size %s.\n" msgstr "" -#: .././quota/project.c:225 +#: .././quota/edit.c:243 #, c-format -msgid "%s: cannot set project on %s: %s\n" +msgid "%s: Warning: `%s' in quota blocks is 0 (unlimited).\n" msgstr "" -#: .././quota/project.c:240 +#: .././quota/edit.c:332 #, c-format -msgid "Checking project %s (path %s)...\n" +msgid "%s: unrecognised argument %s\n" msgstr "" -#: .././quota/project.c:244 +#: .././quota/edit.c:339 #, c-format -msgid "Setting up project %s (path %s)...\n" +msgid "%s: cannot find any valid arguments\n" msgstr "" -#: .././quota/project.c:248 +#: .././quota/edit.c:447 #, c-format -msgid "Clearing project %s (path %s)...\n" +msgid "%s: fopen on %s failed: %s\n" msgstr "" -#: .././quota/project.c:271 +#: .././quota/edit.c:479 #, c-format -msgid "" -"Processed %d (%s and cmdline) paths for project %s with recursion depth %s (%" -"d).\n" +msgid "%s: cannot set timer: %s\n" msgstr "" -#: .././quota/project.c:274 -msgid "infinite" +#: .././quota/edit.c:553 +#, c-format +msgid "%s: cannot set warnings: %s\n" msgstr "" -#: .././quota/project.c:274 -msgid "limited" +#: .././quota/edit.c:689 +msgid "[-gpu] bsoft|bhard|isoft|ihard|rtbsoft|rtbhard=N -d|id|name" msgstr "" -#: .././quota/project.c:319 -#, c-format -msgid "projects file \"%s\" doesn't exist\n" +#: .././quota/edit.c:690 +msgid "modify quota limits" msgstr "" -#: .././quota/project.c:326 -#, c-format -msgid "" -"%s: only one projid/name can be specified when using -p , %d found.\n" +#: .././quota/edit.c:697 .././quota/report.c:33 .././quota/report.c:647 +msgid "[-gpu] [-f file]" msgstr "" -#: .././quota/project.c:336 -#, c-format -msgid "%s - no such project in %s or invalid project number\n" +#: .././quota/edit.c:698 +msgid "restore quota limits from a backup file" msgstr "" -#: .././quota/project.c:353 -msgid "[-c|-s|-C|-d |-p ] project ..." +#: .././quota/edit.c:704 .././quota/edit.c:712 +msgid "[-bir] [-gpu] value -d|id|name" msgstr "" -#: .././quota/project.c:356 -msgid "check, setup or clear project quota trees" +#: .././quota/edit.c:705 +msgid "get/set quota enforcement timeouts" msgstr "" -#: .././quota/quot.c:55 +#: .././quota/edit.c:713 +msgid "get/set enforcement warning counter" +msgstr "" + +#: .././quota/free.c:29 #, c-format msgid "" "\n" -" display a summary of filesystem ownership\n" +" reports the number of free disk blocks and inodes\n" "\n" -" -a -- summarise for all local XFS filesystem mount points\n" -" -c -- display three columns giving file size in kilobytes, number of files\n" -" of that size, and cumulative total of kilobytes in that size or\n" -" smaller file. The last row is used as an overflow bucket and is the\n" -" total of all files greater than 500 kilobytes.\n" -" -v -- display three columns containing the number of kilobytes not\n" -" accessed in the last 30, 60, and 90 days.\n" -" -g -- display group summary\n" -" -p -- display project summary\n" -" -u -- display user summary\n" -" -b -- display number of blocks used\n" -" -i -- display number of inodes used\n" -" -r -- display number of realtime blocks used\n" -" -n -- skip identifier-to-name translations, just report IDs\n" -" -N -- suppress the initial header\n" -" -f -- send output to a file\n" -" The (optional) user/group/project can be specified either by name or by\n" -" number (i.e. uid/gid/projid).\n" +" This command reports the number of total, used, and available disk blocks.\n" +" It can optionally report the same set of numbers for inodes and realtime\n" +" disk blocks, and will report on all known XFS filesystem mount points and\n" +" project quota paths by default (see 'print' command for a list).\n" +" -b -- report the block count values\n" +" -i -- report the inode count values\n" +" -r -- report the realtime block count values\n" +" -h -- report in a human-readable format\n" +" -N -- suppress the header from the output\n" "\n" msgstr "" -#: .././quota/quot.c:219 +#: .././quota/free.c:154 #, c-format -msgid "%s (%s) %s:\n" +msgid "%s: project quota flag not set on %s\n" msgstr "" -#: .././quota/quot.c:295 +#: .././quota/free.c:163 #, c-format -msgid "%s (%s):\n" +msgid "%s: project ID %u (%s) doesn't match ID %u (%s)\n" msgstr "" -#: .././quota/quot.c:300 .././quota/quot.c:304 +#: .././quota/free.c:230 #, c-format -msgid "%d\t%llu\t%llu\n" -msgstr "" - -#: .././quota/quot.c:418 -msgid "[-bir] [-gpu] [-acv] [-f file]" -msgstr "" - -#: .././quota/quot.c:419 -msgid "summarize filesystem ownership" +msgid "Filesystem " msgstr "" -#: .././quota/quota.c:32 +#: .././quota/free.c:230 #, c-format -msgid "" -"\n" -" display usage and quota information\n" -"\n" -" -g -- display group quota information\n" -" -p -- display project quota information\n" -" -u -- display user quota information\n" -" -b -- display number of blocks used\n" -" -i -- display number of inodes used\n" -" -r -- display number of realtime blocks used\n" -" -h -- report in a human-readable format\n" -" -n -- skip identifier-to-name translations, just report IDs\n" -" -N -- suppress the initial header\n" -" -v -- increase verbosity in reporting (also dumps zero values)\n" -" -f -- send output to a file\n" -" The (optional) user/group/project can be specified either by name or by\n" -" number (i.e. uid/gid/projid).\n" -"\n" +msgid "Filesystem " msgstr "" -#: .././quota/quota.c:85 +#: .././quota/free.c:233 #, c-format -msgid "" -"Disk quotas for %s %s (%u)\n" -"Filesystem%s" +msgid " Size Used Avail Use%%" msgstr "" -#: .././quota/quota.c:90 +#: .././quota/free.c:234 #, c-format -msgid " Blocks Quota Limit Warn/Time " +msgid " 1K-blocks Used Available Use%%" msgstr "" -#: .././quota/quota.c:91 +#: .././quota/free.c:237 #, c-format -msgid " Blocks Quota Limit Warn/Time " +msgid " Inodes Used Free Use%%" msgstr "" -#: .././quota/quota.c:94 +#: .././quota/free.c:238 #, c-format -msgid " Files Quota Limit Warn/Time " +msgid " Inodes IUsed IFree IUse%%" msgstr "" -#: .././quota/quota.c:95 +#: .././quota/free.c:239 #, c-format -msgid " Files Quota Limit Warn/Time " +msgid " Pathname\n" msgstr "" -#: .././quota/quota.c:98 -#, c-format -msgid "Realtime Quota Limit Warn/Time " +#: .././quota/free.c:371 +msgid "[-bir] [-hn] [-f file]" msgstr "" -#: .././quota/quota.c:99 -#, c-format -msgid " Realtime Quota Limit Warn/Time " +#: .././quota/free.c:372 +msgid "show free and used counts for blocks and inodes" msgstr "" -#: .././quota/quota.c:235 +#: .././quota/project.c:45 #, c-format -msgid "%s: cannot find user %s\n" +msgid "" +"\n" +" list projects or setup a project tree for tree quota management\n" +"\n" +" Example:\n" +" 'project -c logfiles'\n" +" (match project 'logfiles' to a directory, and setup the directory tree)\n" +"\n" +" Without arguments, report all projects found in the /etc/projects file.\n" +" The project quota mechanism in XFS can be used to implement a form of\n" +" directory tree quota, where a specified directory and all of the files\n" +" and subdirectories below it (i.e. a tree) can be restricted to using a\n" +" subset of the available space in the filesystem.\n" +"\n" +" A managed tree must be setup initially using the -c option with a project.\n" +" The specified project name or identifier is matched to one or more trees\n" +" defined in /etc/projects, and these trees are then recursively descended\n" +" to mark the affected inodes as being part of that tree - which sets inode\n" +" flags and the project identifier on every file.\n" +" Once this has been done, new files created in the tree will automatically\n" +" be accounted to the tree based on their project identifier. An attempt to\n" +" create a hard link to a file in the tree will only succeed if the project\n" +" identifier matches the project identifier for the tree. The xfs_io " +"utility\n" +" can be used to set the project ID for an arbitrary file, but this can only\n" +" be done by a privileged user.\n" +"\n" +" A previously setup tree can be cleared from project quota control through\n" +" use of the -C option, which will recursively descend the tree, clearing\n" +" the affected inodes from project quota control.\n" +"\n" +" The -c option can be used to check whether a tree is setup, it reports\n" +" nothing if the tree is correct, otherwise it reports the paths of inodes\n" +" which do not have the project ID of the rest of the tree, or if the inode\n" +" flag is not set.\n" +"\n" +" The -p option can be used to manually specify project path without\n" +" need to create /etc/projects file. This option can be used multiple times\n" +" to specify multiple paths. When using this option only one projid/name can\n" +" be specified at command line. Note that /etc/projects is also used if " +"exists.\n" +"\n" +" The -d option allows to descend at most levels of " +"directories\n" +" below the command line arguments. -d 0 means only apply the actions\n" +" to the top level of the projects. -d -1 means no recursion limit " +"(default).\n" +"\n" +" The /etc/projid and /etc/projects file formats are simple, and described\n" +" on the xfs_quota man page.\n" +"\n" msgstr "" -#: .././quota/quota.c:285 +#: .././quota/project.c:108 .././quota/project.c:153 .././quota/project.c:200 #, c-format -msgid "%s: cannot find group %s\n" +msgid "%s: cannot stat file %s\n" msgstr "" -#: .././quota/quota.c:342 +#: .././quota/project.c:112 .././quota/project.c:157 .././quota/project.c:204 #, c-format -msgid "%s: must specify a project name/ID\n" +msgid "%s: skipping special file %s\n" msgstr "" -#: .././quota/quota.c:355 +#: .././quota/project.c:126 #, c-format -msgid "%s: cannot find project %s\n" +msgid "%s - project identifier is not set (inode=%u, tree=%u)\n" msgstr "" -#: .././quota/quota.c:460 -msgid "[-bir] [-gpu] [-hnNv] [-f file] [id|name]..." +#: .././quota/project.c:130 +#, c-format +msgid "%s - project inheritance flag is not set\n" msgstr "" -#: .././quota/quota.c:461 -msgid "show usage and limits" +#: .././quota/project.c:178 +#, c-format +msgid "%s: cannot clear project on %s: %s\n" msgstr "" -#: .././quota/free.c:29 +#: .././quota/project.c:225 #, c-format -msgid "" -"\n" -" reports the number of free disk blocks and inodes\n" -"\n" -" This command reports the number of total, used, and available disk blocks.\n" -" It can optionally report the same set of numbers for inodes and realtime\n" -" disk blocks, and will report on all known XFS filesystem mount points and\n" -" project quota paths by default (see 'print' command for a list).\n" -" -b -- report the block count values\n" -" -i -- report the inode count values\n" -" -r -- report the realtime block count values\n" -" -h -- report in a human-readable format\n" -" -N -- suppress the header from the output\n" -"\n" +msgid "%s: cannot set project on %s: %s\n" msgstr "" -#: .././quota/free.c:154 +#: .././quota/project.c:240 #, c-format -msgid "%s: project quota flag not set on %s\n" +msgid "Checking project %s (path %s)...\n" msgstr "" -#: .././quota/free.c:163 +#: .././quota/project.c:244 #, c-format -msgid "%s: project ID %u (%s) doesn't match ID %u (%s)\n" +msgid "Setting up project %s (path %s)...\n" msgstr "" -#: .././quota/free.c:230 +#: .././quota/project.c:248 #, c-format -msgid "Filesystem " +msgid "Clearing project %s (path %s)...\n" msgstr "" -#: .././quota/free.c:230 +#: .././quota/project.c:271 #, c-format -msgid "Filesystem " +msgid "" +"Processed %d (%s and cmdline) paths for project %s with recursion depth %s " +"(%d).\n" msgstr "" -#: .././quota/free.c:233 -#, c-format -msgid " Size Used Avail Use%%" +#: .././quota/project.c:274 +msgid "infinite" msgstr "" -#: .././quota/free.c:234 -#, c-format -msgid " 1K-blocks Used Available Use%%" +#: .././quota/project.c:274 +msgid "limited" msgstr "" -#: .././quota/free.c:237 +#: .././quota/project.c:319 #, c-format -msgid " Inodes Used Free Use%%" +msgid "projects file \"%s\" doesn't exist\n" msgstr "" -#: .././quota/free.c:238 +#: .././quota/project.c:326 #, c-format -msgid " Inodes IUsed IFree IUse%%" +msgid "" +"%s: only one projid/name can be specified when using -p , %d found.\n" msgstr "" -#: .././quota/free.c:239 +#: .././quota/project.c:336 #, c-format -msgid " Pathname\n" +msgid "%s - no such project in %s or invalid project number\n" msgstr "" -#: .././quota/free.c:371 -msgid "[-bir] [-hn] [-f file]" +#: .././quota/project.c:353 +msgid "[-c|-s|-C|-d |-p ] project ..." msgstr "" -#: .././quota/free.c:372 -msgid "show free and used counts for blocks and inodes" +#: .././quota/project.c:356 +msgid "check, setup or clear project quota trees" msgstr "" #: .././quota/state.c:33 @@ -7390,174 +7622,188 @@ msgid "%s: fdopen on %s failed: %s\n" msgstr "" -#: .././quota/edit.c:36 +#: .././quota/init.c:48 #, c-format -msgid "" -"\n" -" modify quota limits for the specified user\n" -"\n" -" Example:\n" -" 'limit bsoft=100m bhard=110m tanya\n" -"\n" -" Changes the soft and/or hard block limits, inode limits and/or realtime\n" -" block limits that are currently being used for the specified user, group,\n" -" or project. The filesystem identified by the current path is modified.\n" -" -d -- set the default values, used the first time a file is created\n" -" -g -- modify group quota limits\n" -" -p -- modify project quota limits\n" -" -u -- modify user quota limits\n" -" The block limit values can be specified with a units suffix - accepted\n" -" units are: k (kilobytes), m (megabytes), g (gigabytes), and t (terabytes).\n" -" The user/group/project can be specified either by name or by number.\n" -"\n" +msgid "Usage: %s [-V] [-x] [-p prog] [-c cmd]... [-d project]... [path]\n" msgstr "" -#: .././quota/edit.c:59 +#: .././quota/path.c:39 #, c-format -msgid "" -"\n" -" modify quota enforcement timeout for the current filesystem\n" -"\n" -" Example:\n" -" 'timer -i 3days'\n" -" (soft inode limit timer is changed to 3 days)\n" -"\n" -" Changes the timeout value associated with the block limits, inode limits\n" -" and/or realtime block limits for all users, groups, or projects on the\n" -" current filesystem.\n" -" As soon as a user consumes the amount of space or number of inodes set as\n" -" the soft limit, a timer is started. If the timer expires and the user is\n" -" still over the soft limit, the soft limit is enforced as the hard limit.\n" -" The default timeout is 7 days.\n" -" -d -- set the default values, used the first time a file is created\n" -" -g -- modify group quota timer\n" -" -p -- modify project quota timer\n" -" -u -- modify user quota timer\n" -" -b -- modify the blocks-used timer\n" -" -i -- modify the inodes-used timer\n" -" -r -- modify the blocks-used timer for the (optional) realtime subvolume\n" -" The timeout value is specified as a number of seconds, by default.\n" -" However, a suffix may be used to alternatively specify minutes (m),\n" -" hours (h), days (d), or weeks (w) - either the full word or the first\n" -" letter of the word can be used.\n" -"\n" +msgid "%sFilesystem Pathname\n" msgstr "" -#: .././quota/edit.c:91 +#: .././quota/path.c:40 +msgid " " +msgstr "" + +#: .././quota/path.c:43 +#, c-format +msgid "%c%03d%c " +msgstr "" + +#: .././quota/path.c:45 +#, c-format +msgid "%-19s %s" +msgstr "" + +#: .././quota/path.c:48 +#, c-format +msgid " (project %u" +msgstr "" + +#: .././quota/path.c:50 +#, c-format +msgid ", %s" +msgstr "" + +#: .././quota/path.c:103 +#, c-format +msgid "No paths are available\n" +msgstr "" + +#: .././quota/path.c:131 +msgid "set current path, or show the list of paths" +msgstr "" + +#: .././quota/path.c:139 +msgid "list known mount points and projects" +msgstr "" + +#: .././quota/quot.c:55 #, c-format msgid "" "\n" -" modify the number of quota warnings sent to the specified user\n" -"\n" -" Example:\n" -" 'warn 2 jimmy'\n" -" (tell the quota system that two warnings have been sent to user jimmy)\n" +" display a summary of filesystem ownership\n" "\n" -" Changes the warning count associated with the block limits, inode limits\n" -" and/or realtime block limits for the specified user, group, or project.\n" -" When a user has been warned the maximum number of times allowed, the soft\n" -" limit is enforced as the hard limit. It is intended as an alternative to\n" -" the timeout system, where the system administrator updates a count of the\n" -" number of warnings issued to people, and they are penalised if the " -"warnings\n" -" are ignored.\n" -" -d -- set maximum warning count, which triggers soft limit enforcement\n" -" -g -- set group quota warning count\n" -" -p -- set project quota warning count\n" -" -u -- set user quota warning count\n" -" -b -- set the blocks-used warning count\n" -" -i -- set the inodes-used warning count\n" -" -r -- set the blocks-used warn count for the (optional) realtime subvolume\n" -" The user/group/project can be specified either by name or by number.\n" +" -a -- summarise for all local XFS filesystem mount points\n" +" -c -- display three columns giving file size in kilobytes, number of files\n" +" of that size, and cumulative total of kilobytes in that size or\n" +" smaller file. The last row is used as an overflow bucket and is the\n" +" total of all files greater than 500 kilobytes.\n" +" -v -- display three columns containing the number of kilobytes not\n" +" accessed in the last 30, 60, and 90 days.\n" +" -g -- display group summary\n" +" -p -- display project summary\n" +" -u -- display user summary\n" +" -b -- display number of blocks used\n" +" -i -- display number of inodes used\n" +" -r -- display number of realtime blocks used\n" +" -n -- skip identifier-to-name translations, just report IDs\n" +" -N -- suppress the initial header\n" +" -f -- send output to a file\n" +" The (optional) user/group/project can be specified either by name or by\n" +" number (i.e. uid/gid/projid).\n" "\n" msgstr "" -#: .././quota/edit.c:145 +#: .././quota/quot.c:220 #, c-format -msgid "%s: cannot set limits: %s\n" +msgid "%s (%s) %s:\n" msgstr "" -#: .././quota/edit.c:166 .././quota/edit.c:569 +#: .././quota/quot.c:296 #, c-format -msgid "%s: invalid user name: %s\n" +msgid "%s (%s):\n" msgstr "" -#: .././quota/edit.c:189 .././quota/edit.c:586 +#: .././quota/quot.c:301 .././quota/quot.c:305 #, c-format -msgid "%s: invalid group name: %s\n" +msgid "%d\t%llu\t%llu\n" msgstr "" -#: .././quota/edit.c:212 .././quota/edit.c:603 -#, c-format -msgid "%s: invalid project name: %s\n" +#: .././quota/quot.c:419 +msgid "[-bir] [-gpu] [-acv] [-f file]" msgstr "" -#: .././quota/edit.c:237 -#, c-format -msgid "%s: Error: could not parse size %s.\n" +#: .././quota/quot.c:420 +msgid "summarize filesystem ownership" msgstr "" -#: .././quota/edit.c:243 +#: .././quota/quota.c:32 #, c-format -msgid "%s: Warning: `%s' in quota blocks is 0 (unlimited).\n" +msgid "" +"\n" +" display usage and quota information\n" +"\n" +" -g -- display group quota information\n" +" -p -- display project quota information\n" +" -u -- display user quota information\n" +" -b -- display number of blocks used\n" +" -i -- display number of inodes used\n" +" -r -- display number of realtime blocks used\n" +" -h -- report in a human-readable format\n" +" -n -- skip identifier-to-name translations, just report IDs\n" +" -N -- suppress the initial header\n" +" -v -- increase verbosity in reporting (also dumps zero values)\n" +" -f -- send output to a file\n" +" The (optional) user/group/project can be specified either by name or by\n" +" number (i.e. uid/gid/projid).\n" +"\n" msgstr "" -#: .././quota/edit.c:332 +#: .././quota/quota.c:85 #, c-format -msgid "%s: unrecognised argument %s\n" +msgid "" +"Disk quotas for %s %s (%u)\n" +"Filesystem%s" msgstr "" -#: .././quota/edit.c:339 +#: .././quota/quota.c:90 #, c-format -msgid "%s: cannot find any valid arguments\n" +msgid " Blocks Quota Limit Warn/Time " msgstr "" -#: .././quota/edit.c:447 +#: .././quota/quota.c:91 #, c-format -msgid "%s: fopen on %s failed: %s\n" +msgid " Blocks Quota Limit Warn/Time " msgstr "" -#: .././quota/edit.c:479 +#: .././quota/quota.c:94 #, c-format -msgid "%s: cannot set timer: %s\n" +msgid " Files Quota Limit Warn/Time " msgstr "" -#: .././quota/edit.c:553 +#: .././quota/quota.c:95 #, c-format -msgid "%s: cannot set warnings: %s\n" +msgid " Files Quota Limit Warn/Time " msgstr "" -#: .././quota/edit.c:689 -msgid "[-gpu] bsoft|bhard|isoft|ihard|rtbsoft|rtbhard=N -d|id|name" +#: .././quota/quota.c:98 +#, c-format +msgid "Realtime Quota Limit Warn/Time " msgstr "" -#: .././quota/edit.c:690 -msgid "modify quota limits" +#: .././quota/quota.c:99 +#, c-format +msgid " Realtime Quota Limit Warn/Time " msgstr "" -#: .././quota/edit.c:697 .././quota/report.c:33 .././quota/report.c:647 -msgid "[-gpu] [-f file]" +#: .././quota/quota.c:235 +#, c-format +msgid "%s: cannot find user %s\n" msgstr "" -#: .././quota/edit.c:698 -msgid "restore quota limits from a backup file" +#: .././quota/quota.c:285 +#, c-format +msgid "%s: cannot find group %s\n" msgstr "" -#: .././quota/edit.c:704 .././quota/edit.c:712 -msgid "[-bir] [-gpu] value -d|id|name" +#: .././quota/quota.c:346 +#, c-format +msgid "%s: must specify a project name/ID\n" msgstr "" -#: .././quota/edit.c:705 -msgid "get/set quota enforcement timeouts" +#: .././quota/quota.c:359 +#, c-format +msgid "%s: cannot find project %s\n" msgstr "" -#: .././quota/edit.c:713 -msgid "get/set enforcement warning counter" +#: .././quota/quota.c:464 +msgid "[-bir] [-gpu] [-hnNv] [-f file] [id|name]..." msgstr "" -#: .././quota/init.c:48 -#, c-format -msgid "Usage: %s [-p prog] [-c cmd]... [-d project]... [path]\n" +#: .././quota/quota.c:465 +msgid "show usage and limits" msgstr "" #: .././quota/report.c:34 .././quota/report.c:648 @@ -7640,2798 +7886,2540 @@ msgid "[-bir] [-gpu] [-ahnt] [-f file]" msgstr "" -#: .././repair/init.c:47 -#, c-format -msgid "getrlimit(RLIMIT_FSIZE) failed!\n" -msgstr "" - -#: .././repair/init.c:55 -#, c-format -msgid "setrlimit failed - current: %lld, max: %lld\n" -msgstr "" - -#: .././repair/init.c:102 -msgid "couldn't initialize XFS library\n" -msgstr "" - -#: .././repair/sb.c:100 -msgid "" -"\n" -"attempting to find secondary superblock...\n" -msgstr "" - -#: .././repair/sb.c:105 -msgid "error finding secondary superblock -- failed to memalign buffer\n" -msgstr "" - -#: .././repair/sb.c:142 -msgid "found candidate secondary superblock...\n" -msgstr "" - -#: .././repair/sb.c:154 -msgid "verified secondary superblock...\n" -msgstr "" - -#: .././repair/sb.c:159 -msgid "unable to verify superblock, continuing...\n" -msgstr "" - -#: .././repair/sb.c:457 -msgid "failed to memalign superblock buffer\n" -msgstr "" - -#: .././repair/sb.c:464 -msgid "couldn't seek to offset 0 in filesystem\n" -msgstr "" - -#: .././repair/sb.c:472 -msgid "primary superblock write failed!\n" -msgstr "" - -#: .././repair/sb.c:490 -#, c-format -msgid "error reading superblock %u -- failed to memalign buffer\n" -msgstr "" - -#: .././repair/sb.c:500 -#, c-format -msgid "error reading superblock %u -- seek to offset % failed\n" -msgstr "" - -#: .././repair/sb.c:508 -#, c-format -msgid "superblock read failed, offset %, size %d, ag %u, rval %d\n" -msgstr "" - -#: .././repair/sb.c:554 -msgid "couldn't malloc geometry structure\n" -msgstr "" - -#: .././repair/sb.c:706 -msgid "calloc failed in verify_set_primary_sb\n" -msgstr "" - -#: .././repair/sb.c:777 -msgid "" -"Only two AGs detected and they do not match - cannot validate filesystem " -"geometry.\n" -"Use the -o force_geometry option to proceed.\n" -msgstr "" - -#: .././repair/sb.c:793 -msgid "" -"Only one AG detected - cannot validate filesystem geometry.\n" -"Use the -o force_geometry option to proceed.\n" -msgstr "" - -#: .././repair/sb.c:808 -msgid "Not enough matching superblocks - cannot proceed.\n" -msgstr "" - -#: .././repair/sb.c:823 -msgid "could not read superblock\n" -msgstr "" - -#: .././repair/rt.c:47 -msgid "couldn't allocate memory for incore realtime bitmap.\n" -msgstr "" - -#: .././repair/rt.c:51 -msgid "couldn't allocate memory for incore realtime summary info.\n" -msgstr "" - -#: .././repair/rt.c:203 -#, c-format -msgid "can't find block %d for rtbitmap inode\n" -msgstr "" - -#: .././repair/rt.c:211 -#, c-format -msgid "can't read block %d for rtbitmap inode\n" -msgstr "" - -#: .././repair/rt.c:265 -#, c-format -msgid "block %d for rtsummary inode is missing\n" -msgstr "" - -#: .././repair/rt.c:273 -#, c-format -msgid "can't read block %d for rtsummary inode\n" -msgstr "" - -#: .././repair/agheader.c:35 -#, c-format -msgid "bad magic # 0x%x for agf %d\n" -msgstr "" - -#: .././repair/agheader.c:44 -#, c-format -msgid "bad version # %d for agf %d\n" -msgstr "" - -#: .././repair/agheader.c:53 -#, c-format -msgid "bad sequence # %d for agf %d\n" -msgstr "" - -#: .././repair/agheader.c:63 +#: .././repair/avl.c:1011 .././repair/avl64.c:1032 #, c-format -msgid "bad length %d for agf %d, should be %d\n" +msgid "avl_insert: Warning! duplicate range [%llu,%llu]\n" msgstr "" -#: .././repair/agheader.c:76 +#: .././repair/avl.c:1206 .././repair/avl64.c:1227 #, c-format -msgid "bad length %d for agf %d, should be %\n" +msgid "Command [fpdir] : " msgstr "" -#: .././repair/agheader.c:90 +#: .././repair/avl.c:1215 .././repair/avl64.c:1236 #, c-format -msgid "flfirst %d in agf %d too large (max = %zu)\n" +msgid "end of range ? " msgstr "" -#: .././repair/agheader.c:98 +#: .././repair/avl.c:1226 .././repair/avl64.c:1247 #, c-format -msgid "fllast %d in agf %d too large (max = %zu)\n" +msgid "Cannot find %d\n" msgstr "" -#: .././repair/agheader.c:120 +#: .././repair/avl.c:1239 .././repair/avl64.c:1260 #, c-format -msgid "bad magic # 0x%x for agi %d\n" +msgid "size of range ? " msgstr "" -#: .././repair/agheader.c:129 +#: .././repair/avl.c:1250 .././repair/avl64.c:1271 #, c-format -msgid "bad version # %d for agi %d\n" +msgid "End of range ? " msgstr "" -#: .././repair/agheader.c:138 +#: .././repair/avl.c:1254 .././repair/avl64.c:1275 #, c-format -msgid "bad sequence # %d for agi %d\n" +msgid "checklen 0/1 ? " msgstr "" -#: .././repair/agheader.c:148 +#: .././repair/avl.c:1261 .././repair/avl64.c:1282 #, c-format -msgid "bad length # %d for agi %d, should be %d\n" +msgid "Found something\n" msgstr "" -#: .././repair/agheader.c:161 +#: .././repair/init.c:46 #, c-format -msgid "bad length # %d for agi %d, should be %\n" +msgid "getrlimit(RLIMIT_FSIZE) failed!\n" msgstr "" -#: .././repair/agheader.c:271 +#: .././repair/init.c:54 #, c-format -msgid "zeroing unused portion of %s superblock (AG #%u)\n" -msgstr "" - -#: .././repair/agheader.c:272 .././repair/agheader.c:278 -msgid "primary" -msgstr "" - -#: .././repair/agheader.c:272 .././repair/agheader.c:278 -msgid "secondary" +msgid "setrlimit failed - current: %lld, max: %lld\n" msgstr "" -#: .././repair/agheader.c:277 +#: .././repair/init.c:107 #, c-format -msgid "would zero unused portion of %s superblock (AG #%u)\n" +msgid "" +"Unmount or use the dangerous (-d) option to repair a read-only mounted " +"filesystem\n" msgstr "" -#: .././repair/agheader.c:296 -#, c-format -msgid "bad flags field in superblock %d\n" +#: .././repair/init.c:109 +msgid "couldn't initialize XFS library\n" msgstr "" -#: .././repair/agheader.c:313 -#, c-format -msgid "non-null user quota inode field in superblock %d\n" +#: .././repair/incore_ext.c:135 .././repair/incore_ext.c:562 +msgid "couldn't allocate new extent descriptor.\n" msgstr "" -#: .././repair/agheader.c:326 -#, c-format -msgid "non-null group quota inode field in superblock %d\n" +#: .././repair/incore_ext.c:232 +msgid "duplicate bno extent range\n" msgstr "" -#: .././repair/agheader.c:338 -#, c-format -msgid "non-null quota flags in superblock %d\n" +#: .././repair/incore_ext.c:369 +msgid ": duplicate bno extent range\n" msgstr "" -#: .././repair/agheader.c:356 -#, c-format -msgid "bad shared version number in superblock %d\n" +#: .././repair/incore_ext.c:644 .././repair/incore_ext.c:699 +msgid "duplicate extent range\n" msgstr "" -#: .././repair/agheader.c:368 -#, c-format -msgid "bad inode alignment field in superblock %d\n" +#: .././repair/incore_ext.c:752 .././repair/incore_ext.c:756 +msgid "couldn't malloc dup extent tree descriptor table\n" msgstr "" -#: .././repair/agheader.c:381 -#, c-format -msgid "bad stripe unit/width fields in superblock %d\n" +#: .././repair/incore_ext.c:761 +msgid "couldn't malloc free by-bno extent tree descriptor table\n" msgstr "" -#: .././repair/agheader.c:399 -#, c-format -msgid "bad log/data device sector size fields in superblock %d\n" +#: .././repair/incore_ext.c:766 +msgid "couldn't malloc free by-bcnt extent tree descriptor table\n" msgstr "" -#: .././repair/agheader.c:430 -#, c-format -msgid "bad on-disk superblock %d - %s\n" +#: .././repair/incore_ext.c:772 +msgid "couldn't malloc bno extent tree descriptor\n" msgstr "" -#: .././repair/agheader.c:437 -#, c-format -msgid "primary/secondary superblock %d conflict - %s\n" +#: .././repair/incore_ext.c:776 +msgid "couldn't malloc bcnt extent tree descriptor\n" msgstr "" -#: .././repair/dir.c:152 -#, c-format -msgid "invalid inode number % in directory %\n" +#: .././repair/incore_ext.c:787 +msgid "couldn't malloc dup rt extent tree descriptor\n" msgstr "" -#: .././repair/dir.c:157 +#: .././repair/phase4.c:139 .././repair/phase6.c:3059 .././repair/phase3.c:76 +#: .././repair/phase5.c:1525 #, c-format -msgid "entry in shortform dir % references rt bitmap inode %\n" +msgid " - agno = %d\n" msgstr "" -#: .././repair/dir.c:162 -#, c-format -msgid "" -"entry in shortform dir % references rt summary inode %\n" +#: .././repair/phase4.c:174 +msgid "Phase 4 - check for duplicate blocks...\n" msgstr "" -#: .././repair/dir.c:167 -#, c-format -msgid "" -"entry in shortform dir % references user quota inode %\n" +#: .././repair/phase4.c:175 +msgid " - setting up duplicate extent list...\n" msgstr "" -#: .././repair/dir.c:172 -#, c-format -msgid "" -"entry in shortform dir % references group quota inode %\n" +#: .././repair/phase4.c:189 +msgid "root inode would be lost\n" msgstr "" -#: .././repair/dir.c:193 -#, c-format -msgid "" -"entry references free inode % in shortform directory %\n" +#: .././repair/phase4.c:191 +msgid "root inode lost\n" msgstr "" -#: .././repair/dir.c:212 +#: .././repair/phase4.c:208 #, c-format -msgid "" -"entry references non-existent inode % in shortform dir %\n" +msgid "unknown block state, ag %d, block %d\n" msgstr "" -#: .././repair/dir.c:236 .././repair/dir2.c:995 +#: .././repair/phase4.c:241 #, c-format -msgid "zero length entry in shortform dir %, resetting to %d\n" +msgid "unknown rt extent state, extent %\n" msgstr "" -#: .././repair/dir.c:241 .././repair/dir2.c:1000 -#, c-format -msgid "zero length entry in shortform dir %, would set to %d\n" +#: .././repair/phase4.c:290 +msgid " - check for inodes claiming duplicate blocks...\n" msgstr "" -#: .././repair/dir.c:246 -#, c-format -msgid "zero length entry in shortform dir %, " +#: .././repair/progress.c:16 +msgid "inodes" msgstr "" -#: .././repair/dir.c:249 .././repair/dir.c:292 .././repair/dir2.c:1051 -#, c-format -msgid "junking %d entries\n" +#: .././repair/progress.c:20 +msgid "directories" msgstr "" -#: .././repair/dir.c:252 .././repair/dir.c:301 .././repair/dir2.c:1060 -#, c-format -msgid "would junk %d entries\n" +#: .././repair/progress.c:22 +msgid "allocation groups" msgstr "" -#: .././repair/dir.c:270 .././repair/dir2.c:1029 -#, c-format -msgid "size of last entry overflows space left in in shortform dir %, " +#: .././repair/progress.c:24 +msgid "AGI unlinked buckets" msgstr "" -#: .././repair/dir.c:273 .././repair/dir2.c:1032 -#, c-format -msgid "resetting to %d\n" +#: .././repair/progress.c:28 +msgid "realtime extents" msgstr "" -#: .././repair/dir.c:278 .././repair/dir2.c:1037 -#, c-format -msgid "would reset to %d\n" +#: .././repair/progress.c:30 +msgid "unlinked lists" msgstr "" -#: .././repair/dir.c:283 .././repair/dir2.c:1042 +#: .././repair/progress.c:37 #, c-format -msgid "size of entry #%d overflows space left in in shortform dir %\n" +msgid " - %02d:%02d:%02d: %s - %llu of %llu %s done\n" msgstr "" -#: .././repair/dir.c:288 .././repair/dir2.c:1047 +#: .././repair/progress.c:39 #, c-format -msgid "junking entry #%d\n" +msgid " - %02d:%02d:%02d: %s - %llu %s done\n" msgstr "" -#: .././repair/dir.c:297 .././repair/dir2.c:1056 -#, c-format -msgid "would junk entry #%d\n" +#: .././repair/progress.c:51 +msgid "scanning filesystem freespace" msgstr "" -#: .././repair/dir.c:320 .././repair/dir2.c:1079 -#, c-format -msgid "entry contains illegal character in shortform dir %\n" +#: .././repair/progress.c:53 +msgid "scanning agi unlinked lists" msgstr "" -#: .././repair/dir.c:374 .././repair/dir2.c:1143 -#, c-format -msgid "junking entry \"%s\" in directory inode %\n" +#: .././repair/progress.c:55 +msgid "check uncertain AG inodes" msgstr "" -#: .././repair/dir.c:378 .././repair/dir2.c:1147 -#, c-format -msgid "would have junked entry \"%s\" in directory inode %\n" +#: .././repair/progress.c:57 +msgid "process known inodes and inode discovery" msgstr "" -#: .././repair/dir.c:404 .././repair/dir2.c:1174 -#, c-format -msgid "would have corrected entry count in directory % from %d to %d\n" +#: .././repair/progress.c:59 +msgid "process newly discovered inodes" msgstr "" -#: .././repair/dir.c:408 .././repair/dir2.c:1178 -#, c-format -msgid "corrected entry count in directory %, was %d, now %d\n" +#: .././repair/progress.c:61 +msgid "setting up duplicate extent list" msgstr "" -#: .././repair/dir.c:419 -#, c-format -msgid "" -"would have corrected directory % size from %to %\n" +#: .././repair/progress.c:63 +msgid "initialize realtime bitmap" msgstr "" -#: .././repair/dir.c:424 .././repair/dir2.c:1212 -#, c-format -msgid "corrected directory % size, was %, now %\n" +#: .././repair/progress.c:65 +msgid "reset realtime bitmaps" msgstr "" -#: .././repair/dir.c:446 .././repair/dir2.c:1253 -#, c-format -msgid "bogus .. inode number (%) in directory inode %, " +#: .././repair/progress.c:67 +msgid "check for inodes claiming duplicate blocks" msgstr "" -#: .././repair/dir.c:449 .././repair/dir.c:483 .././repair/dir2.c:1257 -#: .././repair/dir2.c:1292 -msgid "clearing inode number\n" +#: .././repair/progress.c:69 +msgid "rebuild AG headers and trees" msgstr "" -#: .././repair/dir.c:455 .././repair/dir.c:489 .././repair/dir2.c:1263 -#: .././repair/dir2.c:1298 -msgid "would clear inode number\n" +#: .././repair/progress.c:71 +msgid "traversing filesystem" msgstr "" -#: .././repair/dir.c:463 .././repair/dir2.c:1271 -#, c-format -msgid "" -"corrected root directory % .. entry, was %, now %\n" +#: .././repair/progress.c:73 +msgid "traversing all unattached subtrees" msgstr "" -#: .././repair/dir.c:471 .././repair/dir2.c:1279 -#, c-format -msgid "" -"would have corrected root directory % .. entry from % to %" -"\n" +#: .././repair/progress.c:75 +msgid "moving disconnected inodes to lost+found" msgstr "" -#: .././repair/dir.c:480 -#, c-format -msgid "bad .. entry in dir ino %, points to self, " +#: .././repair/progress.c:77 +msgid "verify and correct link counts" msgstr "" -#: .././repair/dir.c:524 -#, c-format -msgid "bad range claimed [%d, %d) in da block\n" +#: .././repair/progress.c:79 +msgid "verify link counts" msgstr "" -#: .././repair/dir.c:531 -#, c-format -msgid "byte range end [%d %d) in da block larger than blocksize %d\n" +#: .././repair/progress.c:118 +msgid "cannot malloc pointer to done vector\n" msgstr "" -#: .././repair/dir.c:538 -#, c-format -msgid "multiply claimed byte %d in da block\n" +#: .././repair/progress.c:135 +msgid "unable to create progress report thread\n" msgstr "" -#: .././repair/dir.c:568 -#, c-format -msgid "hole (start %d, len %d) out of range, block %d, dir ino %\n" +#: .././repair/progress.c:178 +msgid "progress_rpt: cannot malloc progress msg buffer\n" msgstr "" -#: .././repair/dir.c:579 -#, c-format -msgid "hole claims used byte %d, block %d, dir ino %\n" +#: .././repair/progress.c:192 +msgid "progress_rpt: cannot create timer\n" msgstr "" -#: .././repair/dir.c:693 -#, c-format -msgid "- derived hole value %d, saw %d, block %d, dir ino %\n" +#: .././repair/progress.c:195 +msgid "progress_rpt: cannot set timer\n" msgstr "" -#: .././repair/dir.c:712 -#, c-format -msgid "" -"- derived hole (base %d, size %d) in block %d, dir inode % not " -"found\n" +#: .././repair/progress.c:219 +msgid "progress_rpt: cannot lock progress mutex\n" msgstr "" -#: .././repair/dir.c:767 .././repair/phase6.c:1214 .././repair/phase6.c:1583 +#: .././repair/progress.c:256 .././repair/progress.c:359 #, c-format -msgid "can't read block %u (fsbno %) for directory inode %\n" +msgid "%s" msgstr "" -#: .././repair/dir.c:771 +#: .././repair/progress.c:264 #, c-format msgid "" -"can't read block %u (fsbno %) for attrbute fork of inode %\n" +"\t- %02d:%02d:%02d: Phase %d: elapsed time %s - processed %d %s per minute\n" msgstr "" -#: .././repair/dir.c:779 .././repair/phase6.c:1224 +#: .././repair/progress.c:269 #, c-format msgid "" -"bad dir/attr magic number in inode %, file bno = %u, fsbno = %" -"\n" +"\t- %02d:%02d:%02d: Phase %d: %%% done - estimated remaining time " +"%s\n" msgstr "" -#: .././repair/dir.c:787 .././repair/dir2.c:333 -#, c-format -msgid "bad record count in inode %, count = %d, max = %d\n" +#: .././repair/progress.c:277 +msgid "progress_rpt: error unlock msg mutex\n" msgstr "" -#: .././repair/dir.c:806 .././repair/dir2.c:356 -#, c-format -msgid "bad directory btree for directory inode %\n" +#: .././repair/progress.c:283 +msgid "cannot delete timer\n" msgstr "" -#: .././repair/dir.c:810 -#, c-format -msgid "bad attribute fork btree for inode %\n" +#: .././repair/progress.c:297 +msgid "set_progress_msg: cannot lock progress mutex\n" msgstr "" -#: .././repair/dir.c:864 -#, c-format -msgid "release_da_cursor_int got unexpected non-null bp, dabno = %u\n" +#: .././repair/progress.c:307 +msgid "set_progress_msg: cannot unlock progress mutex\n" msgstr "" -#: .././repair/dir.c:931 -#, c-format -msgid "directory/attribute block used/count inconsistency - %d/%hu\n" +#: .././repair/progress.c:327 +msgid "print_final_rpt: cannot lock progress mutex\n" msgstr "" -#: .././repair/dir.c:941 .././repair/dir2.c:478 -#, c-format -msgid "" -"directory/attribute block hashvalue inconsistency, expected > %u / saw %u\n" +#: .././repair/progress.c:363 +msgid "print_final_rpt: cannot unlock progress mutex\n" msgstr "" -#: .././repair/dir.c:948 .././repair/dir2.c:485 +#: .././repair/progress.c:412 #, c-format -msgid "bad directory/attribute forward block pointer, expected 0, saw %u\n" +msgid "%02d:%02d:%02d" msgstr "" -#: .././repair/dir.c:954 +#: .././repair/progress.c:434 #, c-format -msgid "bad directory block in dir ino %\n" +msgid "%d week" msgstr "" -#: .././repair/dir.c:984 -#, c-format -msgid "" -"correcting bad hashval in non-leaf dir/attr block\n" -"\tin (level %d) in inode %.\n" +#: .././repair/progress.c:435 .././repair/progress.c:445 +#: .././repair/progress.c:461 .././repair/progress.c:479 +#: .././repair/progress.c:494 +msgid "s" msgstr "" -#: .././repair/dir.c:992 +#: .././repair/progress.c:444 #, c-format -msgid "" -"would correct bad hashval in non-leaf dir/attr block\n" -"\tin (level %d) in inode %.\n" +msgid "%d day" msgstr "" -#: .././repair/dir.c:1130 .././repair/dir2.c:652 -#, c-format -msgid "can't get map info for block %u of directory inode %\n" +#: .././repair/progress.c:451 .././repair/progress.c:468 +#: .././repair/progress.c:486 .././repair/progress.c:496 +msgid ", " msgstr "" -#: .././repair/dir.c:1140 +#: .././repair/progress.c:460 #, c-format -msgid "can't read block %u (%) for directory inode %\n" +msgid "%d hour" msgstr "" -#: .././repair/dir.c:1153 +#: .././repair/progress.c:478 #, c-format -msgid "" -"bad magic number %x in block %u (%) for directory inode %\n" +msgid "%d minute" msgstr "" -#: .././repair/dir.c:1161 +#: .././repair/progress.c:493 #, c-format -msgid "" -"bad back pointer in block %u (%) for directory inode %\n" +msgid "%d second" msgstr "" -#: .././repair/dir.c:1167 +#: .././repair/progress.c:514 #, c-format msgid "" -"entry count %d too large in block %u (%) for directory inode %" -"\n" +"\n" +" XFS_REPAIR Summary %s\n" msgstr "" -#: .././repair/dir.c:1174 -#, c-format -msgid "bad level %d in block %u (%) for directory inode %\n" +#: .././repair/progress.c:516 +msgid "Phase\t\tStart\t\tEnd\t\tDuration\n" msgstr "" -#: .././repair/dir.c:1231 +#: .././repair/progress.c:521 .././repair/progress.c:524 #, c-format -msgid "" -"correcting bad hashval in interior dir/attr block\n" -"\tin (level %d) in inode %.\n" +msgid "Phase %d:\tSkipped\n" msgstr "" -#: .././repair/dir.c:1239 +#: .././repair/progress.c:528 #, c-format -msgid "" -"would correct bad hashval in interior dir/attr block\n" -"\tin (level %d) in inode %.\n" +msgid "Phase %d:\t%02d/%02d %02d:%02d:%02d\t%02d/%02d %02d:%02d:%02d\t%s\n" msgstr "" -#: .././repair/dir.c:1347 +#: .././repair/progress.c:534 #, c-format msgid "" -"directory block header conflicts with used space in directory inode %" -"\n" +"\n" +"Total run time: %s\n" msgstr "" -#: .././repair/dir.c:1377 +#: .././repair/threads.c:90 #, c-format -msgid "" -"nameidx %d for entry #%d, bno %d, ino % > fs blocksize, deleting " -"entry\n" +msgid "cannot create worker threads, error = [%d] %s\n" msgstr "" -#: .././repair/dir.c:1414 +#: .././repair/threads.c:108 #, c-format -msgid "" -"nameidx %d, entry #%d, bno %d, ino % > fs blocksize, marking entry " -"bad\n" +msgid "cannot allocate worker item, error = [%d] %s\n" msgstr "" -#: .././repair/dir.c:1429 -#, c-format -msgid "" -"nameidx %d, entry #%d, bno %d, ino % > fs blocksize, would delete " -"entry\n" +#: .././repair/phase1.c:28 +msgid "Sorry, could not find valid secondary superblock\n" msgstr "" -#: .././repair/dir.c:1466 -#, c-format -msgid "invalid ino number % in dir ino %, entry #%d, bno %d\n" +#: .././repair/phase1.c:29 +msgid "Exiting now.\n" msgstr "" -#: .././repair/dir.c:1470 .././repair/dir.c:1486 .././repair/dir.c:1503 -#: .././repair/dir.c:1519 .././repair/dir.c:1536 +#: .././repair/phase1.c:40 #, c-format -msgid "\tclearing ino number in entry %d...\n" +msgid "could not allocate ag header buffer (%d bytes)\n" msgstr "" -#: .././repair/dir.c:1477 .././repair/dir.c:1494 .././repair/dir.c:1510 -#: .././repair/dir.c:1527 .././repair/dir.c:1544 -#, c-format -msgid "\twould clear ino number in entry %d...\n" +#: .././repair/phase1.c:58 +msgid "Phase 1 - find and verify superblock...\n" msgstr "" -#: .././repair/dir.c:1482 -#, c-format -msgid "" -"entry #%d, bno %d in directory % references realtime bitmap inode %" -"\n" +#: .././repair/phase1.c:75 +msgid "error reading primary superblock\n" msgstr "" -#: .././repair/dir.c:1499 +#: .././repair/phase1.c:81 #, c-format -msgid "" -"entry #%d, bno %d in directory % references realtime summary inode %" -"\n" +msgid "bad primary superblock - %s !!!\n" msgstr "" -#: .././repair/dir.c:1515 +#: .././repair/phase1.c:88 #, c-format -msgid "" -"entry #%d, bno %d in directory % references user quota inode %" -"\n" +msgid "couldn't verify primary superblock - %s !!!\n" msgstr "" -#: .././repair/dir.c:1532 -#, c-format -msgid "" -"entry #%d, bno %d in directory % references group quota inode %" -"\n" +#: .././repair/phase1.c:106 +msgid "superblock has a features2 mismatch, correcting\n" msgstr "" -#: .././repair/dir.c:1569 +#: .././repair/phase1.c:123 #, c-format -msgid "" -"entry references free inode % in directory %, will clear " -"entry\n" +msgid "Enabling lazy-counters\n" msgstr "" -#: .././repair/dir.c:1577 +#: .././repair/phase1.c:128 #, c-format -msgid "" -"entry references free inode % in directory %, would clear " -"entry\n" +msgid "Disabling lazy-counters\n" msgstr "" -#: .././repair/dir.c:1585 +#: .././repair/phase1.c:131 #, c-format -msgid "bad ino number % in dir ino %, entry #%d, bno %d\n" +msgid "Lazy-counters are already %s\n" msgstr "" -#: .././repair/dir.c:1588 -msgid "clearing inode number...\n" +#: .././repair/phase1.c:132 +msgid "enabled" msgstr "" -#: .././repair/dir.c:1593 -msgid "would clear inode number...\n" +#: .././repair/phase1.c:132 +msgid "disabled" msgstr "" -#: .././repair/dir.c:1613 -#, c-format -msgid "entry #%d, dir inode %, has zero-len name, deleting entry\n" +#: .././repair/phase1.c:139 +msgid "writing modified primary superblock\n" msgstr "" -#: .././repair/dir.c:1651 -#, c-format -msgid "entry #%d, dir inode %, has zero-len name, marking entry bad\n" +#: .././repair/phase1.c:142 +msgid "would write modified primary superblock\n" msgstr "" -#: .././repair/dir.c:1664 +#: .././repair/agheader.c:40 #, c-format -msgid "" -"bad size, entry #%d in dir inode %, block %u -- entry overflows " -"block\n" +msgid "bad magic # 0x%x for agf %d\n" msgstr "" -#: .././repair/dir.c:1675 +#: .././repair/agheader.c:49 #, c-format -msgid "" -"dir entry slot %d in block %u conflicts with used space in dir inode %" -"\n" +msgid "bad version # %d for agf %d\n" msgstr "" -#: .././repair/dir.c:1715 +#: .././repair/agheader.c:58 #, c-format -msgid "" -"illegal name \"%s\" in directory inode %, entry will be cleared\n" +msgid "bad sequence # %d for agf %d\n" msgstr "" -#: .././repair/dir.c:1721 +#: .././repair/agheader.c:68 #, c-format -msgid "" -"illegal name \"%s\" in directory inode %, entry would be cleared\n" +msgid "bad length %d for agf %d, should be %d\n" msgstr "" -#: .././repair/dir.c:1731 +#: .././repair/agheader.c:81 #, c-format -msgid "\tmismatched hash value for entry \"%s\"\n" +msgid "bad length %d for agf %d, should be %\n" msgstr "" -#: .././repair/dir.c:1735 +#: .././repair/agheader.c:95 #, c-format -msgid "\t\tin directory inode %. resetting hash value.\n" +msgid "flfirst %d in agf %d too large (max = %zu)\n" msgstr "" -#: .././repair/dir.c:1741 +#: .././repair/agheader.c:103 #, c-format -msgid "\t\tin directory inode %. would reset hash value.\n" +msgid "fllast %d in agf %d too large (max = %zu)\n" msgstr "" -#: .././repair/dir.c:1771 +#: .././repair/agheader.c:120 #, c-format -msgid "\tbad hash ordering for entry \"%s\"\n" +msgid "bad uuid %s for agf %d\n" msgstr "" -#: .././repair/dir.c:1775 +#: .././repair/agheader.c:138 #, c-format -msgid "\t\tin directory inode %. will clear entry\n" +msgid "bad magic # 0x%x for agi %d\n" msgstr "" -#: .././repair/dir.c:1782 +#: .././repair/agheader.c:147 #, c-format -msgid "\t\tin directory inode %. would clear entry\n" +msgid "bad version # %d for agi %d\n" msgstr "" -#: .././repair/dir.c:1798 +#: .././repair/agheader.c:156 #, c-format -msgid "" -"name \"%s\" (block %u, slot %d) conflicts with used space in dir inode %" -"\n" +msgid "bad sequence # %d for agi %d\n" msgstr "" -#: .././repair/dir.c:1805 +#: .././repair/agheader.c:166 #, c-format -msgid "will clear entry \"%s\" (#%d) in directory inode %\n" +msgid "bad length # %d for agi %d, should be %d\n" msgstr "" -#: .././repair/dir.c:1809 +#: .././repair/agheader.c:179 #, c-format -msgid "would clear entry \"%s\" (#%d)in directory inode %\n" +msgid "bad length # %d for agi %d, should be %\n" msgstr "" -#: .././repair/dir.c:1845 +#: .././repair/agheader.c:198 #, c-format -msgid "bad .. entry in dir ino %, points to self" +msgid "bad uuid %s for agi %d\n" msgstr "" -#: .././repair/dir.c:1849 .././repair/dir.c:1946 -msgid "will clear entry\n" +#: .././repair/agheader.c:302 +#, c-format +msgid "zeroing unused portion of %s superblock (AG #%u)\n" msgstr "" -#: .././repair/dir.c:1854 .././repair/dir.c:1950 .././repair/dir2.c:1642 -msgid "would clear entry\n" +#: .././repair/agheader.c:303 .././repair/agheader.c:318 +msgid "primary" msgstr "" -#: .././repair/dir.c:1864 -#, c-format -msgid "correcting .. entry in root inode %, was %\n" +#: .././repair/agheader.c:303 .././repair/agheader.c:318 +msgid "secondary" msgstr "" -#: .././repair/dir.c:1871 +#: .././repair/agheader.c:317 #, c-format -msgid "bad .. entry (%) in root inode % should be %\n" +msgid "would zero unused portion of %s superblock (AG #%u)\n" msgstr "" -#: .././repair/dir.c:1888 +#: .././repair/agheader.c:335 #, c-format -msgid "" -"multiple .. entries in directory inode %, will clear second entry\n" +msgid "bad flags field in superblock %d\n" msgstr "" -#: .././repair/dir.c:1894 +#: .././repair/agheader.c:358 #, c-format -msgid "" -"multiple .. entries in directory inode %, would clear second entry\n" +msgid "non-null user quota inode field in superblock %d\n" msgstr "" -#: .././repair/dir.c:1907 +#: .././repair/agheader.c:373 #, c-format -msgid "" -". in directory inode % has wrong value (%), fixing entry...\n" +msgid "non-null group quota inode field in superblock %d\n" msgstr "" -#: .././repair/dir.c:1914 +#: .././repair/agheader.c:388 #, c-format -msgid ". in directory inode % has wrong value (%)\n" +msgid "non-null project quota inode field in superblock %d\n" msgstr "" -#: .././repair/dir.c:1920 +#: .././repair/agheader.c:400 #, c-format -msgid "multiple . entries in directory inode %\n" +msgid "non-null quota flags in superblock %d\n" msgstr "" -#: .././repair/dir.c:1927 +#: .././repair/agheader.c:418 #, c-format -msgid "will clear one . entry in directory inode %\n" +msgid "bad shared version number in superblock %d\n" msgstr "" -#: .././repair/dir.c:1933 +#: .././repair/agheader.c:430 #, c-format -msgid "would clear one . entry in directory inode %\n" +msgid "bad inode alignment field in superblock %d\n" msgstr "" -#: .././repair/dir.c:1943 +#: .././repair/agheader.c:443 #, c-format -msgid "entry \"%s\" in directory inode % points to self, " +msgid "bad stripe unit/width fields in superblock %d\n" msgstr "" -#: .././repair/dir.c:1968 +#: .././repair/agheader.c:461 #, c-format -msgid "" -"- resetting first used heap value from %d to %d in block %u of dir ino %" -"\n" +msgid "bad log/data device sector size fields in superblock %d\n" msgstr "" -#: .././repair/dir.c:1976 +#: .././repair/agheader.c:492 #, c-format -msgid "" -"- would reset first used value from %d to %d in block %u of dir ino %" -"\n" +msgid "bad on-disk superblock %d - %s\n" msgstr "" -#: .././repair/dir.c:1986 +#: .././repair/agheader.c:499 #, c-format -msgid "" -"- resetting namebytes cnt from %d to %d in block %u of dir inode %\n" +msgid "primary/secondary superblock %d conflict - %s\n" msgstr "" -#: .././repair/dir.c:1994 +#: .././repair/attr_repair.c:110 #, c-format -msgid "" -"- would reset namebytes cnt from %d to %d in block %u of dir inode %" -"\n" +msgid "bad range claimed [%d, %d) in da block\n" msgstr "" -#: .././repair/dir.c:2029 +#: .././repair/attr_repair.c:117 #, c-format -msgid "- found unexpected lost holes in block %u, dir inode %\n" +msgid "byte range end [%d %d) in da block larger than blocksize %d\n" msgstr "" -#: .././repair/dir.c:2037 +#: .././repair/attr_repair.c:124 #, c-format -msgid "- hole info non-optimal in block %u, dir inode %\n" +msgid "multiply claimed byte %d in da block\n" msgstr "" -#: .././repair/dir.c:2044 +#: .././repair/attr_repair.c:177 #, c-format -msgid "- hole info incorrect in block %u, dir inode %\n" +msgid "can't read block %u (fsbno %) for directory inode %\n" msgstr "" -#: .././repair/dir.c:2055 +#: .././repair/attr_repair.c:181 #, c-format msgid "" -"- existing hole info for block %d, dir inode % (base, size) - \n" +"can't read block %u (fsbno %) for attrbute fork of inode %\n" msgstr "" -#: .././repair/dir.c:2063 +#: .././repair/attr_repair.c:192 #, c-format -msgid "- holes flag = %d\n" +msgid "" +"bad dir/attr magic number in inode %, file bno = %u, fsbno = " +"%\n" msgstr "" -#: .././repair/dir.c:2069 +#: .././repair/attr_repair.c:200 .././repair/dir2.c:205 #, c-format -msgid "- compacting block %u in dir inode %\n" +msgid "bad record count in inode %, count = %d, max = %d\n" msgstr "" -#: .././repair/dir.c:2110 +#: .././repair/attr_repair.c:219 .././repair/dir2.c:229 #, c-format -msgid "not enough space in block %u of dir inode % for all entries\n" +msgid "bad directory btree for directory inode %\n" msgstr "" -#: .././repair/dir.c:2180 +#: .././repair/attr_repair.c:223 #, c-format -msgid "- would compact block %u in dir inode %\n" +msgid "bad attribute fork btree for inode %\n" msgstr "" -#: .././repair/dir.c:2245 .././repair/dir2.c:1828 +#: .././repair/attr_repair.c:276 #, c-format -msgid "can't map block %u for directory inode %\n" +msgid "release_da_cursor_int got unexpected non-null bp, dabno = %u\n" msgstr "" -#: .././repair/dir.c:2256 +#: .././repair/attr_repair.c:348 #, c-format -msgid "" -"can't read file block %u (fsbno %, daddr %) for directory " -"inode %\n" +msgid "directory/attribute block used/count inconsistency - %d/%hu\n" msgstr "" -#: .././repair/dir.c:2270 .././repair/dir.c:2529 +#: .././repair/attr_repair.c:358 .././repair/dir2.c:354 #, c-format -msgid "bad directory leaf magic # %#x for dir ino %\n" +msgid "" +"directory/attribute block hashvalue inconsistency, expected > %u / saw %u\n" msgstr "" -#: .././repair/dir.c:2310 +#: .././repair/attr_repair.c:365 .././repair/dir2.c:361 #, c-format -msgid "" -"bad sibling back pointer for directory block %u in directory inode %" -"\n" +msgid "bad directory/attribute forward block pointer, expected 0, saw %u\n" msgstr "" -#: .././repair/dir.c:2341 .././repair/dir2.c:1904 +#: .././repair/attr_repair.c:371 #, c-format -msgid "bad hash path in directory %\n" +msgid "bad directory block in dir ino %\n" msgstr "" -#: .././repair/dir.c:2450 +#: .././repair/attr_repair.c:399 #, c-format -msgid "out of range internal directory block numbers (inode %)\n" +msgid "" +"correcting bad hashval in non-leaf dir/attr block\n" +"\tin (level %d) in inode %.\n" msgstr "" -#: .././repair/dir.c:2456 +#: .././repair/attr_repair.c:407 #, c-format msgid "" -"setting directory inode (%) size to % bytes, was % " -"bytes\n" +"would correct bad hashval in non-leaf dir/attr block\n" +"\tin (level %d) in inode %.\n" msgstr "" -#: .././repair/dir.c:2509 +#: .././repair/attr_repair.c:549 .././repair/dir2.c:530 #, c-format -msgid "block 0 for directory inode % is missing\n" +msgid "can't get map info for block %u of directory inode %\n" msgstr "" -#: .././repair/dir.c:2516 +#: .././repair/attr_repair.c:559 #, c-format -msgid "can't read block 0 for directory inode %\n" +msgid "can't read block %u (%) for directory inode %\n" msgstr "" -#: .././repair/dir.c:2552 +#: .././repair/attr_repair.c:575 #, c-format -msgid "clearing forw/back pointers for directory inode %\n" +msgid "" +"bad magic number %x in block %u (%) for directory inode %\n" msgstr "" -#: .././repair/dir.c:2558 +#: .././repair/attr_repair.c:582 #, c-format -msgid "would clear forw/back pointers for directory inode %\n" +msgid "" +"bad back pointer in block %u (%) for directory inode %\n" msgstr "" -#: .././repair/dir.c:2623 .././repair/dir2.c:2113 +#: .././repair/attr_repair.c:588 #, c-format -msgid "no . entry for directory %\n" +msgid "" +"entry count %d too large in block %u (%) for directory inode " +"%\n" msgstr "" -#: .././repair/dir.c:2632 .././repair/dir2.c:2123 +#: .././repair/attr_repair.c:595 #, c-format -msgid "no .. entry for directory %\n" +msgid "bad level %d in block %u (%) for directory inode %\n" msgstr "" -#: .././repair/dir.c:2634 .././repair/dir2.c:2125 +#: .././repair/attr_repair.c:660 #, c-format -msgid "no .. entry for root directory %\n" +msgid "" +"correcting bad hashval in interior dir/attr block\n" +"\tin (level %d) in inode %.\n" msgstr "" -#: .././repair/phase1.c:28 -msgid "Sorry, could not find valid secondary superblock\n" +#: .././repair/attr_repair.c:668 +#, c-format +msgid "" +"would correct bad hashval in interior dir/attr block\n" +"\tin (level %d) in inode %.\n" msgstr "" -#: .././repair/phase1.c:29 -msgid "Exiting now.\n" +#: .././repair/attr_repair.c:755 +msgid "No memory for ACL check!\n" msgstr "" -#: .././repair/phase1.c:40 -#, c-format -msgid "could not allocate ag header buffer (%d bytes)\n" +#: .././repair/attr_repair.c:763 +msgid "" +"entry contains illegal value in attribute named SGI_ACL_FILE or " +"SGI_ACL_DEFAULT\n" msgstr "" -#: .././repair/phase1.c:58 -msgid "Phase 1 - find and verify superblock...\n" +#: .././repair/attr_repair.c:789 +msgid "entry contains illegal value in attribute named SGI_MAC_LABEL\n" msgstr "" -#: .././repair/phase1.c:74 -msgid "error reading primary superblock\n" +#: .././repair/attr_repair.c:795 +msgid "entry contains illegal value in attribute named SGI_CAP_FILE\n" msgstr "" -#: .././repair/phase1.c:80 +#: .././repair/attr_repair.c:835 #, c-format -msgid "bad primary superblock - %s !!!\n" +msgid "there are no attributes in the fork for inode %\n" msgstr "" -#: .././repair/phase1.c:87 +#: .././repair/attr_repair.c:843 #, c-format -msgid "couldn't verify primary superblock - %s !!!\n" -msgstr "" - -#: .././repair/phase1.c:105 -msgid "superblock has a features2 mismatch, correcting\n" +msgid "would junk the attribute fork since count is 0 for inode %\n" msgstr "" -#: .././repair/phase1.c:122 -#, c-format -msgid "Enabling lazy-counters\n" +#: .././repair/attr_repair.c:863 +msgid "zero length name entry in attribute fork," msgstr "" -#: .././repair/phase1.c:127 +#: .././repair/attr_repair.c:866 .././repair/attr_repair.c:886 #, c-format -msgid "Disabling lazy-counters\n" +msgid " truncating attributes for inode % to %d\n" msgstr "" -#: .././repair/phase1.c:130 +#: .././repair/attr_repair.c:871 .././repair/attr_repair.c:892 #, c-format -msgid "Lazy-counters are already %s\n" -msgstr "" - -#: .././repair/phase1.c:131 -msgid "enabled" -msgstr "" - -#: .././repair/phase1.c:131 -msgid "disabled" +msgid " would truncate attributes for inode % to %d\n" msgstr "" -#: .././repair/phase1.c:138 -msgid "writing modified primary superblock\n" +#: .././repair/attr_repair.c:883 +msgid "name or value attribute lengths are too large,\n" msgstr "" -#: .././repair/phase1.c:141 -msgid "would write modified primary superblock\n" +#: .././repair/attr_repair.c:905 +msgid "entry contains illegal character in shortform attribute name\n" msgstr "" -#: .././repair/scan.c:90 .././repair/scan.c:135 -#, c-format -msgid "can't read btree block %d/%d\n" +#: .././repair/attr_repair.c:911 +msgid "entry has INCOMPLETE flag on in shortform attribute\n" msgstr "" -#: .././repair/scan.c:197 +#: .././repair/attr_repair.c:928 #, c-format -msgid "bad magic # %#x in inode % (%s fork) bmbt block %\n" +msgid "removing attribute entry %d for inode %\n" msgstr "" -#: .././repair/scan.c:203 +#: .././repair/attr_repair.c:940 #, c-format -msgid "" -"expected level %d got %d in inode %, (%s fork) bmbt block %\n" +msgid "would remove attribute entry %d for inode %\n" msgstr "" -#: .././repair/scan.c:223 +#: .././repair/attr_repair.c:955 #, c-format msgid "" -"bad fwd (right) sibling pointer (saw % parent block says %)\n" -"\tin inode % (%s fork) bmap btree block %\n" +"would have corrected attribute entry count in inode % from %d to %d\n" msgstr "" -#: .././repair/scan.c:233 +#: .././repair/attr_repair.c:959 #, c-format -msgid "" -"bad back (left) sibling pointer (saw %llu parent block says %)\n" -"\tin inode % (%s fork) bmap btree block %\n" +msgid "corrected attribute entry count in inode %, was %d, now %d\n" msgstr "" -#: .././repair/scan.c:248 +#: .././repair/attr_repair.c:970 #, c-format msgid "" -"bad back (left) sibling pointer (saw %llu should be NULL (0))\n" -"\tin inode % (%s fork) bmap btree block %\n" +"would have corrected attribute totsize in inode % from %d to %d\n" msgstr "" -#: .././repair/scan.c:289 +#: .././repair/attr_repair.c:975 #, c-format -msgid "inode 0x%bmap block 0x% claimed, state is %d\n" +msgid "corrected attribute entry totsize in inode %, was %d, now %d\n" msgstr "" -#: .././repair/scan.c:296 +#: .././repair/attr_repair.c:1009 #, c-format -msgid "inode 0x% bmap block 0x% claimed, state is %d\n" +msgid "remote block for attributes of inode % is missing\n" msgstr "" -#: .././repair/scan.c:311 +#: .././repair/attr_repair.c:1018 #, c-format -msgid "bad state %d, inode % bmap block 0x%\n" +msgid "can't read remote block for attributes of inode %\n" msgstr "" -#: .././repair/scan.c:338 .././repair/scan.c:389 +#: .././repair/attr_repair.c:1025 #, c-format -msgid "inode % bad # of bmap records (%u, min - %u, max - %u)\n" +msgid "Corrupt remote block for attributes of inode %\n" msgstr "" -#: .././repair/scan.c:368 +#: .././repair/attr_repair.c:1066 #, c-format msgid "" -"out-of-order bmap key (file offset) in inode %, %s fork, fsbno %" -"\n" -msgstr "" - -#: .././repair/scan.c:406 .././repair/dinode.c:1187 -#, c-format -msgid "bad bmap btree ptr 0x%llx in ino %\n" +"attribute entry %d in attr block %u, inode % has bad name (namelen = " +"%d)\n" msgstr "" -#: .././repair/scan.c:433 +#: .././repair/attr_repair.c:1083 #, c-format msgid "" -"correcting bt key (was %llu, now %) in inode %\n" -"\t\t%s fork, btree block %\n" +"bad hashvalue for attribute entry %d in attr block %u, inode %\n" msgstr "" -#: .././repair/scan.c:445 +#: .././repair/attr_repair.c:1093 #, c-format msgid "" -"bad btree key (is %llu, should be %) in inode %\n" -"\t\t%s fork, btree block %\n" +"bad security value for attribute entry %d in attr block %u, inode %\n" msgstr "" -#: .././repair/scan.c:463 +#: .././repair/attr_repair.c:1126 #, c-format msgid "" -"bad fwd (right) sibling pointer (saw % should be NULLDFSBNO)\n" -"\tin inode % (%s fork) bmap btree block %\n" +"inconsistent remote attribute entry %d in attr block %u, ino %\n" msgstr "" -#: .././repair/scan.c:537 +#: .././repair/attr_repair.c:1136 #, c-format -msgid "bad magic # %#x in bt%s block %d/%d\n" +msgid "cannot malloc enough for remotevalue attribute for inode %\n" msgstr "" -#: .././repair/scan.c:555 -#, c-format -msgid "expected level %d got %d in bt%s block %d/%d\n" +#: .././repair/attr_repair.c:1138 +msgid "SKIPPING this remote attribute\n" msgstr "" -#: .././repair/scan.c:569 +#: .././repair/attr_repair.c:1144 #, c-format -msgid "" -"%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n" +msgid "remote attribute get failed for entry %d, inode %\n" msgstr "" -#: .././repair/scan.c:589 .././repair/scan.c:688 +#: .././repair/attr_repair.c:1151 #, c-format -msgid "bad btree nrecs (%u, min=%u, max=%u) in bt%s block %u/%u\n" +msgid "remote attribute value check failed for entry %d, inode %\n" msgstr "" -#: .././repair/scan.c:607 +#: .././repair/attr_repair.c:1189 #, c-format -msgid "invalid start block %u in record %u of %s btree block %u/%u\n" +msgid "bad attribute count %d in attr block %u, inode %\n" msgstr "" -#: .././repair/scan.c:613 +#: .././repair/attr_repair.c:1204 #, c-format -msgid "invalid length %u in record %u of %s btree block %u/%u\n" +msgid "bad attribute nameidx %d in attr block %u, inode %\n" msgstr "" -#: .././repair/scan.c:658 +#: .././repair/attr_repair.c:1213 #, c-format -msgid "block (%d,%d-%d) multiply claimed by %s space tree, state - %d\n" +msgid "attribute entry #%d in attr block %u, inode % is INCOMPLETE\n" msgstr "" -#: .././repair/scan.c:755 +#: .././repair/attr_repair.c:1224 #, c-format -msgid "badly aligned inode rec (starting inode = %)\n" +msgid "" +"attribute entry %d in attr block %u, inode % claims already used " +"space\n" msgstr "" -#: .././repair/scan.c:771 +#: .././repair/attr_repair.c:1247 #, c-format -msgid "bad starting inode # (% (0x%x 0x%x)) in ino rec, skipping rec\n" +msgid "" +"attribute entry %d in attr block %u, inode % claims used space\n" msgstr "" -#: .././repair/scan.c:779 +#: .././repair/attr_repair.c:1271 #, c-format -msgid "bad ending inode # (% (0x%x 0x%zx)) in ino rec, skipping rec\n" +msgid "" +"- resetting first used heap value from %d to %d in block %u of attribute " +"fork of inode %\n" msgstr "" -#: .././repair/scan.c:804 +#: .././repair/attr_repair.c:1279 #, c-format msgid "" -"inode chunk claims used block, inobt block - agno %d, bno %d, inopb %d\n" +"- would reset first used value from %d to %d in block %u of attribute fork " +"of inode %\n" msgstr "" -#: .././repair/scan.c:826 +#: .././repair/attr_repair.c:1289 #, c-format msgid "" -"inode rec for ino % (%d/%d) overlaps existing rec (start %d/%d)\n" +"- resetting usedbytes cnt from %d to %d in block %u of attribute fork of " +"inode %\n" msgstr "" -#: .././repair/scan.c:873 +#: .././repair/attr_repair.c:1297 #, c-format -msgid "ir_freecount/free mismatch, inode chunk %d/%u, freecount %d nfree %d\n" +msgid "" +"- would reset usedbytes cnt from %d to %d in block %u of attribute fork of " +"%\n" msgstr "" -#: .././repair/scan.c:919 +#: .././repair/attr_repair.c:1352 #, c-format -msgid "bad magic # %#x in inobt block %d/%d\n" +msgid "can't map block %u for attribute fork for inode %\n" msgstr "" -#: .././repair/scan.c:927 +#: .././repair/attr_repair.c:1362 #, c-format -msgid "expected level %d got %d in inobt block %d/%d\n" +msgid "" +"can't read file block %u (fsbno %) for attribute fork of inode " +"%\n" msgstr "" -#: .././repair/scan.c:949 +#: .././repair/attr_repair.c:1376 #, c-format -msgid "inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n" +msgid "bad attribute leaf magic %#x for inode %\n" msgstr "" -#: .././repair/scan.c:972 +#: .././repair/attr_repair.c:1407 #, c-format -msgid "dubious inode btree block header %d/%d\n" +msgid "" +"bad sibling back pointer for block %u in attribute fork for inode %\n" msgstr "" -#: .././repair/scan.c:1065 +#: .././repair/attr_repair.c:1434 #, c-format -msgid "can't read agfl block for ag %d\n" +msgid "bad hash path in attribute fork for inode %\n" msgstr "" -#: .././repair/scan.c:1076 +#: .././repair/attr_repair.c:1534 #, c-format -msgid "bad agbno %u in agfl, agno %d\n" +msgid "block 0 of inode % attribute fork is missing\n" msgstr "" -#: .././repair/scan.c:1085 +#: .././repair/attr_repair.c:1541 #, c-format -msgid "freeblk count %d != flcount %d in ag %d\n" +msgid "agno of attribute fork of inode % out of regular partition\n" msgstr "" -#: .././repair/scan.c:1107 +#: .././repair/attr_repair.c:1549 #, c-format -msgid "bad agbno %u for btbno root, agno %d\n" +msgid "can't read block 0 of inode % attribute fork\n" msgstr "" -#: .././repair/scan.c:1116 +#: .././repair/attr_repair.c:1566 #, c-format -msgid "bad agbno %u for btbcnt root, agno %d\n" +msgid "" +"clearing forw/back pointers in block 0 for attributes in inode %\n" msgstr "" -#: .././repair/scan.c:1132 +#: .././repair/attr_repair.c:1574 #, c-format -msgid "agf_btreeblks %u, counted % in ag %u\n" +msgid "" +"would clear forw/back pointers in block 0 for attributes in inode %\n" msgstr "" -#: .././repair/scan.c:1151 +#: .././repair/attr_repair.c:1606 #, c-format -msgid "bad agbno %u for inobt root, agno %d\n" +msgid "bad attribute leaf magic # %#x for dir ino %\n" msgstr "" -#: .././repair/scan.c:1170 +#: .././repair/attr_repair.c:1635 #, c-format -msgid "agi unlinked bucket %d is %u in ag %u (inode=%)\n" +msgid "Too many ACL entries, count %d\n" msgstr "" -#: .././repair/scan.c:1201 -#, c-format -msgid "can't get root superblock for ag %d\n" +#: .././repair/attr_repair.c:1644 +msgid "cannot malloc enough for ACL attribute\n" msgstr "" -#: .././repair/scan.c:1207 -msgid "can't allocate memory for superblock\n" +#: .././repair/attr_repair.c:1645 +msgid "SKIPPING this ACL\n" msgstr "" -#: .././repair/scan.c:1217 +#: .././repair/attr_repair.c:1695 .././repair/dinode.c:2053 #, c-format -msgid "can't read agf block for ag %d\n" +msgid "illegal attribute format %d, ino %\n" msgstr "" -#: .././repair/scan.c:1228 +#: .././repair/dir2.c:49 #, c-format -msgid "can't read agi block for ag %d\n" +msgid "malloc failed (%zu bytes) dir2_add_badlist:ino %\n" msgstr "" -#: .././repair/scan.c:1252 -#, c-format -msgid "reset bad sb for ag %d\n" +#: .././repair/dir2.c:111 .././repair/prefetch.c:238 +msgid "couldn't malloc dir2 buffer list\n" msgstr "" -#: .././repair/scan.c:1255 +#: .././repair/dir2.c:174 .././repair/dir2.c:541 .././repair/dir2.c:1597 #, c-format -msgid "would reset bad sb for ag %d\n" +msgid "can't read block %u for directory inode %\n" msgstr "" -#: .././repair/scan.c:1260 +#: .././repair/dir2.c:186 #, c-format -msgid "reset bad agf for ag %d\n" +msgid "found non-root LEAFN node in inode % bno = %u\n" msgstr "" -#: .././repair/scan.c:1263 +#: .././repair/dir2.c:196 #, c-format -msgid "would reset bad agf for ag %d\n" +msgid "bad dir magic number 0x%x in inode % bno = %u\n" msgstr "" -#: .././repair/scan.c:1268 +#: .././repair/dir2.c:218 #, c-format -msgid "reset bad agi for ag %d\n" +msgid "bad header depth for directory inode %\n" msgstr "" -#: .././repair/scan.c:1271 +#: .././repair/dir2.c:278 #, c-format -msgid "would reset bad agi for ag %d\n" +msgid "release_dir2_cursor_int got unexpected non-null bp, dabno = %u\n" msgstr "" -#: .././repair/scan.c:1281 +#: .././repair/dir2.c:345 #, c-format -msgid "bad uncorrected agheader %d, skipping ag...\n" -msgstr "" - -#: .././repair/scan.c:1340 -msgid "no memory for ag header counts\n" +msgid "directory block used/count inconsistency - %d / %hu\n" msgstr "" -#: .././repair/scan.c:1363 +#: .././repair/dir2.c:367 #, c-format -msgid "sb_icount %, counted %\n" +msgid "bad directory block in inode %\n" msgstr "" -#: .././repair/scan.c:1368 +#: .././repair/dir2.c:387 #, c-format -msgid "sb_ifree %, counted %\n" +msgid "" +"correcting bad hashval in non-leaf dir block\n" +"\tin (level %d) in inode %.\n" msgstr "" -#: .././repair/scan.c:1373 +#: .././repair/dir2.c:395 #, c-format -msgid "sb_fdblocks %, counted %\n" +msgid "" +"would correct bad hashval in non-leaf dir block\n" +"\tin (level %d) in inode %.\n" msgstr "" -#: .././repair/threads.c:90 +#: .././repair/dir2.c:557 #, c-format -msgid "cannot create worker threads, error = [%d] %s\n" +msgid "bad magic number %x in block %u for directory inode %\n" msgstr "" -#: .././repair/threads.c:108 +#: .././repair/dir2.c:564 #, c-format -msgid "cannot allocate worker item, error = [%d] %s\n" +msgid "bad back pointer in block %u for directory inode %\n" msgstr "" -#: .././repair/versions.c:73 +#: .././repair/dir2.c:570 #, c-format -msgid "bogus quota flags 0x%x set in superblock" -msgstr "" - -#: .././repair/versions.c:86 -msgid ", bogus flags will be cleared\n" -msgstr "" - -#: .././repair/versions.c:88 -msgid ", bogus flags would be cleared\n" -msgstr "" - -#: .././repair/versions.c:141 -msgid "This filesystem has uninitialized extent flags.\n" -msgstr "" - -#: .././repair/versions.c:149 -msgid "This filesystem is marked shared.\n" -msgstr "" - -#: .././repair/versions.c:155 -msgid "" -"This filesystem uses feature(s) not yet supported in this release.\n" -"Please run a more recent version of xfs_repair.\n" +msgid "entry count %d too large in block %u for directory inode %\n" msgstr "" -#: .././repair/versions.c:161 +#: .././repair/dir2.c:577 #, c-format -msgid "WARNING: unknown superblock version %d\n" +msgid "bad level %d in block %u for directory inode %\n" msgstr "" -#: .././repair/versions.c:164 -msgid "This filesystem contains features not understood by this program.\n" +#: .././repair/dir2.c:624 +#, c-format +msgid "" +"correcting bad hashval in interior dir block\n" +"\tin (level %d) in inode %.\n" msgstr "" -#: .././repair/versions.c:172 +#: .././repair/dir2.c:632 +#, c-format msgid "" -"WARNING: you have disallowed superblock-feature-bits-allowed\n" -"\tbut this superblock has feature bits. The superblock\n" -"\twill be downgraded. This may cause loss of filesystem meta-data\n" +"would correct bad hashval in interior dir block\n" +"\tin (level %d) in inode %.\n" msgstr "" -#: .././repair/versions.c:177 -msgid "" -"WARNING: you have disallowed superblock-feature-bits-allowed\n" -"\tbut this superblock has feature bits. The superblock\n" -"\twould be downgraded. This might cause loss of filesystem\n" -"\tmeta-data.\n" +#: .././repair/dir2.c:667 +msgid "couldn't malloc dir2 shortform copy\n" msgstr "" -#: .././repair/versions.c:191 -msgid "" -"WARNING: you have disallowed attributes but this filesystem\n" -"\thas attributes. The filesystem will be downgraded and\n" -"\tall attributes will be removed.\n" +#: .././repair/dir2.c:803 +msgid "current" msgstr "" -#: .././repair/versions.c:196 -msgid "" -"WARNING: you have disallowed attributes but this filesystem\n" -"\thas attributes. The filesystem would be downgraded and\n" -"\tall attributes would be removed.\n" +#: .././repair/dir2.c:806 .././repair/dir2.c:1328 +msgid "invalid" msgstr "" -#: .././repair/versions.c:209 -msgid "" -"WARNING: you have disallowed attr2 attributes but this filesystem\n" -"\thas attributes. The filesystem will be downgraded and\n" -"\tall attr2 attributes will be removed.\n" +#: .././repair/dir2.c:809 .././repair/dir2.c:1330 +msgid "realtime bitmap" msgstr "" -#: .././repair/versions.c:214 -msgid "" -"WARNING: you have disallowed attr2 attributes but this filesystem\n" -"\thas attributes. The filesystem would be downgraded and\n" -"\tall attr2 attributes would be removed.\n" +#: .././repair/dir2.c:812 .././repair/dir2.c:1332 +msgid "realtime summary" msgstr "" -#: .././repair/versions.c:227 -msgid "" -"WARNING: you have disallowed version 2 inodes but this filesystem\n" -"\thas version 2 inodes. The filesystem will be downgraded and\n" -"\tall version 2 inodes will be converted to version 1 inodes.\n" -"\tThis may cause some hard links to files to be destroyed\n" +#: .././repair/dir2.c:815 .././repair/dir2.c:1334 +msgid "user quota" msgstr "" -#: .././repair/versions.c:233 -msgid "" -"WARNING: you have disallowed version 2 inodes but this filesystem\n" -"\thas version 2 inodes. The filesystem would be downgraded and\n" -"\tall version 2 inodes would be converted to version 1 inodes.\n" -"\tThis might cause some hard links to files to be destroyed\n" +#: .././repair/dir2.c:818 .././repair/dir2.c:1336 +msgid "group quota" msgstr "" -#: .././repair/versions.c:247 -msgid "" -"WARNING: you have disallowed quotas but this filesystem\n" -"\thas quotas. The filesystem will be downgraded and\n" -"\tall quota information will be removed.\n" +#: .././repair/dir2.c:821 .././repair/dir2.c:1338 +msgid "project quota" msgstr "" -#: .././repair/versions.c:252 -msgid "" -"WARNING: you have disallowed quotas but this filesystem\n" -"\thas quotas. The filesystem would be downgraded and\n" -"\tall quota information would be removed.\n" +#: .././repair/dir2.c:839 .././repair/dir2.c:1368 +msgid "free" msgstr "" -#: .././repair/versions.c:276 -msgid "" -"WARNING: you have disallowed aligned inodes but this filesystem\n" -"\thas aligned inodes. The filesystem will be downgraded.\n" -"\tThis will permanently degrade the performance of this filesystem.\n" +#: .././repair/dir2.c:856 .././repair/dir2.c:1348 +msgid "non-existent" msgstr "" -#: .././repair/versions.c:281 +#: .././repair/dir2.c:861 +#, c-format msgid "" -"WARNING: you have disallowed aligned inodes but this filesystem\n" -"\thas aligned inodes. The filesystem would be downgraded.\n" -"\tThis would permanently degrade the performance of this filesystem.\n" +"entry \"%*.*s\" in shortform directory % references %s inode " +"%\n" msgstr "" -#: .././repair/avl.c:1011 .././repair/avl64.c:1032 +#: .././repair/dir2.c:881 #, c-format -msgid "avl_insert: Warning! duplicate range [%llu,%llu]\n" +msgid "zero length entry in shortform dir %, resetting to %d\n" msgstr "" -#: .././repair/avl.c:1206 .././repair/avl64.c:1227 +#: .././repair/dir2.c:886 #, c-format -msgid "Command [fpdir] : " +msgid "zero length entry in shortform dir %, would set to %d\n" msgstr "" -#: .././repair/avl.c:1215 .././repair/avl64.c:1236 +#: .././repair/dir2.c:891 #, c-format -msgid "end of range ? " +msgid "zero length entry in shortform dir %" msgstr "" -#: .././repair/avl.c:1226 .././repair/avl64.c:1247 +#: .././repair/dir2.c:894 #, c-format -msgid "Cannot find %d\n" +msgid ", junking %d entries\n" msgstr "" -#: .././repair/avl.c:1239 .././repair/avl64.c:1260 +#: .././repair/dir2.c:897 #, c-format -msgid "size of range ? " +msgid ", would junk %d entries\n" msgstr "" -#: .././repair/avl.c:1250 .././repair/avl64.c:1271 +#: .././repair/dir2.c:915 #, c-format -msgid "End of range ? " +msgid "size of last entry overflows space left in in shortform dir %, " msgstr "" -#: .././repair/avl.c:1254 .././repair/avl64.c:1275 +#: .././repair/dir2.c:918 #, c-format -msgid "checklen 0/1 ? " +msgid "resetting to %d\n" msgstr "" -#: .././repair/avl.c:1261 .././repair/avl64.c:1282 +#: .././repair/dir2.c:923 #, c-format -msgid "Found something\n" +msgid "would reset to %d\n" msgstr "" -#: .././repair/phase5.c:211 -msgid "could not set up btree block array\n" +#: .././repair/dir2.c:928 +#, c-format +msgid "size of entry #%d overflows space left in in shortform dir %\n" msgstr "" -#: .././repair/phase5.c:223 -msgid "error - not enough free space in filesystem\n" +#: .././repair/dir2.c:933 +#, c-format +msgid "junking entry #%d\n" msgstr "" -#: .././repair/phase5.c:438 +#: .././repair/dir2.c:937 #, c-format -msgid "can't rebuild fs trees -- not enough free space on ag %u\n" +msgid "junking %d entries\n" msgstr "" -#: .././repair/phase5.c:462 +#: .././repair/dir2.c:942 #, c-format -msgid "ag %u - not enough free space to build freespace btrees\n" +msgid "would junk entry #%d\n" msgstr "" -#: .././repair/phase5.c:497 +#: .././repair/dir2.c:946 #, c-format -msgid "not enough free blocks left to describe all free blocks in AG %u\n" +msgid "would junk %d entries\n" msgstr "" -#: .././repair/phase5.c:1310 +#: .././repair/dir2.c:965 #, c-format -msgid "lost %d blocks in ag %u\n" +msgid "entry contains illegal character in shortform dir %\n" msgstr "" -#: .././repair/phase5.c:1313 +#: .././repair/dir2.c:972 #, c-format -msgid "thought we were going to lose %d blocks in ag %u, actually lost %d\n" +msgid "entry contains offset out of order in shortform dir %\n" msgstr "" -#: .././repair/phase5.c:1360 .././repair/xfs_repair.c:849 -msgid "couldn't get superblock\n" +#: .././repair/dir2.c:1029 +#, c-format +msgid "junking entry \"%s\" in directory inode %\n" msgstr "" -#: .././repair/phase5.c:1409 .././repair/phase6.c:3624 -#: .././repair/phase4.c:125 .././repair/phase3.c:76 +#: .././repair/dir2.c:1033 #, c-format -msgid " - agno = %d\n" +msgid "would have junked entry \"%s\" in directory inode %\n" msgstr "" -#: .././repair/phase5.c:1432 +#: .././repair/dir2.c:1058 #, c-format -msgid "unable to rebuild AG %u. Not enough free space in on-disk AG.\n" +msgid "would have corrected entry count in directory % from %d to %d\n" msgstr "" -#: .././repair/phase5.c:1467 +#: .././repair/dir2.c:1062 #, c-format -msgid "unable to rebuild AG %u. No free space.\n" +msgid "corrected entry count in directory %, was %d, now %d\n" msgstr "" -#: .././repair/phase5.c:1494 +#: .././repair/dir2.c:1073 #, c-format -msgid "lost %d blocks in agno %d, sorry.\n" +msgid "would have corrected i8 count in directory % from %d to %d\n" msgstr "" -#: .././repair/phase5.c:1563 -msgid "Phase 5 - rebuild AG headers and trees...\n" +#: .././repair/dir2.c:1077 +#, c-format +msgid "corrected i8 count in directory %, was %d, now %d\n" msgstr "" -#: .././repair/phase5.c:1593 -msgid "cannot alloc sb_icount_ag buffers\n" +#: .././repair/dir2.c:1091 +#, c-format +msgid "" +"would have corrected directory % size from % to %\n" msgstr "" -#: .././repair/phase5.c:1597 -msgid "cannot alloc sb_ifree_ag buffers\n" +#: .././repair/dir2.c:1096 +#, c-format +msgid "corrected directory % size, was %, now %\n" msgstr "" -#: .././repair/phase5.c:1601 -msgid "cannot alloc sb_fdblocks_ag buffers\n" +#: .././repair/dir2.c:1108 +#, c-format +msgid "directory % offsets too high\n" msgstr "" -#: .././repair/phase5.c:1620 -msgid " - generate realtime summary info and bitmap...\n" +#: .././repair/dir2.c:1114 +#, c-format +msgid "would have corrected entry offsets in directory %\n" msgstr "" -#: .././repair/phase5.c:1625 -msgid " - reset superblock...\n" +#: .././repair/dir2.c:1118 +#, c-format +msgid "corrected entry offsets in directory %\n" msgstr "" -#: .././repair/attr_repair.c:105 -msgid "" -"entry contains illegal value in attribute named SGI_ACL_FILE or " -"SGI_ACL_DEFAULT\n" +#: .././repair/dir2.c:1137 +#, c-format +msgid "bogus .. inode number (%) in directory inode %, " msgstr "" -#: .././repair/attr_repair.c:127 -msgid "entry contains illegal value in attribute named SGI_MAC_LABEL\n" +#: .././repair/dir2.c:1141 .././repair/dir2.c:1176 +msgid "clearing inode number\n" msgstr "" -#: .././repair/attr_repair.c:133 -msgid "entry contains illegal value in attribute named SGI_CAP_FILE\n" +#: .././repair/dir2.c:1147 .././repair/dir2.c:1182 +msgid "would clear inode number\n" msgstr "" -#: .././repair/attr_repair.c:172 +#: .././repair/dir2.c:1155 #, c-format -msgid "there are no attributes in the fork for inode %\n" +msgid "" +"corrected root directory % .. entry, was %, now %\n" msgstr "" -#: .././repair/attr_repair.c:180 +#: .././repair/dir2.c:1163 #, c-format -msgid "would junk the attribute fork since count is 0 for inode %\n" +msgid "" +"would have corrected root directory % .. entry from % to " +"%\n" msgstr "" -#: .././repair/attr_repair.c:200 -msgid "zero length name entry in attribute fork," +#: .././repair/dir2.c:1173 +#, c-format +msgid "bad .. entry in directory inode %, points to self, " msgstr "" -#: .././repair/attr_repair.c:203 .././repair/attr_repair.c:223 +#: .././repair/dir2.c:1286 #, c-format -msgid " truncating attributes for inode % to %d\n" +msgid "corrupt block %u in directory inode %\n" msgstr "" -#: .././repair/attr_repair.c:208 .././repair/attr_repair.c:229 -#, c-format -msgid " would truncate attributes for inode % to %d\n" +#: .././repair/dir2.c:1289 +msgid "\twill junk block\n" msgstr "" -#: .././repair/attr_repair.c:220 -msgid "name or value attribute lengths are too large,\n" +#: .././repair/dir2.c:1291 +msgid "\twould junk block\n" msgstr "" -#: .././repair/attr_repair.c:242 -msgid "entry contains illegal character in shortform attribute name\n" +#: .././repair/dir2.c:1377 +#, c-format +msgid "" +"entry \"%*.*s\" at block %d offset % in directory inode % " +"references %s inode %\n" msgstr "" -#: .././repair/attr_repair.c:248 -msgid "entry has INCOMPLETE flag on in shortform attribute\n" +#: .././repair/dir2.c:1388 +#, c-format +msgid "" +"entry at block %u offset % in directory inode %has 0 " +"namelength\n" msgstr "" -#: .././repair/attr_repair.c:265 +#: .././repair/dir2.c:1401 #, c-format -msgid "removing attribute entry %d for inode %\n" +msgid "\tclearing inode number in entry at offset %...\n" msgstr "" -#: .././repair/attr_repair.c:277 +#: .././repair/dir2.c:1407 #, c-format -msgid "would remove attribute entry %d for inode %\n" +msgid "\twould clear inode number in entry at offset %...\n" msgstr "" -#: .././repair/attr_repair.c:292 +#: .././repair/dir2.c:1420 #, c-format msgid "" -"would have corrected attribute entry count in inode % from %d to %d\n" +"entry at block %u offset % in directory inode % has illegal " +"name \"%*.*s\": " msgstr "" -#: .././repair/attr_repair.c:296 +#: .././repair/dir2.c:1451 #, c-format -msgid "corrected attribute entry count in inode %, was %d, now %d\n" +msgid "bad .. entry in directory inode %, points to self: " msgstr "" -#: .././repair/attr_repair.c:307 +#: .././repair/dir2.c:1462 #, c-format -msgid "" -"would have corrected attribute totsize in inode % from %d to %d\n" +msgid "bad .. entry in root directory inode %, was %: " msgstr "" -#: .././repair/attr_repair.c:312 -#, c-format -msgid "corrected attribute entry totsize in inode %, was %d, now %d\n" +#: .././repair/dir2.c:1465 .././repair/dir2.c:1497 .././repair/phase2.c:184 +#: .././repair/phase2.c:193 .././repair/phase2.c:202 +msgid "correcting\n" +msgstr "" + +#: .././repair/dir2.c:1469 .././repair/dir2.c:1501 .././repair/phase2.c:186 +#: .././repair/phase2.c:195 .././repair/phase2.c:204 +msgid "would correct\n" msgstr "" -#: .././repair/attr_repair.c:342 +#: .././repair/dir2.c:1481 #, c-format -msgid "remote block for attributes of inode % is missing\n" +msgid "multiple .. entries in directory inode %: " msgstr "" -#: .././repair/attr_repair.c:350 +#: .././repair/dir2.c:1494 #, c-format -msgid "can't read remote block for attributes of inode %\n" +msgid "bad . entry in directory inode %, was %: " msgstr "" -#: .././repair/attr_repair.c:388 +#: .././repair/dir2.c:1506 #, c-format -msgid "" -"attribute entry %d in attr block %u, inode % has bad name (namelen = " -"%d)\n" +msgid "multiple . entries in directory inode %: " msgstr "" -#: .././repair/attr_repair.c:405 +#: .././repair/dir2.c:1516 #, c-format -msgid "" -"bad hashvalue for attribute entry %d in attr block %u, inode %\n" +msgid "entry \"%*.*s\" in directory inode % points to self: " msgstr "" -#: .././repair/attr_repair.c:415 +#: .././repair/dir2.c:1527 +msgid "clearing entry\n" +msgstr "" + +#: .././repair/dir2.c:1529 +msgid "would clear entry\n" +msgstr "" + +#: .././repair/dir2.c:1542 #, c-format -msgid "" -"bad security value for attribute entry %d in attr block %u, inode %\n" +msgid "bad bestfree table in block %u in directory inode %: " +msgstr "" + +#: .././repair/dir2.c:1545 +msgid "repairing table\n" msgstr "" -#: .././repair/attr_repair.c:448 +#: .././repair/dir2.c:1549 +msgid "would repair table\n" +msgstr "" + +#: .././repair/dir2.c:1588 #, c-format -msgid "" -"inconsistent remote attribute entry %d in attr block %u, ino %\n" +msgid "block %u for directory inode % is missing\n" msgstr "" -#: .././repair/attr_repair.c:458 +#: .././repair/dir2.c:1608 #, c-format -msgid "cannot malloc enough for remotevalue attribute for inode %\n" +msgid "" +"bad directory block magic # %#x in block %u for directory inode %\n" msgstr "" -#: .././repair/attr_repair.c:460 -msgid "SKIPPING this remote attribute\n" +#: .././repair/dir2.c:1660 +#, c-format +msgid "bad entry count in block %u of directory inode %\n" msgstr "" -#: .././repair/attr_repair.c:466 +#: .././repair/dir2.c:1668 #, c-format -msgid "remote attribute get failed for entry %d, inode %\n" +msgid "bad hash ordering in block %u of directory inode %\n" msgstr "" -#: .././repair/attr_repair.c:473 +#: .././repair/dir2.c:1676 #, c-format -msgid "remote attribute value check failed for entry %d, inode %\n" +msgid "bad stale count in block %u of directory inode %\n" msgstr "" -#: .././repair/attr_repair.c:510 +#: .././repair/dir2.c:1725 #, c-format -msgid "bad attribute count %d in attr block %u, inode %\n" +msgid "can't map block %u for directory inode %\n" msgstr "" -#: .././repair/attr_repair.c:525 +#: .././repair/dir2.c:1735 #, c-format -msgid "bad attribute nameidx %d in attr block %u, inode %\n" +msgid "can't read file block %u for directory inode %\n" msgstr "" -#: .././repair/attr_repair.c:534 +#: .././repair/dir2.c:1747 #, c-format -msgid "attribute entry #%d in attr block %u, inode % is INCOMPLETE\n" +msgid "bad directory leaf magic # %#x for directory inode % block %u\n" msgstr "" -#: .././repair/attr_repair.c:545 +#: .././repair/dir2.c:1775 #, c-format -msgid "" -"attribute entry %d in attr block %u, inode % claims already used " -"space\n" +msgid "bad sibling back pointer for block %u in directory inode %\n" msgstr "" -#: .././repair/attr_repair.c:568 +#: .././repair/dir2.c:1806 #, c-format -msgid "" -"attribute entry %d in attr block %u, inode % claims used space\n" +msgid "bad hash path in directory %\n" msgstr "" -#: .././repair/attr_repair.c:592 +#: .././repair/dir2.c:1916 #, c-format -msgid "" -"- resetting first used heap value from %d to %d in block %u of attribute " -"fork of inode %\n" +msgid "block % for directory inode % is missing\n" msgstr "" -#: .././repair/attr_repair.c:600 +#: .././repair/dir2.c:1925 #, c-format -msgid "" -"- would reset first used value from %d to %d in block %u of attribute fork " -"of inode %\n" +msgid "can't read block % for directory inode %\n" msgstr "" -#: .././repair/attr_repair.c:610 +#: .././repair/dir2.c:1933 #, c-format msgid "" -"- resetting usedbytes cnt from %d to %d in block %u of attribute fork of " -"inode %\n" +"bad directory block magic # %#x in block % for directory inode " +"%\n" msgstr "" -#: .././repair/attr_repair.c:618 +#: .././repair/dir2.c:2014 #, c-format -msgid "" -"- would reset usedbytes cnt from %d to %d in block %u of attribute fork of %" -"\n" +msgid "bad size/format for directory %\n" msgstr "" -#: .././repair/attr_repair.c:670 +#: .././repair/dir2.c:2021 #, c-format -msgid "can't map block %u for attribute fork for inode %\n" +msgid "no . entry for directory %\n" msgstr "" -#: .././repair/attr_repair.c:679 +#: .././repair/dir2.c:2031 #, c-format -msgid "" -"can't read file block %u (fsbno %) for attribute fork of inode %" -"\n" +msgid "no .. entry for directory %\n" msgstr "" -#: .././repair/attr_repair.c:689 +#: .././repair/dir2.c:2033 #, c-format -msgid "bad attribute leaf magic %#x for inode %\n" +msgid "no .. entry for root directory %\n" msgstr "" -#: .././repair/attr_repair.c:720 +#: .././repair/phase6.c:64 #, c-format -msgid "" -"bad sibling back pointer for block %u in attribute fork for inode %\n" +msgid "malloc failed add_dotdot_update (%zu bytes)\n" msgstr "" -#: .././repair/attr_repair.c:747 +#: .././repair/phase6.c:216 #, c-format -msgid "bad hash path in attribute fork for inode %\n" +msgid "malloc failed in dir_hash_add (%zu bytes)\n" msgstr "" -#: .././repair/attr_repair.c:846 -#, c-format -msgid "block 0 of inode % attribute fork is missing\n" +#: .././repair/phase6.c:270 +msgid "ok" msgstr "" -#: .././repair/attr_repair.c:853 -#, c-format -msgid "agno of attribute fork of inode % out of regular partition\n" +#: .././repair/phase6.c:271 +msgid "duplicate leaf" msgstr "" -#: .././repair/attr_repair.c:861 -#, c-format -msgid "can't read block 0 of inode % attribute fork\n" +#: .././repair/phase6.c:272 +msgid "hash value mismatch" msgstr "" -#: .././repair/attr_repair.c:876 -#, c-format -msgid "" -"clearing forw/back pointers in block 0 for attributes in inode %\n" +#: .././repair/phase6.c:273 +msgid "no data entry" msgstr "" -#: .././repair/attr_repair.c:883 -#, c-format -msgid "" -"would clear forw/back pointers in block 0 for attributes in inode %\n" +#: .././repair/phase6.c:274 +msgid "no leaf entry" msgstr "" -#: .././repair/attr_repair.c:913 -#, c-format -msgid "bad attribute leaf magic # %#x for dir ino %\n" +#: .././repair/phase6.c:275 +msgid "bad stale count" msgstr "" -#: .././repair/attr_repair.c:938 +#: .././repair/phase6.c:283 #, c-format -msgid "Too many ACL entries, count %d\n" +msgid "bad hash table for directory inode % (%s): " msgstr "" -#: .././repair/attr_repair.c:947 -msgid "cannot malloc enough for ACL attribute\n" +#: .././repair/phase6.c:286 +msgid "rebuilding\n" msgstr "" -#: .././repair/attr_repair.c:948 -msgid "SKIPPING this ACL\n" +#: .././repair/phase6.c:288 +msgid "would rebuild\n" +msgstr "" + +#: .././repair/phase6.c:324 +msgid "calloc failed in dir_hash_init\n" +msgstr "" + +#: .././repair/phase6.c:471 +msgid "ran out of disk space!\n" msgstr "" -#: .././repair/attr_repair.c:994 .././repair/dinode.c:2182 +#: .././repair/phase6.c:473 #, c-format -msgid "illegal attribute format %d, ino %\n" +msgid "xfs_trans_reserve returned %d\n" msgstr "" -#: .././repair/dino_chunks.c:58 +#: .././repair/phase6.c:506 .././repair/phase6.c:615 #, c-format -msgid "cannot read agbno (%u/%u), disk block %\n" +msgid "couldn't iget realtime bitmap inode -- error - %d\n" msgstr "" -#: .././repair/dino_chunks.c:149 +#: .././repair/phase6.c:570 #, c-format -msgid "uncertain inode block %d/%d already known\n" +msgid "couldn't allocate realtime bitmap, error = %d\n" msgstr "" -#: .././repair/dino_chunks.c:165 .././repair/dino_chunks.c:437 -#: .././repair/dino_chunks.c:496 +#: .././repair/phase6.c:583 #, c-format -msgid "inode block %d/%d multiply claimed, (state %d)\n" +msgid "allocation of the realtime bitmap failed, error = %d\n" msgstr "" -#: .././repair/dino_chunks.c:172 .././repair/dino_chunks.c:501 +#: .././repair/phase6.c:629 #, c-format -msgid "inode block %d/%d bad state, (state %d)\n" +msgid "couldn't map realtime bitmap block %, error = %d\n" msgstr "" -#: .././repair/dino_chunks.c:444 +#: .././repair/phase6.c:642 #, c-format -msgid "uncertain inode block overlap, agbno = %d, ino = %\n" +msgid "" +"can't access block % (fsbno %) of realtime bitmap inode " +"%\n" msgstr "" -#: .././repair/dino_chunks.c:483 +#: .././repair/phase6.c:687 .././repair/phase6.c:762 #, c-format -msgid "uncertain inode block % already known\n" +msgid "couldn't iget realtime summary inode -- error - %d\n" msgstr "" -#: .././repair/dino_chunks.c:620 +#: .././repair/phase6.c:701 #, c-format -msgid "failed to allocate %zd bytes of memory\n" +msgid "couldn't map realtime summary inode block %, error = %d\n" msgstr "" -#: .././repair/dino_chunks.c:631 +#: .././repair/phase6.c:714 #, c-format -msgid "cannot read inode %, disk block %, cnt %d\n" +msgid "" +"can't access block % (fsbno %) of realtime summary inode " +"%\n" msgstr "" -#: .././repair/dino_chunks.c:747 .././repair/dino_chunks.c:922 +#: .././repair/phase6.c:831 #, c-format -msgid "bad state in block map %d\n" +msgid "couldn't allocate realtime summary inode, error = %d\n" msgstr "" -#: .././repair/dino_chunks.c:751 .././repair/dino_chunks.c:928 +#: .././repair/phase6.c:844 #, c-format -msgid "inode block % multiply claimed, state was %d\n" +msgid "allocation of the realtime summary ino failed, error = %d\n" msgstr "" -#: .././repair/dino_chunks.c:788 +#: .././repair/phase6.c:876 #, c-format -msgid "imap claims in-use inode % is free, " +msgid "could not iget root inode -- error - %d\n" msgstr "" -#: .././repair/dino_chunks.c:793 -msgid "correcting imap\n" +#: .././repair/phase6.c:958 +#, c-format +msgid "%d - couldn't iget root inode to obtain %s\n" msgstr "" -#: .././repair/dino_chunks.c:795 -msgid "would correct imap\n" +#: .././repair/phase6.c:991 +#, c-format +msgid "%s inode allocation failed %d\n" msgstr "" -#: .././repair/dino_chunks.c:841 +#: .././repair/phase6.c:1038 #, c-format -msgid "cleared root inode %\n" +msgid "can't make %s, createname error %d\n" msgstr "" -#: .././repair/dino_chunks.c:845 +#: .././repair/phase6.c:1058 #, c-format -msgid "would clear root inode %\n" +msgid "%s directory creation failed -- bmapf error %d\n" msgstr "" -#: .././repair/dino_chunks.c:853 +#: .././repair/phase6.c:1105 #, c-format -msgid "cleared realtime bitmap inode %\n" +msgid "%d - couldn't iget orphanage inode\n" msgstr "" -#: .././repair/dino_chunks.c:857 +#: .././repair/phase6.c:1118 #, c-format -msgid "would clear realtime bitmap inode %\n" +msgid "%d - couldn't iget disconnected inode\n" msgstr "" -#: .././repair/dino_chunks.c:865 +#: .././repair/phase6.c:1137 .././repair/phase6.c:1180 +#: .././repair/phase6.c:1237 #, c-format -msgid "cleared realtime summary inode %\n" +msgid "space reservation failed (%d), filesystem may be out of space\n" msgstr "" -#: .././repair/dino_chunks.c:869 +#: .././repair/phase6.c:1148 .././repair/phase6.c:1192 +#: .././repair/phase6.c:1248 #, c-format -msgid "would clear realtime summary inode %\n" +msgid "name create failed in %s (%d), filesystem may be out of space\n" msgstr "" -#: .././repair/dino_chunks.c:873 +#: .././repair/phase6.c:1161 #, c-format -msgid "cleared inode %\n" +msgid "creation of .. entry failed (%d), filesystem may be out of space\n" msgstr "" -#: .././repair/dino_chunks.c:876 +#: .././repair/phase6.c:1170 #, c-format -msgid "would have cleared inode %\n" +msgid "bmap finish failed (err - %d), filesystem may be out of space\n" msgstr "" -#: .././repair/dino_chunks.c:1083 .././repair/dino_chunks.c:1118 -#: .././repair/dino_chunks.c:1232 -msgid "found inodes not in the inode allocation tree\n" +#: .././repair/phase6.c:1211 +#, c-format +msgid "name replace op failed (%d), filesystem may be out of space\n" msgstr "" -#: .././repair/incore_ext.c:135 .././repair/incore_ext.c:562 -msgid "couldn't allocate new extent descriptor.\n" +#: .././repair/phase6.c:1218 .././repair/phase6.c:1258 +#: .././repair/phase6.c:1388 +#, c-format +msgid "bmap finish failed (%d), filesystem may be out of space\n" msgstr "" -#: .././repair/incore_ext.c:232 -msgid "duplicate bno extent range\n" +#: .././repair/phase6.c:1277 +msgid ", marking entry to be junked\n" msgstr "" -#: .././repair/incore_ext.c:369 -msgid ": duplicate bno extent range\n" +#: .././repair/phase6.c:1281 +msgid ", would junk entry\n" msgstr "" -#: .././repair/incore_ext.c:644 .././repair/incore_ext.c:699 -msgid "duplicate extent range\n" +#: .././repair/phase6.c:1315 +#, c-format +msgid "rebuilding directory inode %\n" msgstr "" -#: .././repair/incore_ext.c:752 .././repair/incore_ext.c:756 -msgid "couldn't malloc dup extent tree descriptor table\n" +#: .././repair/phase6.c:1338 +#, c-format +msgid "xfs_bmap_last_offset failed -- error - %d\n" msgstr "" -#: .././repair/incore_ext.c:761 -msgid "couldn't malloc free by-bno extent tree descriptor table\n" +#: .././repair/phase6.c:1345 +#, c-format +msgid "xfs_bunmapi failed -- error - %d\n" msgstr "" -#: .././repair/incore_ext.c:766 -msgid "couldn't malloc free by-bcnt extent tree descriptor table\n" +#: .././repair/phase6.c:1380 +#, c-format +msgid "" +"name create failed in ino % (%d), filesystem may be out of space\n" msgstr "" -#: .././repair/incore_ext.c:772 -msgid "couldn't malloc bno extent tree descriptor\n" +#: .././repair/phase6.c:1445 +#, c-format +msgid "shrink_inode failed inode % block %u\n" msgstr "" -#: .././repair/incore_ext.c:776 -msgid "couldn't malloc bcnt extent tree descriptor\n" +#: .././repair/phase6.c:1532 .././repair/phase6.c:2227 +#, c-format +msgid "realloc failed in %s (%zu bytes)\n" msgstr "" -#: .././repair/incore_ext.c:787 -msgid "couldn't malloc dup rt extent tree descriptor\n" +#: .././repair/phase6.c:1589 +#, c-format +msgid "empty data block %u in directory inode %: " msgstr "" -#: .././repair/incore_ino.c:47 -msgid "could not allocate nlink array\n" +#: .././repair/phase6.c:1593 +#, c-format +msgid "corrupt block %u in directory inode %: " msgstr "" -#: .././repair/incore_ino.c:233 -msgid "inode map malloc failed\n" +#: .././repair/phase6.c:1597 +msgid "junking block\n" msgstr "" -#: .././repair/incore_ino.c:340 -msgid "add_aginode_uncertain - duplicate inode range\n" +#: .././repair/phase6.c:1600 +msgid "would junk block\n" msgstr "" -#: .././repair/incore_ino.c:435 -msgid "add_inode - duplicate inode range\n" +#: .././repair/phase6.c:1622 +#, c-format +msgid "" +"bad directory block magic # %#x for directory inode % block %d: " msgstr "" -#: .././repair/incore_ino.c:529 +#: .././repair/phase6.c:1625 #, c-format -msgid "good inode list is --\n" +msgid "fixing magic # to %#x\n" msgstr "" -#: .././repair/incore_ino.c:532 +#: .././repair/phase6.c:1629 #, c-format -msgid "uncertain inode list is --\n" +msgid "would fix magic # to %#x\n" msgstr "" -#: .././repair/incore_ino.c:537 +#: .././repair/phase6.c:1650 #, c-format -msgid "agno %d -- no inodes\n" +msgid "directory inode % block %u has consecutive free entries: " +msgstr "" + +#: .././repair/phase6.c:1653 +msgid "joining together\n" +msgstr "" + +#: .././repair/phase6.c:1662 +msgid "would join together\n" msgstr "" -#: .././repair/incore_ino.c:541 +#: .././repair/phase6.c:1694 #, c-format -msgid "agno %d\n" +msgid "" +"entry \"%s\" in directory inode % points to non-existent inode " +"%" msgstr "" -#: .././repair/incore_ino.c:545 +#: .././repair/phase6.c:1711 #, c-format -msgid "\tptr = %lx, start = 0x%x, free = 0x%llx, confirmed = 0x%llx\n" +msgid "" +"entry \"%s\" in directory inode % points to free inode %" msgstr "" -#: .././repair/incore_ino.c:596 -msgid "couldn't malloc parent list table\n" +#: .././repair/phase6.c:1729 .././repair/phase6.c:2541 +#, c-format +msgid "%s (ino %) in root (%) is not a directory" msgstr "" -#: .././repair/incore_ino.c:607 .././repair/incore_ino.c:653 -msgid "couldn't memalign pentries table\n" +#: .././repair/phase6.c:1751 .././repair/phase6.c:2563 +#, c-format +msgid "entry \"%s\" (ino %) in dir % is a duplicate name" msgstr "" -#: .././repair/incore_ino.c:711 -msgid "could not malloc inode extra data\n" +#: .././repair/phase6.c:1782 +#, c-format +msgid "" +"entry \"%s\" (ino %) in dir % is not in the the first block" msgstr "" -#: .././repair/incore_ino.c:777 -msgid "couldn't malloc inode tree descriptor table\n" +#: .././repair/phase6.c:1808 +#, c-format +msgid "entry \"%s\" in dir % is not the first entry" msgstr "" -#: .././repair/incore_ino.c:781 -msgid "couldn't malloc uncertain ino tree descriptor table\n" +#: .././repair/phase6.c:1834 .././repair/phase6.c:2632 +#, c-format +msgid "" +"would fix ftype mismatch (%d/%d) in directory/child inode %/" +"%\n" msgstr "" -#: .././repair/incore_ino.c:786 -msgid "couldn't malloc inode tree descriptor\n" +#: .././repair/phase6.c:1839 .././repair/phase6.c:2637 +#, c-format +msgid "" +"fixing ftype mismatch (%d/%d) in directory/child inode %/%\n" msgstr "" -#: .././repair/incore_ino.c:790 -msgid "couldn't malloc uncertain ino tree descriptor\n" +#: .././repair/phase6.c:1872 +#, c-format +msgid "" +"entry \"%s\" in dir % points to an already connected directory inode " +"%\n" msgstr "" -#: .././repair/incore_ino.c:798 -msgid "couldn't malloc uncertain inode cache area\n" +#: .././repair/phase6.c:1881 .././repair/phase6.c:2601 +#, c-format +msgid "" +"entry \"%s\" in dir ino % doesn't have a .. entry, will set it in " +"ino %.\n" msgstr "" -#: .././repair/phase6.c:63 +#: .././repair/phase6.c:1891 #, c-format -msgid "malloc failed add_dotdot_update (%zu bytes)\n" +msgid "" +"entry \"%s\" in dir inode % inconsistent with .. value (%) " +"in ino %\n" msgstr "" -#: .././repair/phase6.c:174 +#: .././repair/phase6.c:1903 #, c-format -msgid "malloc failed in dir_hash_add (%zu bytes)\n" +msgid "\twill clear entry \"%s\"\n" msgstr "" -#: .././repair/phase6.c:228 -msgid "ok" +#: .././repair/phase6.c:1906 +#, c-format +msgid "\twould clear entry \"%s\"\n" msgstr "" -#: .././repair/phase6.c:229 -msgid "duplicate leaf" +#: .././repair/phase6.c:1953 +#, c-format +msgid "can't read block %u for directory inode %, error %d\n" msgstr "" -#: .././repair/phase6.c:230 -msgid "hash value mismatch" +#: .././repair/phase6.c:1971 .././repair/phase6.c:2071 +#, c-format +msgid "leaf block %u for directory inode % bad header\n" msgstr "" -#: .././repair/phase6.c:231 -msgid "no data entry" +#: .././repair/phase6.c:1988 +#, c-format +msgid "leaf block %u for directory inode % bad tail\n" msgstr "" -#: .././repair/phase6.c:232 -msgid "no leaf entry" +#: .././repair/phase6.c:2042 +#, c-format +msgid "can't read leaf block %u for directory inode %, error %d\n" msgstr "" -#: .././repair/phase6.c:233 -msgid "bad stale count" +#: .././repair/phase6.c:2057 +#, c-format +msgid "unknown magic number %#x for block %u in directory inode %\n" msgstr "" -#: .././repair/phase6.c:241 +#: .././repair/phase6.c:2096 #, c-format -msgid "bad hash table for directory inode % (%s): " +msgid "can't read freespace block %u for directory inode %, error %d\n" msgstr "" -#: .././repair/phase6.c:244 -msgid "rebuilding\n" +#: .././repair/phase6.c:2111 +#, c-format +msgid "free block %u for directory inode % bad header\n" msgstr "" -#: .././repair/phase6.c:246 -msgid "would rebuild\n" +#: .././repair/phase6.c:2121 +#, c-format +msgid "free block %u entry %i for directory ino % bad\n" msgstr "" -#: .././repair/phase6.c:282 -msgid "calloc failed in dir_hash_init\n" +#: .././repair/phase6.c:2131 +#, c-format +msgid "free block %u for directory inode % bad nused\n" msgstr "" -#: .././repair/phase6.c:412 -msgid "ran out of disk space!\n" +#: .././repair/phase6.c:2142 +#, c-format +msgid "missing freetab entry %u for directory inode %\n" msgstr "" -#: .././repair/phase6.c:414 +#: .././repair/phase6.c:2180 #, c-format -msgid "xfs_trans_reserve returned %d\n" +msgid "malloc failed in %s (% bytes)\n" msgstr "" -#: .././repair/phase6.c:443 .././repair/phase6.c:536 +#: .././repair/phase6.c:2194 #, c-format -msgid "couldn't iget realtime bitmap inode -- error - %d\n" +msgid "calloc failed in %s (%zu bytes)\n" msgstr "" -#: .././repair/phase6.c:493 +#: .././repair/phase6.c:2240 #, c-format -msgid "couldn't allocate realtime bitmap, error = %d\n" +msgid "can't read data block %u for directory inode % error %d\n" msgstr "" -#: .././repair/phase6.c:506 +#: .././repair/phase6.c:2333 +msgid "would junk entry\n" +msgstr "" + +#: .././repair/phase6.c:2357 +msgid "junking entry\n" +msgstr "" + +#: .././repair/phase6.c:2403 #, c-format -msgid "allocation of the realtime bitmap failed, error = %d\n" +msgid "would set .. in sf dir inode % to %\n" msgstr "" -#: .././repair/phase6.c:549 +#: .././repair/phase6.c:2407 #, c-format -msgid "couldn't map realtime bitmap block %, error = %d\n" +msgid "setting .. in sf dir inode % to %\n" +msgstr "" + +#: .././repair/phase6.c:2508 +#, c-format +msgid "" +"entry \"%s\" in shortform directory % references non-existent inode " +"%\n" msgstr "" -#: .././repair/phase6.c:562 +#: .././repair/phase6.c:2525 #, c-format msgid "" -"can't access block % (fsbno %) of realtime bitmap inode %" -"\n" +"entry \"%s\" in shortform directory inode % points to free inode " +"%\n" msgstr "" -#: .././repair/phase6.c:605 .././repair/phase6.c:676 +#: .././repair/phase6.c:2587 #, c-format -msgid "couldn't iget realtime summary inode -- error - %d\n" +msgid "" +"entry \"%s\" in directory inode % references already connected inode " +"%.\n" msgstr "" -#: .././repair/phase6.c:618 +#: .././repair/phase6.c:2610 #, c-format -msgid "couldn't map realtime summary inode block %, error = %d\n" +msgid "" +"entry \"%s\" in directory inode % not consistent with .. value " +"(%) in inode %,\n" msgstr "" -#: .././repair/phase6.c:631 +#: .././repair/phase6.c:2667 #, c-format -msgid "" -"can't access block % (fsbno %) of realtime summary inode %" -"\n" +msgid "would fix i8count in inode %\n" msgstr "" -#: .././repair/phase6.c:732 +#: .././repair/phase6.c:2682 #, c-format -msgid "couldn't allocate realtime summary inode, error = %d\n" +msgid "fixing i8count in inode %\n" msgstr "" -#: .././repair/phase6.c:745 +#: .././repair/phase6.c:2702 #, c-format -msgid "allocation of the realtime summary ino failed, error = %d\n" +msgid "setting size to % bytes to reflect junked entries\n" msgstr "" -#: .././repair/phase6.c:775 +#: .././repair/phase6.c:2741 .././repair/phase6.c:2745 .././repair/phase7.c:84 #, c-format -msgid "could not iget root inode -- error - %d\n" +msgid "couldn't map inode %, err = %d\n" msgstr "" -#: .././repair/phase6.c:845 -#, c-format -msgid "%d - couldn't iget root inode to obtain %s\n" +#: .././repair/phase6.c:2850 +msgid "recreating root directory .. entry\n" msgstr "" -#: .././repair/phase6.c:876 +#: .././repair/phase6.c:2868 #, c-format -msgid "%s inode allocation failed %d\n" +msgid "can't make \"..\" entry in root inode %, createname error %d\n" msgstr "" -#: .././repair/phase6.c:907 -#, c-format -msgid "can't make %s, createname error %d\n" +#: .././repair/phase6.c:2879 +msgid "would recreate root directory .. entry\n" msgstr "" -#: .././repair/phase6.c:927 +#: .././repair/phase6.c:2903 #, c-format -msgid "%s directory creation failed -- bmapf error %d\n" +msgid "would create missing \".\" entry in dir ino %\n" msgstr "" -#: .././repair/phase6.c:970 +#: .././repair/phase6.c:2910 #, c-format -msgid "%d - couldn't iget orphanage inode\n" +msgid "creating missing \".\" entry in dir ino %\n" msgstr "" -#: .././repair/phase6.c:983 +#: .././repair/phase6.c:2929 #, c-format -msgid "%d - couldn't iget disconnected inode\n" +msgid "can't make \".\" entry in dir ino %, createname error %d\n" msgstr "" -#: .././repair/phase6.c:1003 .././repair/phase6.c:1047 -#: .././repair/phase6.c:1104 .././repair/phase6.c:1747 +#: .././repair/phase6.c:3026 #, c-format -msgid "space reservation failed (%d), filesystem may be out of space\n" +msgid "disconnected dir inode %, " msgstr "" -#: .././repair/phase6.c:1014 .././repair/phase6.c:1059 -#: .././repair/phase6.c:1115 +#: .././repair/phase6.c:3028 #, c-format -msgid "name create failed in %s (%d), filesystem may be out of space\n" +msgid "disconnected inode %, " msgstr "" -#: .././repair/phase6.c:1027 +#: .././repair/phase6.c:3032 #, c-format -msgid "creation of .. entry failed (%d), filesystem may be out of space\n" +msgid "moving to %s\n" msgstr "" -#: .././repair/phase6.c:1036 +#: .././repair/phase6.c:3035 #, c-format -msgid "bmap finish failed (err - %d), filesystem may be out of space\n" +msgid "would move to %s\n" msgstr "" -#: .././repair/phase6.c:1078 -#, c-format -msgid "name replace op failed (%d), filesystem may be out of space\n" +#: .././repair/phase6.c:3120 +msgid "Phase 6 - check inode connectivity...\n" msgstr "" -#: .././repair/phase6.c:1085 .././repair/phase6.c:1125 -#: .././repair/phase6.c:1770 -#, c-format -msgid "bmap finish failed (%d), filesystem may be out of space\n" +#: .././repair/phase6.c:3134 +msgid "reinitializing root directory\n" msgstr "" -#: .././repair/phase6.c:1163 .././repair/phase6.c:1564 -msgid "dir" +#: .././repair/phase6.c:3139 +msgid "would reinitialize root directory\n" msgstr "" -#: .././repair/phase6.c:1172 .././repair/phase6.c:1176 -#, c-format -msgid "" -"can't map block %d in %s inode %, xfs_bmapi returns %d, nmap = %d\n" +#: .././repair/phase6.c:3145 +msgid "reinitializing realtime bitmap inode\n" msgstr "" -#: .././repair/phase6.c:1185 .././repair/phase6.c:1189 -#: .././repair/phase6.c:1643 .././repair/phase6.c:1647 -#, c-format -msgid "block %d in %s ino % doesn't exist\n" +#: .././repair/phase6.c:3149 +msgid "would reinitialize realtime bitmap inode\n" msgstr "" -#: .././repair/phase6.c:1244 .././repair/phase6.c:1248 -#, c-format -msgid "" -"can't map block %d in %s ino %, xfs_bmapi returns %d, nmap = %d\n" +#: .././repair/phase6.c:3155 +msgid "reinitializing realtime summary inode\n" msgstr "" -#: .././repair/phase6.c:1256 .././repair/phase6.c:1260 -#, c-format -msgid "block %d in %s inode % doesn't exist\n" +#: .././repair/phase6.c:3159 +msgid "would reinitialize realtime summary inode\n" msgstr "" -#: .././repair/phase6.c:1283 -msgid ", marking entry to be junked\n" +#: .././repair/phase6.c:3165 +msgid " - resetting contents of realtime bitmap and summary inodes\n" msgstr "" -#: .././repair/phase6.c:1287 -msgid ", would junk entry\n" +#: .././repair/phase6.c:3168 .././repair/phase6.c:3173 +msgid "Warning: realtime bitmap may be inconsistent\n" msgstr "" -#: .././repair/phase6.c:1404 -#, c-format -msgid "" -"entry \"%s\" in dir inode % points to non-existent inode %" +#: .././repair/phase6.c:3179 +msgid " - traversing filesystem ...\n" msgstr "" -#: .././repair/phase6.c:1422 -#, c-format -msgid "entry \"%s\" in dir inode % points to free inode %" +#: .././repair/phase6.c:3202 +msgid " - traversal finished ...\n" msgstr "" -#: .././repair/phase6.c:1438 .././repair/phase6.c:2105 -#: .././repair/phase6.c:2733 .././repair/phase6.c:3063 +#: .././repair/phase6.c:3203 #, c-format -msgid "%s (ino %) in root (%) is not a directory" +msgid " - moving disconnected inodes to %s ...\n" msgstr "" -#: .././repair/phase6.c:1460 .././repair/phase6.c:2126 -#: .././repair/phase6.c:2751 .././repair/phase6.c:3081 +#: .././repair/scan.c:83 .././repair/scan.c:138 #, c-format -msgid "entry \"%s\" (ino %) in dir % is a duplicate name" +msgid "can't read btree block %d/%d\n" msgstr "" -#: .././repair/phase6.c:1491 +#: .././repair/scan.c:87 .././repair/scan.c:150 #, c-format -msgid "" -"entry \"%s\" in dir ino % points to an already connected dir inode %" -",\n" +msgid "btree block %d/%d is suspect, error %d\n" msgstr "" -#: .././repair/phase6.c:1500 .././repair/phase6.c:2226 -#: .././repair/phase6.c:2785 .././repair/phase6.c:3113 +#: .././repair/scan.c:210 #, c-format -msgid "" -"entry \"%s\" in dir ino % doesn't have a .. entry, will set it in " -"ino %.\n" +msgid "bad magic # %#x in inode % (%s fork) bmbt block %\n" msgstr "" -#: .././repair/phase6.c:1508 +#: .././repair/scan.c:216 #, c-format msgid "" -"entry \"%s\" in dir ino % not consistent with .. value (%) " -"in ino %,\n" +"expected level %d got %d in inode %, (%s fork) bmbt block %\n" msgstr "" -#: .././repair/phase6.c:1522 .././repair/phase6.c:2249 +#: .././repair/scan.c:226 #, c-format -msgid "\twill clear entry \"%s\"\n" +msgid "expected owner inode %, got %llu, bmbt block %\n" msgstr "" -#: .././repair/phase6.c:1525 .././repair/phase6.c:2252 +#: .././repair/scan.c:246 #, c-format -msgid "\twould clear entry \"%s\"\n" +msgid "" +"bad fwd (right) sibling pointer (saw % parent block says %)\n" +"\tin inode % (%s fork) bmap btree block %\n" msgstr "" -#: .././repair/phase6.c:1570 +#: .././repair/scan.c:256 #, c-format -msgid "cannot map block 0 of directory inode %\n" +msgid "" +"bad back (left) sibling pointer (saw %llu parent block says %)\n" +"\tin inode % (%s fork) bmap btree block %\n" msgstr "" -#: .././repair/phase6.c:1593 +#: .././repair/scan.c:271 #, c-format msgid "" -"bad magic # (0x%x) for dir ino % leaf block (bno %u fsbno %" -")\n" +"bad back (left) sibling pointer (saw %llu should be NULL (0))\n" +"\tin inode % (%s fork) bmap btree block %\n" msgstr "" -#: .././repair/phase6.c:1630 .././repair/phase6.c:1634 +#: .././repair/scan.c:312 #, c-format -msgid "" -"can't map leaf block %d in dir %, xfs_bmapi returns %d, nmap = %d\n" +msgid "inode 0x%bmap block 0x% claimed, state is %d\n" msgstr "" -#: .././repair/phase6.c:1686 +#: .././repair/scan.c:319 #, c-format -msgid "rebuilding directory inode %\n" +msgid "inode 0x% bmap block 0x% claimed, state is %d\n" msgstr "" -#: .././repair/phase6.c:1711 +#: .././repair/scan.c:334 #, c-format -msgid "xfs_bmap_last_offset failed -- error - %d\n" +msgid "bad state %d, inode % bmap block 0x%\n" msgstr "" -#: .././repair/phase6.c:1718 +#: .././repair/scan.c:361 .././repair/scan.c:412 #, c-format -msgid "xfs_bunmapi failed -- error - %d\n" +msgid "inode % bad # of bmap records (%u, min - %u, max - %u)\n" msgstr "" -#: .././repair/phase6.c:1760 +#: .././repair/scan.c:391 #, c-format msgid "" -"name create failed in ino % (%d), filesystem may be out of space\n" +"out-of-order bmap key (file offset) in inode %, %s fork, fsbno " +"%\n" msgstr "" -#: .././repair/phase6.c:1825 +#: .././repair/scan.c:429 .././repair/dinode.c:963 #, c-format -msgid "shrink_inode failed inode % block %u\n" +msgid "bad bmap btree ptr 0x%llx in ino %\n" msgstr "" -#: .././repair/phase6.c:1906 +#: .././repair/scan.c:457 #, c-format -msgid "realloc failed in longform_dir2_entry_check_data (%zu bytes)\n" +msgid "" +"correcting bt key (was %llu, now %) in inode %\n" +"\t\t%s fork, btree block %\n" msgstr "" -#: .././repair/phase6.c:1963 +#: .././repair/scan.c:469 #, c-format -msgid "empty data block %u in directory inode %: " +msgid "" +"bad btree key (is %llu, should be %) in inode %\n" +"\t\t%s fork, btree block %\n" msgstr "" -#: .././repair/phase6.c:1967 +#: .././repair/scan.c:487 #, c-format -msgid "corrupt block %u in directory inode %: " +msgid "" +"bad fwd (right) sibling pointer (saw % should be NULLDFSBNO)\n" +"\tin inode % (%s fork) bmap btree block %\n" msgstr "" -#: .././repair/phase6.c:1971 -msgid "junking block\n" +#: .././repair/scan.c:545 +#, c-format +msgid "bad magic # %#x in bt%s block %d/%d\n" msgstr "" -#: .././repair/phase6.c:1974 -msgid "would junk block\n" +#: .././repair/scan.c:563 +#, c-format +msgid "expected level %d got %d in bt%s block %d/%d\n" msgstr "" -#: .././repair/phase6.c:1998 +#: .././repair/scan.c:577 #, c-format msgid "" -"bad directory block magic # %#x for directory inode % block %d: " +"%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n" msgstr "" -#: .././repair/phase6.c:2001 +#: .././repair/scan.c:597 .././repair/scan.c:698 #, c-format -msgid "fixing magic # to %#x\n" +msgid "bad btree nrecs (%u, min=%u, max=%u) in bt%s block %u/%u\n" msgstr "" -#: .././repair/phase6.c:2005 +#: .././repair/scan.c:615 #, c-format -msgid "would fix magic # to %#x\n" +msgid "invalid start block %u in record %u of %s btree block %u/%u\n" msgstr "" -#: .././repair/phase6.c:2026 +#: .././repair/scan.c:621 #, c-format -msgid "directory inode % block %u has consecutive free entries: " -msgstr "" - -#: .././repair/phase6.c:2029 -msgid "joining together\n" -msgstr "" - -#: .././repair/phase6.c:2038 -msgid "would join together\n" +msgid "invalid length %u in record %u of %s btree block %u/%u\n" msgstr "" -#: .././repair/phase6.c:2070 +#: .././repair/scan.c:668 #, c-format -msgid "" -"entry \"%s\" in directory inode % points to non-existent inode %" -"" +msgid "block (%d,%d-%d) multiply claimed by %s space tree, state - %d\n" msgstr "" -#: .././repair/phase6.c:2087 +#: .././repair/scan.c:775 #, c-format -msgid "" -"entry \"%s\" in directory inode % points to free inode %" +msgid "badly aligned inode rec (starting inode = %)\n" msgstr "" -#: .././repair/phase6.c:2157 +#: .././repair/scan.c:791 #, c-format -msgid "" -"entry \"%s\" (ino %) in dir % is not in the the first block" +msgid "bad starting inode # (% (0x%x 0x%x)) in ino rec, skipping rec\n" msgstr "" -#: .././repair/phase6.c:2182 +#: .././repair/scan.c:799 #, c-format -msgid "entry \"%s\" in dir % is not the first entry" +msgid "bad ending inode # (% (0x%x 0x%zx)) in ino rec, skipping rec\n" msgstr "" -#: .././repair/phase6.c:2217 +#: .././repair/scan.c:824 #, c-format msgid "" -"entry \"%s\" in dir % points to an already connected directory inode " -"%\n" +"inode chunk claims used block, inobt block - agno %d, bno %d, inopb %d\n" msgstr "" -#: .././repair/phase6.c:2236 +#: .././repair/scan.c:846 #, c-format msgid "" -"entry \"%s\" in dir inode % inconsistent with .. value (%) " -"in ino %\n" +"inode rec for ino % (%d/%d) overlaps existing rec (start %d/%d)\n" msgstr "" -#: .././repair/phase6.c:2290 .././repair/dir2.c:305 .././repair/dir2.c:663 -#: .././repair/dir2.c:1709 +#: .././repair/scan.c:893 #, c-format -msgid "can't read block %u for directory inode %\n" +msgid "ir_freecount/free mismatch, inode chunk %d/%u, freecount %d nfree %d\n" msgstr "" -#: .././repair/phase6.c:2307 .././repair/phase6.c:2387 +#: .././repair/scan.c:934 #, c-format -msgid "leaf block %u for directory inode % bad header\n" +msgid "badly aligned finobt inode rec (starting inode = %)\n" msgstr "" -#: .././repair/phase6.c:2326 +#: .././repair/scan.c:948 #, c-format -msgid "leaf block %u for directory inode % bad tail\n" +msgid "" +"bad starting inode # (% (0x%x 0x%x)) in finobt rec, skipping rec\n" msgstr "" -#: .././repair/phase6.c:2365 +#: .././repair/scan.c:956 #, c-format -msgid "can't read leaf block %u for directory inode %\n" +msgid "" +"bad ending inode # (% (0x%x 0x%zx)) in finobt rec, skipping rec\n" msgstr "" -#: .././repair/phase6.c:2377 +#: .././repair/scan.c:981 #, c-format -msgid "unknown magic number %#x for block %u in directory inode %\n" +msgid "" +"inode chunk claims untracked block, finobt block - agno %d, bno %d, inopb " +"%d\n" msgstr "" -#: .././repair/phase6.c:2411 +#: .././repair/scan.c:988 #, c-format -msgid "can't read freespace block %u for directory inode %\n" +msgid "" +"inode chunk claims used block, finobt block - agno %d, bno %d, inopb %d\n" msgstr "" -#: .././repair/phase6.c:2424 +#: .././repair/scan.c:1010 #, c-format -msgid "free block %u for directory inode % bad header\n" +msgid "" +"finobt rec for ino % (%d/%u) does not match existing rec (%d/%d)\n" msgstr "" -#: .././repair/phase6.c:2436 +#: .././repair/scan.c:1038 #, c-format -msgid "free block %u entry %i for directory ino % bad\n" +msgid "undiscovered finobt record, ino % (%d/%u)\n" msgstr "" -#: .././repair/phase6.c:2446 +#: .././repair/scan.c:1092 #, c-format -msgid "free block %u for directory inode % bad nused\n" +msgid "" +"finobt ir_freecount/free mismatch, inode chunk %d/%u, freecount %d nfree %d\n" msgstr "" -#: .././repair/phase6.c:2457 +#: .././repair/scan.c:1098 #, c-format -msgid "missing freetab entry %u for directory inode %\n" +msgid "finobt record with no free inodes, inode chunk %d/%u\n" msgstr "" -#: .././repair/phase6.c:2497 +#: .././repair/scan.c:1142 #, c-format -msgid "malloc failed in longform_dir2_entry_check (% bytes)\n" +msgid "bad magic # %#x in inobt block %d/%d\n" msgstr "" -#: .././repair/phase6.c:2527 +#: .././repair/scan.c:1150 #, c-format -msgid "realloc failed in longform_dir2_entry_check (%zu bytes)\n" +msgid "expected level %d got %d in inobt block %d/%d\n" msgstr "" -#: .././repair/phase6.c:2533 +#: .././repair/scan.c:1172 #, c-format -msgid "can't read data block %u for directory inode %\n" +msgid "inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n" msgstr "" -#: .././repair/phase6.c:2639 +#: .././repair/scan.c:1195 #, c-format -msgid "shortform dir inode % has null data entries \n" +msgid "dubious inode btree block header %d/%d\n" msgstr "" -#: .././repair/phase6.c:2707 +#: .././repair/scan.c:1306 #, c-format -msgid "" -"entry \"%s\" in shortform dir % references non-existent ino %" -"\n" +msgid "can't read agfl block for ag %d\n" msgstr "" -#: .././repair/phase6.c:2720 +#: .././repair/scan.c:1310 #, c-format -msgid "" -"entry \"%s\" in shortform dir inode % points to free inode %" -"\n" +msgid "agfl has bad CRC for ag %d\n" msgstr "" -#: .././repair/phase6.c:2776 +#: .././repair/scan.c:1331 #, c-format -msgid "" -"entry \"%s\" in dir % references already connected dir ino %" -".\n" +msgid "bad agbno %u in agfl, agno %d\n" msgstr "" -#: .././repair/phase6.c:2793 +#: .././repair/scan.c:1340 #, c-format -msgid "" -"entry \"%s\" in dir % not consistent with .. value (%) in " -"dir ino %.\n" -msgstr "" - -#: .././repair/phase6.c:2833 .././repair/phase6.c:3166 -msgid "junking entry\n" -msgstr "" - -#: .././repair/phase6.c:2837 .././repair/phase6.c:3170 -msgid "would junk entry\n" +msgid "freeblk count %d != flcount %d in ag %d\n" msgstr "" -#: .././repair/phase6.c:2876 .././repair/phase6.c:3228 +#: .././repair/scan.c:1366 #, c-format -msgid "setting size to % bytes to reflect junked entries\n" +msgid "bad agbno %u for btbno root, agno %d\n" msgstr "" -#: .././repair/phase6.c:2928 +#: .././repair/scan.c:1378 #, c-format -msgid "would set .. in sf dir inode % to %\n" +msgid "bad agbno %u for btbcnt root, agno %d\n" msgstr "" -#: .././repair/phase6.c:2932 +#: .././repair/scan.c:1394 #, c-format -msgid "setting .. in sf dir inode % to %\n" +msgid "agf_btreeblks %u, counted % in ag %u\n" msgstr "" -#: .././repair/phase6.c:3036 +#: .././repair/scan.c:1417 #, c-format -msgid "" -"entry \"%s\" in shortform directory % references non-existent inode %" -"\n" +msgid "bad agbno %u for inobt root, agno %d\n" msgstr "" -#: .././repair/phase6.c:3050 +#: .././repair/scan.c:1430 #, c-format -msgid "" -"entry \"%s\" in shortform directory inode % points to free inode %" -"\n" +msgid "bad agbno %u for finobt root, agno %d\n" msgstr "" -#: .././repair/phase6.c:3103 +#: .././repair/scan.c:1447 #, c-format -msgid "" -"entry \"%s\" in directory inode % references already connected inode " -"%.\n" +msgid "agi_freecount %u, counted %u in ag %u finobt\n" msgstr "" -#: .././repair/phase6.c:3123 +#: .././repair/scan.c:1457 #, c-format -msgid "" -"entry \"%s\" in directory inode % not consistent with .. value (%" -") in inode %,\n" +msgid "agi unlinked bucket %d is %u in ag %u (inode=%)\n" msgstr "" -#: .././repair/phase6.c:3194 -#, c-format -msgid "would fix i8count in inode %\n" +#: .././repair/scan.c:1488 +msgid "can't allocate memory for superblock\n" msgstr "" -#: .././repair/phase6.c:3207 -#, c-format -msgid "fixing i8count in inode %\n" +#: .././repair/scan.c:1495 +msgid "root superblock" msgstr "" -#: .././repair/phase6.c:3267 .././repair/phase6.c:3271 .././repair/phase7.c:85 -#, c-format -msgid "couldn't map inode %, err = %d\n" +#: .././repair/scan.c:1505 +msgid "agf block" msgstr "" -#: .././repair/phase6.c:3382 -msgid "missing root directory .. entry, cannot fix in V1 dir filesystem\n" +#: .././repair/scan.c:1514 +msgid "agi block" msgstr "" -#: .././repair/phase6.c:3389 +#: .././repair/scan.c:1535 #, c-format -msgid "" -"%d bad entries found in dir inode %, cannot fix in V1 dir " -"filesystem\n" +msgid "reset bad sb for ag %d\n" msgstr "" -#: .././repair/phase6.c:3396 +#: .././repair/scan.c:1538 #, c-format -msgid "" -"missing \".\" entry in dir ino %, cannot in fix V1 dir filesystem\n" +msgid "would reset bad sb for ag %d\n" msgstr "" -#: .././repair/phase6.c:3414 -msgid "recreating root directory .. entry\n" +#: .././repair/scan.c:1543 +#, c-format +msgid "reset bad agf for ag %d\n" msgstr "" -#: .././repair/phase6.c:3434 +#: .././repair/scan.c:1546 #, c-format -msgid "can't make \"..\" entry in root inode %, createname error %d\n" +msgid "would reset bad agf for ag %d\n" msgstr "" -#: .././repair/phase6.c:3445 -msgid "would recreate root directory .. entry\n" +#: .././repair/scan.c:1551 +#, c-format +msgid "reset bad agi for ag %d\n" msgstr "" -#: .././repair/phase6.c:3469 +#: .././repair/scan.c:1554 #, c-format -msgid "would create missing \".\" entry in dir ino %\n" +msgid "would reset bad agi for ag %d\n" msgstr "" -#: .././repair/phase6.c:3476 +#: .././repair/scan.c:1559 #, c-format -msgid "creating missing \".\" entry in dir ino %\n" +msgid "bad uncorrected agheader %d, skipping ag...\n" msgstr "" -#: .././repair/phase6.c:3500 +#: .././repair/scan.c:1622 #, c-format -msgid "can't make \".\" entry in dir ino %, createname error %d\n" +msgid "can't get %s for ag %d\n" msgstr "" -#: .././repair/phase6.c:3589 -#, c-format -msgid "disconnected dir inode %, " +#: .././repair/scan.c:1641 +msgid "no memory for ag header counts\n" msgstr "" -#: .././repair/phase6.c:3591 +#: .././repair/scan.c:1666 #, c-format -msgid "disconnected inode %, " +msgid "sb_icount %, counted %\n" msgstr "" -#: .././repair/phase6.c:3593 -msgid "cannot fix in V1 dir filesystem\n" +#: .././repair/scan.c:1671 +#, c-format +msgid "sb_ifree %, counted %\n" msgstr "" -#: .././repair/phase6.c:3597 +#: .././repair/scan.c:1676 #, c-format -msgid "moving to %s\n" +msgid "sb_fdblocks %, counted %\n" msgstr "" -#: .././repair/phase6.c:3600 -#, c-format -msgid "would move to %s\n" +#: .././repair/sb.c:103 +msgid "" +"\n" +"attempting to find secondary superblock...\n" msgstr "" -#: .././repair/phase6.c:3691 -msgid "Phase 6 - check inode connectivity...\n" +#: .././repair/sb.c:108 +msgid "error finding secondary superblock -- failed to memalign buffer\n" msgstr "" -#: .././repair/phase6.c:3705 -msgid "" -"need to reinitialize root directory, but not supported on V1 dir filesystem\n" +#: .././repair/sb.c:146 +msgid "found candidate secondary superblock...\n" msgstr "" -#: .././repair/phase6.c:3708 -msgid "reinitializing root directory\n" +#: .././repair/sb.c:158 +msgid "verified secondary superblock...\n" msgstr "" -#: .././repair/phase6.c:3713 -msgid "would reinitialize root directory\n" +#: .././repair/sb.c:163 +msgid "unable to verify superblock, continuing...\n" msgstr "" -#: .././repair/phase6.c:3719 -msgid "reinitializing realtime bitmap inode\n" +#: .././repair/sb.c:482 +msgid "failed to memalign superblock buffer\n" msgstr "" -#: .././repair/phase6.c:3723 -msgid "would reinitialize realtime bitmap inode\n" +#: .././repair/sb.c:489 +msgid "couldn't seek to offset 0 in filesystem\n" msgstr "" -#: .././repair/phase6.c:3729 -msgid "reinitializing realtime summary inode\n" +#: .././repair/sb.c:499 +msgid "primary superblock write failed!\n" msgstr "" -#: .././repair/phase6.c:3733 -msgid "would reinitialize realtime summary inode\n" +#: .././repair/sb.c:517 +#, c-format +msgid "error reading superblock %u -- failed to memalign buffer\n" msgstr "" -#: .././repair/phase6.c:3739 -msgid " - resetting contents of realtime bitmap and summary inodes\n" +#: .././repair/sb.c:528 +#, c-format +msgid "error reading superblock %u -- seek to offset % failed\n" msgstr "" -#: .././repair/phase6.c:3742 .././repair/phase6.c:3747 -msgid "Warning: realtime bitmap may be inconsistent\n" +#: .././repair/sb.c:537 +#, c-format +msgid "superblock read failed, offset %, size %d, ag %u, rval %d\n" msgstr "" -#: .././repair/phase6.c:3753 -msgid " - traversing filesystem ...\n" +#: .././repair/sb.c:585 +msgid "couldn't malloc geometry structure\n" msgstr "" -#: .././repair/phase6.c:3776 -msgid " - traversal finished ...\n" +#: .././repair/sb.c:735 +msgid "calloc failed in verify_set_primary_sb\n" msgstr "" -#: .././repair/phase6.c:3777 -#, c-format -msgid " - moving disconnected inodes to %s ...\n" +#: .././repair/sb.c:806 +msgid "" +"Only two AGs detected and they do not match - cannot validate filesystem " +"geometry.\n" +"Use the -o force_geometry option to proceed.\n" msgstr "" -#: .././repair/incore.c:230 -#, c-format -msgid "couldn't allocate realtime block map, size = %\n" +#: .././repair/sb.c:822 +msgid "" +"Only one AG detected - cannot validate filesystem geometry.\n" +"Use the -o force_geometry option to proceed.\n" msgstr "" -#: .././repair/incore.c:295 -msgid "couldn't allocate block map btree roots\n" +#: .././repair/sb.c:837 +msgid "Not enough matching superblocks - cannot proceed.\n" msgstr "" -#: .././repair/incore.c:299 -msgid "couldn't allocate block map locks\n" +#: .././repair/sb.c:852 +msgid "could not read superblock\n" msgstr "" -#: .././repair/phase2.c:65 +#: .././repair/phase2.c:69 #, c-format msgid "" "zero_log: cannot find log head/tail (xlog_find_tail=%d), zeroing it anyway\n" msgstr "" -#: .././repair/phase2.c:71 +#: .././repair/phase2.c:75 #, c-format msgid "zero_log: head block % tail block %\n" msgstr "" -#: .././repair/phase2.c:77 +#: .././repair/phase2.c:81 msgid "" "ALERT: The filesystem has valuable metadata changes in a log which is being\n" "destroyed because the -L option was used.\n" msgstr "" -#: .././repair/phase2.c:81 +#: .././repair/phase2.c:85 msgid "" "ERROR: The filesystem has valuable metadata changes in a log which needs to\n" "be replayed. Mount the filesystem to replay the log, and unmount it before\n" @@ -10441,1450 +10429,1193 @@ "of the filesystem before doing this.\n" msgstr "" -#: .././repair/phase2.c:123 +#: .././repair/phase2.c:127 msgid "" "This filesystem has an external log. Specify log device with the -l " "option.\n" msgstr "" -#: .././repair/phase2.c:126 +#: .././repair/phase2.c:130 #, c-format msgid "Phase 2 - using external log on %s\n" msgstr "" -#: .././repair/phase2.c:128 +#: .././repair/phase2.c:132 msgid "Phase 2 - using internal log\n" msgstr "" -#: .././repair/phase2.c:132 +#: .././repair/phase2.c:136 msgid " - zero log...\n" msgstr "" -#: .././repair/phase2.c:136 +#: .././repair/phase2.c:140 msgid " - scan filesystem freespace and inode maps...\n" msgstr "" -#: .././repair/phase2.c:152 +#: .././repair/phase2.c:156 msgid "root inode chunk not found\n" msgstr "" -#: .././repair/phase2.c:171 +#: .././repair/phase2.c:175 msgid " - found root inode chunk\n" msgstr "" -#: .././repair/phase2.c:177 +#: .././repair/phase2.c:181 msgid "root inode marked free, " msgstr "" -#: .././repair/phase2.c:180 .././repair/phase2.c:189 .././repair/phase2.c:198 -#: .././repair/dir2.c:1578 .././repair/dir2.c:1610 -msgid "correcting\n" -msgstr "" - -#: .././repair/phase2.c:182 .././repair/phase2.c:191 .././repair/phase2.c:200 -#: .././repair/dir2.c:1582 .././repair/dir2.c:1614 -msgid "would correct\n" -msgstr "" - -#: .././repair/phase2.c:186 +#: .././repair/phase2.c:190 msgid "realtime bitmap inode marked free, " msgstr "" -#: .././repair/phase2.c:195 +#: .././repair/phase2.c:199 msgid "realtime summary inode marked free, " msgstr "" -#: .././repair/progress.c:16 -msgid "inodes" -msgstr "" - -#: .././repair/progress.c:20 -msgid "directories" -msgstr "" - -#: .././repair/progress.c:22 -msgid "allocation groups" +#: .././repair/prefetch.c:532 +msgid "prefetch corruption\n" msgstr "" -#: .././repair/progress.c:24 -msgid "AGI unlinked buckets" +#: .././repair/prefetch.c:692 .././repair/prefetch.c:795 +#, c-format +msgid "failed to create prefetch thread: %s\n" msgstr "" -#: .././repair/progress.c:28 -msgid "realtime extents" +#: .././repair/prefetch.c:832 +msgid "failed to initialize prefetch mutex\n" msgstr "" -#: .././repair/progress.c:30 -msgid "unlinked lists" +#: .././repair/prefetch.c:834 .././repair/prefetch.c:836 +msgid "failed to initialize prefetch cond var\n" msgstr "" -#: .././repair/progress.c:37 +#: .././repair/bmap.c:53 #, c-format -msgid " - %02d:%02d:%02d: %s - %llu of %llu %s done\n" +msgid "" +"Number of extents requested in blkmap_alloc (%d) overflows 32 bits.\n" +"If this is not a corruption, then you will need a 64 bit system\n" +"to repair this filesystem.\n" msgstr "" -#: .././repair/progress.c:39 +#: .././repair/bmap.c:66 #, c-format -msgid " - %02d:%02d:%02d: %s - %llu %s done\n" -msgstr "" - -#: .././repair/progress.c:51 -msgid "scanning filesystem freespace" -msgstr "" - -#: .././repair/progress.c:53 -msgid "scanning agi unlinked lists" -msgstr "" - -#: .././repair/progress.c:55 -msgid "check uncertain AG inodes" -msgstr "" - -#: .././repair/progress.c:57 -msgid "process known inodes and inode discovery" -msgstr "" - -#: .././repair/progress.c:59 -msgid "process newly discovered inodes" -msgstr "" - -#: .././repair/progress.c:61 -msgid "setting up duplicate extent list" -msgstr "" - -#: .././repair/progress.c:63 -msgid "initialize realtime bitmap" -msgstr "" - -#: .././repair/progress.c:65 -msgid "reset realtime bitmaps" -msgstr "" - -#: .././repair/progress.c:67 -msgid "check for inodes claiming duplicate blocks" -msgstr "" - -#: .././repair/progress.c:69 -msgid "rebuild AG headers and trees" -msgstr "" - -#: .././repair/progress.c:71 -msgid "traversing filesystem" -msgstr "" - -#: .././repair/progress.c:73 -msgid "traversing all unattached subtrees" -msgstr "" - -#: .././repair/progress.c:75 -msgid "moving disconnected inodes to lost+found" +msgid "malloc failed in blkmap_alloc (%zu bytes)\n" msgstr "" -#: .././repair/progress.c:77 -msgid "verify and correct link counts" +#: .././repair/bmap.c:174 +#, c-format +msgid "blkmap_getn malloc failed (% bytes)\n" msgstr "" -#: .././repair/progress.c:79 -msgid "verify link counts" +#: .././repair/bmap.c:281 +#, c-format +msgid "" +"Number of extents requested in blkmap_grow (%d) overflows 32 bits.\n" +"You need a 64 bit system to repair this filesystem.\n" msgstr "" -#: .././repair/progress.c:118 -msgid "cannot malloc pointer to done vector\n" +#: .././repair/bmap.c:289 +#, c-format +msgid "" +"Number of extents requested in blkmap_grow (%d) overflowed the\n" +"maximum number of supported extents (%d).\n" msgstr "" -#: .././repair/progress.c:134 -msgid "unable to create progress report thread\n" +#: .././repair/bmap.c:297 +msgid "realloc failed in blkmap_grow\n" msgstr "" -#: .././repair/progress.c:173 -msgid "progress_rpt: cannot malloc progress msg buffer\n" +#: .././repair/dino_chunks.c:57 +#, c-format +msgid "cannot read agbno (%u/%u), disk block %\n" msgstr "" -#: .././repair/progress.c:187 -msgid "progress_rpt: cannot create timer\n" +#: .././repair/dino_chunks.c:150 +#, c-format +msgid "uncertain inode block %d/%d already known\n" msgstr "" -#: .././repair/progress.c:190 -msgid "progress_rpt: cannot set timer\n" +#: .././repair/dino_chunks.c:166 .././repair/dino_chunks.c:438 +#: .././repair/dino_chunks.c:497 +#, c-format +msgid "inode block %d/%d multiply claimed, (state %d)\n" msgstr "" -#: .././repair/progress.c:214 -msgid "progress_rpt: cannot lock progress mutex\n" +#: .././repair/dino_chunks.c:173 .././repair/dino_chunks.c:502 +#, c-format +msgid "inode block %d/%d bad state, (state %d)\n" msgstr "" -#: .././repair/progress.c:251 .././repair/progress.c:354 +#: .././repair/dino_chunks.c:445 #, c-format -msgid "%s" +msgid "uncertain inode block overlap, agbno = %d, ino = %\n" msgstr "" -#: .././repair/progress.c:259 +#: .././repair/dino_chunks.c:484 #, c-format -msgid "" -"\t- %02d:%02d:%02d: Phase %d: elapsed time %s - processed %d %s per minute\n" +msgid "uncertain inode block % already known\n" msgstr "" -#: .././repair/progress.c:264 +#: .././repair/dino_chunks.c:621 #, c-format -msgid "" -"\t- %02d:%02d:%02d: Phase %d: %%% done - estimated remaining time %" -"s\n" +msgid "failed to allocate %zd bytes of memory\n" msgstr "" -#: .././repair/progress.c:272 -msgid "progress_rpt: error unlock msg mutex\n" +#: .././repair/dino_chunks.c:633 +#, c-format +msgid "cannot read inode %, disk block %, cnt %d\n" msgstr "" -#: .././repair/progress.c:278 -msgid "cannot delete timer\n" +#: .././repair/dino_chunks.c:750 .././repair/dino_chunks.c:939 +#, c-format +msgid "bad state in block map %d\n" msgstr "" -#: .././repair/progress.c:292 -msgid "set_progress_msg: cannot lock progress mutex\n" +#: .././repair/dino_chunks.c:754 .././repair/dino_chunks.c:945 +#, c-format +msgid "inode block % multiply claimed, state was %d\n" msgstr "" -#: .././repair/progress.c:302 -msgid "set_progress_msg: cannot unlock progress mutex\n" +#: .././repair/dino_chunks.c:796 +#, c-format +msgid "imap claims in-use inode % is free, " msgstr "" -#: .././repair/progress.c:322 -msgid "print_final_rpt: cannot lock progress mutex\n" +#: .././repair/dino_chunks.c:801 +msgid "correcting imap\n" msgstr "" -#: .././repair/progress.c:358 -msgid "print_final_rpt: cannot unlock progress mutex\n" +#: .././repair/dino_chunks.c:803 +msgid "would correct imap\n" msgstr "" -#: .././repair/progress.c:407 +#: .././repair/dino_chunks.c:858 #, c-format -msgid "%02d:%02d:%02d" +msgid "cleared root inode %\n" msgstr "" -#: .././repair/progress.c:429 +#: .././repair/dino_chunks.c:862 #, c-format -msgid "%d week" -msgstr "" - -#: .././repair/progress.c:430 .././repair/progress.c:440 -#: .././repair/progress.c:456 .././repair/progress.c:474 -#: .././repair/progress.c:489 -msgid "s" +msgid "would clear root inode %\n" msgstr "" -#: .././repair/progress.c:439 +#: .././repair/dino_chunks.c:870 #, c-format -msgid "%d day" -msgstr "" - -#: .././repair/progress.c:446 .././repair/progress.c:463 -#: .././repair/progress.c:481 .././repair/progress.c:491 -msgid ", " +msgid "cleared realtime bitmap inode %\n" msgstr "" -#: .././repair/progress.c:455 +#: .././repair/dino_chunks.c:874 #, c-format -msgid "%d hour" +msgid "would clear realtime bitmap inode %\n" msgstr "" -#: .././repair/progress.c:473 +#: .././repair/dino_chunks.c:882 #, c-format -msgid "%d minute" +msgid "cleared realtime summary inode %\n" msgstr "" -#: .././repair/progress.c:488 +#: .././repair/dino_chunks.c:886 #, c-format -msgid "%d second" +msgid "would clear realtime summary inode %\n" msgstr "" -#: .././repair/progress.c:509 +#: .././repair/dino_chunks.c:890 #, c-format -msgid "" -"\n" -" XFS_REPAIR Summary %s\n" +msgid "cleared inode %\n" msgstr "" -#: .././repair/progress.c:511 -msgid "Phase\t\tStart\t\tEnd\t\tDuration\n" +#: .././repair/dino_chunks.c:893 +#, c-format +msgid "would have cleared inode %\n" msgstr "" -#: .././repair/progress.c:516 .././repair/progress.c:519 -#, c-format -msgid "Phase %d:\tSkipped\n" +#: .././repair/dino_chunks.c:1100 .././repair/dino_chunks.c:1135 +#: .././repair/dino_chunks.c:1249 +msgid "found inodes not in the inode allocation tree\n" msgstr "" -#: .././repair/progress.c:523 -#, c-format -msgid "Phase %d:\t%02d/%02d %02d:%02d:%02d\t%02d/%02d %02d:%02d:%02d\t%s\n" +#: .././repair/dinode.c:52 +msgid "real-time" msgstr "" -#: .././repair/progress.c:529 -#, c-format -msgid "" -"\n" -"Total run time: %s\n" +#: .././repair/dinode.c:53 +msgid "regular" msgstr "" -#: .././repair/dinode.c:46 +#: .././repair/dinode.c:76 #, c-format msgid "clearing inode % attributes\n" msgstr "" -#: .././repair/dinode.c:49 +#: .././repair/dinode.c:79 #, c-format msgid "would have cleared inode % attributes\n" msgstr "" -#: .././repair/dinode.c:424 +#: .././repair/dinode.c:443 #, c-format msgid "" -"inode % - bad rt extent start block number %, offset %" -"\n" +"inode % - bad rt extent start block number %, offset " +"%\n" msgstr "" -#: .././repair/dinode.c:432 +#: .././repair/dinode.c:451 #, c-format msgid "" -"inode % - bad rt extent last block number %, offset %" -"\n" +"inode % - bad rt extent last block number %, offset " +"%\n" msgstr "" -#: .././repair/dinode.c:440 +#: .././repair/dinode.c:459 #, c-format msgid "" "inode % - bad rt extent overflows - start %, end %, " "offset %\n" msgstr "" -#: .././repair/dinode.c:457 +#: .././repair/dinode.c:476 #, c-format msgid "malformed rt inode extent [% %] (fs rtext size = %u)\n" msgstr "" -#: .././repair/dinode.c:478 +#: .././repair/dinode.c:497 #, c-format msgid "" -"data fork in rt ino % claims dup rt extent,off - %, start - %" -", count %\n" +"data fork in rt ino % claims dup rt extent,off - %, start - " +"%, count %\n" msgstr "" -#: .././repair/dinode.c:497 +#: .././repair/dinode.c:516 #, c-format msgid "bad state in rt block map %\n" msgstr "" -#: .././repair/dinode.c:503 +#: .././repair/dinode.c:522 #, c-format msgid "" "data fork in rt inode % found metadata block % in rt bmap\n" msgstr "" -#: .././repair/dinode.c:511 +#: .././repair/dinode.c:530 #, c-format msgid "data fork in rt inode % claims used rt block %\n" msgstr "" -#: .././repair/dinode.c:517 +#: .././repair/dinode.c:536 #, c-format msgid "illegal state %d in rt block map %\n" msgstr "" -#: .././repair/dinode.c:573 -msgid "real-time" -msgstr "" - -#: .././repair/dinode.c:575 -msgid "regular" -msgstr "" - -#: .././repair/dinode.c:585 +#: .././repair/dinode.c:599 #, c-format msgid "" "bmap rec out of order, inode % entry %d [o s c] [% % " "%], %d [% % %]\n" msgstr "" -#: .././repair/dinode.c:601 +#: .././repair/dinode.c:615 #, c-format msgid "" "zero length extent (off = %, fsbno = %) in ino %\n" msgstr "" -#: .././repair/dinode.c:632 +#: .././repair/dinode.c:646 #, c-format msgid "" -"inode % - bad extent starting block number %, offset %" -"\n" +"inode % - bad extent starting block number %, offset " +"%\n" msgstr "" -#: .././repair/dinode.c:640 +#: .././repair/dinode.c:654 #, c-format msgid "" "inode % - bad extent last block number %, offset %\n" msgstr "" -#: .././repair/dinode.c:648 -#, c-format -msgid "" -"inode % - bad extent overflows - start %, end %, " -"offset %\n" -msgstr "" - -#: .././repair/dinode.c:658 -#, c-format -msgid "" -"inode % - extent offset too large - start %, count %" -", offset %\n" -msgstr "" - -#: .././repair/dinode.c:678 -#, c-format -msgid "" -"Fatal error: inode % - blkmap_set_ext(): %s\n" -"\t%s fork, off - %, start - %, cnt %\n" -msgstr "" - -#: .././repair/dinode.c:709 -#, c-format -msgid "" -"%s fork in ino % claims dup extent, off - %, start - %" -", cnt %\n" -msgstr "" - -#: .././repair/dinode.c:728 -#, c-format -msgid "%s fork in ino % claims free block %\n" -msgstr "" - -#: .././repair/dinode.c:736 -#, c-format -msgid "bad state in block map %\n" -msgstr "" - -#: .././repair/dinode.c:742 -#, c-format -msgid "%s fork in inode % claims metadata block %\n" -msgstr "" - -#: .././repair/dinode.c:750 -#, c-format -msgid "%s fork in %s inode % claims used block %\n" -msgstr "" - -#: .././repair/dinode.c:756 +#: .././repair/dinode.c:662 #, c-format -msgid "illegal state %d in block map %\n" +msgid "" +"inode % - bad extent overflows - start %, end %, " +"offset %\n" msgstr "" -#: .././repair/dinode.c:769 +#: .././repair/dinode.c:672 #, c-format -msgid "correcting nextents for inode %\n" +msgid "" +"inode % - extent offset too large - start %, count " +"%, offset %\n" msgstr "" -#: .././repair/dinode.c:841 +#: .././repair/dinode.c:693 #, c-format -msgid "cannot read inode (%u/%u), disk block %\n" +msgid "" +"Fatal error: inode % - blkmap_set_ext(): %s\n" +"\t%s fork, off - %, start - %, cnt %\n" msgstr "" -#: .././repair/dinode.c:952 .././repair/dinode.c:1009 +#: .././repair/dinode.c:724 #, c-format -msgid "cannot read bmap block %\n" +msgid "" +"%s fork in ino % claims dup extent, off - %, start - " +"%, cnt %\n" msgstr "" -#: .././repair/dinode.c:973 +#: .././repair/dinode.c:743 #, c-format -msgid "# of bmap records in inode % exceeds max (%u, max - %u)\n" +msgid "%s fork in ino % claims free block %\n" msgstr "" -#: .././repair/dinode.c:981 +#: .././repair/dinode.c:751 #, c-format -msgid "" -"- # of bmap records in inode % less than minimum (%u, min - %u), " -"proceeding ...\n" +msgid "bad state in block map %\n" msgstr "" -#: .././repair/dinode.c:1023 +#: .././repair/dinode.c:757 #, c-format -msgid "" -"# of bmap records in inode % greater than maximum (%u, max - %u)\n" +msgid "%s fork in inode % claims metadata block %\n" msgstr "" -#: .././repair/dinode.c:1030 +#: .././repair/dinode.c:765 #, c-format -msgid "" -"- # of bmap records in inode % less than minimum (%u, min - %u), " -"continuing...\n" +msgid "%s fork in %s inode % claims used block %\n" msgstr "" -#: .././repair/dinode.c:1046 +#: .././repair/dinode.c:771 #, c-format -msgid "could not map block %\n" +msgid "illegal state %d in block map %\n" msgstr "" -#: .././repair/dinode.c:1080 +#: .././repair/dinode.c:784 #, c-format -msgid "get_bmapi() called for local inode %\n" +msgid "correcting nextents for inode %\n" msgstr "" -#: .././repair/dinode.c:1088 +#: .././repair/dinode.c:857 #, c-format -msgid "bad inode format for inode %\n" +msgid "cannot read inode (%u/%u), disk block %\n" msgstr "" -#: .././repair/dinode.c:1152 +#: .././repair/dinode.c:928 #, c-format msgid "bad level %d in inode % bmap btree root block\n" msgstr "" -#: .././repair/dinode.c:1158 +#: .././repair/dinode.c:934 #, c-format msgid "bad numrecs 0 in inode % bmap btree root block\n" msgstr "" -#: .././repair/dinode.c:1167 +#: .././repair/dinode.c:943 #, c-format msgid "" -"indicated size of %s btree root (%d bytes) greater than space in inode %" -" %s fork\n" +"indicated size of %s btree root (%d bytes) greater than space in inode " +"% %s fork\n" msgstr "" -#: .././repair/dinode.c:1206 +#: .././repair/dinode.c:982 #, c-format msgid "" "correcting key in bmbt root (was %llu, now %) in inode % %s " "fork\n" msgstr "" -#: .././repair/dinode.c:1218 +#: .././repair/dinode.c:994 #, c-format msgid "" -"bad key in bmbt root (is %llu, would reset to %) in inode % %" -"s fork\n" +"bad key in bmbt root (is %llu, would reset to %) in inode % " +"%s fork\n" msgstr "" -#: .././repair/dinode.c:1235 +#: .././repair/dinode.c:1011 #, c-format msgid "out of order bmbt root key % in inode % %s fork\n" msgstr "" -#: .././repair/dinode.c:1252 +#: .././repair/dinode.c:1028 #, c-format msgid "" "extent count for ino % %s fork too low (%) for file format\n" msgstr "" -#: .././repair/dinode.c:1263 +#: .././repair/dinode.c:1039 #, c-format msgid "bad fwd (right) sibling pointer (saw % should be NULLDFSBNO)\n" msgstr "" -#: .././repair/dinode.c:1266 +#: .././repair/dinode.c:1042 #, c-format msgid "\tin inode % (%s fork) bmap btree block %\n" msgstr "" -#: .././repair/dinode.c:1339 +#: .././repair/dinode.c:1124 #, c-format msgid "local inode % data fork is too large (size = %lld, max = %d)\n" msgstr "" -#: .././repair/dinode.c:1347 +#: .././repair/dinode.c:1132 #, c-format msgid "local inode % attr fork too large (size %d, max = %d)\n" msgstr "" -#: .././repair/dinode.c:1354 +#: .././repair/dinode.c:1139 #, c-format msgid "local inode % attr too small (size = %d, min size = %zd)\n" msgstr "" -#: .././repair/dinode.c:1378 +#: .././repair/dinode.c:1163 #, c-format msgid "" "mismatch between format (%d) and size (%) in symlink ino %\n" msgstr "" -#: .././repair/dinode.c:1385 +#: .././repair/dinode.c:1170 #, c-format msgid "" -"mismatch between format (%d) and size (%) in symlink inode %" -"\n" +"mismatch between format (%d) and size (%) in symlink inode " +"%\n" msgstr "" -#: .././repair/dinode.c:1400 +#: .././repair/dinode.c:1185 #, c-format msgid "bad number of extents (%d) in symlink % data fork\n" msgstr "" -#: .././repair/dinode.c:1413 +#: .././repair/dinode.c:1198 #, c-format msgid "bad extent #%d offset (%) in symlink % data fork\n" msgstr "" -#: .././repair/dinode.c:1419 +#: .././repair/dinode.c:1204 #, c-format msgid "bad extent #%d count (%) in symlink % data fork\n" msgstr "" -#: .././repair/dinode.c:1474 +#: .././repair/dinode.c:1262 #, c-format -msgid "symlink in inode % too long (%llu chars)\n" +msgid "cannot read inode %, file block %d, NULL disk block\n" msgstr "" -#: .././repair/dinode.c:1507 +#: .././repair/dinode.c:1284 #, c-format msgid "cannot read inode %, file block %d, disk block %\n" msgstr "" -#: .././repair/dinode.c:1529 +#: .././repair/dinode.c:1290 +#, c-format +msgid "" +"Bad symlink buffer CRC, block %, inode %.\n" +"Correcting CRC, but symlink may be bad.\n" +msgstr "" + +#: .././repair/dinode.c:1303 +#, c-format +msgid "bad symlink header ino %, file block %d, disk block %\n" +msgstr "" + +#: .././repair/dinode.c:1346 +#, c-format +msgid "symlink in inode % too long (%llu chars)\n" +msgstr "" + +#: .././repair/dinode.c:1378 #, c-format msgid "found illegal null character in symlink inode %\n" msgstr "" -#: .././repair/dinode.c:1543 .././repair/dinode.c:1553 +#: .././repair/dinode.c:1392 .././repair/dinode.c:1402 #, c-format msgid "component of symlink in inode % too long\n" msgstr "" -#: .././repair/dinode.c:1579 +#: .././repair/dinode.c:1428 #, c-format msgid "inode % has bad inode type (IFMNT)\n" msgstr "" -#: .././repair/dinode.c:1590 +#: .././repair/dinode.c:1439 #, c-format msgid "size of character device inode % != 0 (% bytes)\n" msgstr "" -#: .././repair/dinode.c:1595 +#: .././repair/dinode.c:1444 #, c-format msgid "size of block device inode % != 0 (% bytes)\n" msgstr "" -#: .././repair/dinode.c:1600 +#: .././repair/dinode.c:1449 #, c-format msgid "size of socket inode % != 0 (% bytes)\n" msgstr "" -#: .././repair/dinode.c:1605 +#: .././repair/dinode.c:1454 #, c-format msgid "size of fifo inode % != 0 (% bytes)\n" msgstr "" -#: .././repair/dinode.c:1609 +#: .././repair/dinode.c:1458 #, c-format msgid "Internal error - process_misc_ino_types, illegal type %d\n" msgstr "" -#: .././repair/dinode.c:1636 +#: .././repair/dinode.c:1485 #, c-format msgid "size of character device inode % != 0 (% blocks)\n" msgstr "" -#: .././repair/dinode.c:1641 +#: .././repair/dinode.c:1490 #, c-format msgid "size of block device inode % != 0 (% blocks)\n" msgstr "" -#: .././repair/dinode.c:1646 +#: .././repair/dinode.c:1495 #, c-format msgid "size of socket inode % != 0 (% blocks)\n" msgstr "" -#: .././repair/dinode.c:1651 +#: .././repair/dinode.c:1500 #, c-format msgid "size of fifo inode % != 0 (% blocks)\n" msgstr "" -#: .././repair/dinode.c:1729 +#: .././repair/dinode.c:1578 #, c-format msgid "root inode % has bad type 0x%x\n" msgstr "" -#: .././repair/dinode.c:1733 +#: .././repair/dinode.c:1582 msgid "resetting to directory\n" msgstr "" -#: .././repair/dinode.c:1737 +#: .././repair/dinode.c:1586 msgid "would reset to directory\n" msgstr "" -#: .././repair/dinode.c:1743 +#: .././repair/dinode.c:1592 #, c-format msgid "user quota inode % has bad type 0x%x\n" msgstr "" -#: .././repair/dinode.c:1752 +#: .././repair/dinode.c:1601 #, c-format msgid "group quota inode % has bad type 0x%x\n" msgstr "" -#: .././repair/dinode.c:1762 +#: .././repair/dinode.c:1610 +#, c-format +msgid "project quota inode % has bad type 0x%x\n" +msgstr "" + +#: .././repair/dinode.c:1620 #, c-format msgid "realtime summary inode % has bad type 0x%x, " msgstr "" -#: .././repair/dinode.c:1765 .././repair/dinode.c:1786 +#: .././repair/dinode.c:1623 .././repair/dinode.c:1644 msgid "resetting to regular file\n" msgstr "" -#: .././repair/dinode.c:1769 .././repair/dinode.c:1790 +#: .././repair/dinode.c:1627 .././repair/dinode.c:1648 msgid "would reset to regular file\n" msgstr "" -#: .././repair/dinode.c:1774 +#: .././repair/dinode.c:1632 #, c-format msgid "bad # of extents (%u) for realtime summary inode %\n" msgstr "" -#: .././repair/dinode.c:1783 +#: .././repair/dinode.c:1641 #, c-format msgid "realtime bitmap inode % has bad type 0x%x, " msgstr "" -#: .././repair/dinode.c:1795 +#: .././repair/dinode.c:1653 #, c-format msgid "bad # of extents (%u) for realtime bitmap inode %\n" msgstr "" -#: .././repair/dinode.c:1830 +#: .././repair/dinode.c:1688 #, c-format msgid "" -"mismatch between format (%d) and size (%) in directory ino %" -"\n" +"mismatch between format (%d) and size (%) in directory ino " +"%\n" msgstr "" -#: .././repair/dinode.c:1836 +#: .././repair/dinode.c:1694 #, c-format msgid "directory inode % has bad size %\n" msgstr "" -#: .././repair/dinode.c:1844 +#: .././repair/dinode.c:1702 #, c-format msgid "bad data fork in symlink %\n" msgstr "" -#: .././repair/dinode.c:1865 +#: .././repair/dinode.c:1723 #, c-format msgid "found inode % claiming to be a real-time file\n" msgstr "" -#: .././repair/dinode.c:1874 +#: .././repair/dinode.c:1732 #, c-format msgid "" -"realtime bitmap inode % has bad size % (should be %" -")\n" +"realtime bitmap inode % has bad size % (should be " +"%)\n" msgstr "" -#: .././repair/dinode.c:1885 +#: .././repair/dinode.c:1743 #, c-format msgid "" "realtime summary inode % has bad size % (should be %d)\n" msgstr "" -#: .././repair/dinode.c:1913 +#: .././repair/dinode.c:1771 #, c-format msgid "bad attr fork offset %d in dev inode %, should be %d\n" msgstr "" -#: .././repair/dinode.c:1924 +#: .././repair/dinode.c:1783 #, c-format msgid "bad attr fork offset %d in inode %, max=%d\n" msgstr "" -#: .././repair/dinode.c:1931 +#: .././repair/dinode.c:1790 #, c-format msgid "unexpected inode format %d\n" msgstr "" -#: .././repair/dinode.c:1952 +#: .././repair/dinode.c:1811 #, c-format msgid "correcting nblocks for inode %, was %llu - counted %\n" msgstr "" -#: .././repair/dinode.c:1959 +#: .././repair/dinode.c:1818 #, c-format msgid "bad nblocks %llu for inode %, would reset to %\n" msgstr "" -#: .././repair/dinode.c:1967 +#: .././repair/dinode.c:1826 #, c-format msgid "too many data fork extents (%) in inode %\n" msgstr "" -#: .././repair/dinode.c:1974 +#: .././repair/dinode.c:1833 #, c-format msgid "correcting nextents for inode %, was %d - counted %\n" msgstr "" -#: .././repair/dinode.c:1982 +#: .././repair/dinode.c:1841 #, c-format msgid "bad nextents %d for inode %, would reset to %\n" msgstr "" -#: .././repair/dinode.c:1990 +#: .././repair/dinode.c:1849 #, c-format msgid "too many attr fork extents (%) in inode %\n" msgstr "" -#: .././repair/dinode.c:1997 +#: .././repair/dinode.c:1856 #, c-format msgid "correcting anextents for inode %, was %d - counted %\n" msgstr "" -#: .././repair/dinode.c:2004 +#: .././repair/dinode.c:1863 #, c-format msgid "bad anextents %d for inode %, would reset to %\n" msgstr "" -#: .././repair/dinode.c:2016 +#: .././repair/dinode.c:1875 #, c-format msgid "nblocks (%) smaller than nextents for inode %\n" msgstr "" -#: .././repair/dinode.c:2069 .././repair/dinode.c:2107 +#: .././repair/dinode.c:1940 .././repair/dinode.c:1978 #, c-format msgid "unknown format %d, ino % (mode = %d)\n" msgstr "" -#: .././repair/dinode.c:2074 +#: .././repair/dinode.c:1945 #, c-format msgid "bad data fork in inode %\n" msgstr "" -#: .././repair/dinode.c:2145 +#: .././repair/dinode.c:2016 #, c-format msgid "bad attribute format %d in inode %, " msgstr "" -#: .././repair/dinode.c:2148 +#: .././repair/dinode.c:2019 msgid "resetting value\n" msgstr "" -#: .././repair/dinode.c:2152 +#: .././repair/dinode.c:2023 msgid "would reset value\n" msgstr "" -#: .././repair/dinode.c:2197 +#: .././repair/dinode.c:2068 #, c-format msgid "bad attribute fork in inode %" msgstr "" -#: .././repair/dinode.c:2201 +#: .././repair/dinode.c:2072 msgid ", clearing attr fork\n" msgstr "" -#: .././repair/dinode.c:2210 +#: .././repair/dinode.c:2081 msgid ", would clear attr fork\n" msgstr "" -#: .././repair/dinode.c:2238 +#: .././repair/dinode.c:2109 #, c-format msgid "illegal attribute fmt %d, ino %\n" msgstr "" -#: .././repair/dinode.c:2258 +#: .././repair/dinode.c:2129 #, c-format msgid "problem with attribute contents in inode %\n" msgstr "" -#: .././repair/dinode.c:2266 +#: .././repair/dinode.c:2137 msgid "would clear attr fork\n" msgstr "" -#: .././repair/dinode.c:2309 +#: .././repair/dinode.c:2180 #, c-format msgid "version 2 inode % claims > %u links, " msgstr "" -#: .././repair/dinode.c:2313 +#: .././repair/dinode.c:2184 msgid "updating superblock version number\n" msgstr "" -#: .././repair/dinode.c:2316 +#: .././repair/dinode.c:2187 msgid "would update superblock version number\n" msgstr "" -#: .././repair/dinode.c:2324 +#: .././repair/dinode.c:2195 #, c-format msgid "WARNING: version 2 inode % claims > %u links, " msgstr "" -#: .././repair/dinode.c:2327 +#: .././repair/dinode.c:2198 #, c-format msgid "" "converting back to version 1,\n" "this may destroy %d links\n" msgstr "" -#: .././repair/dinode.c:2337 +#: .././repair/dinode.c:2208 #, c-format msgid "" "would convert back to version 1,\n" "\tthis might destroy %d links\n" msgstr "" -#: .././repair/dinode.c:2352 +#: .././repair/dinode.c:2223 #, c-format msgid "found version 2 inode %, " msgstr "" -#: .././repair/dinode.c:2354 +#: .././repair/dinode.c:2225 msgid "converting back to version 1\n" msgstr "" -#: .././repair/dinode.c:2360 +#: .././repair/dinode.c:2231 msgid "would convert back to version 1\n" msgstr "" -#: .././repair/dinode.c:2374 +#: .././repair/dinode.c:2245 #, c-format msgid "" "clearing obsolete nlink field in version 2 inode %, was %d, now 0\n" msgstr "" -#: .././repair/dinode.c:2380 +#: .././repair/dinode.c:2251 #, c-format msgid "" "would clear obsolete nlink field in version 2 inode %, currently %d\n" msgstr "" -#: .././repair/dinode.c:2449 +#: .././repair/dinode.c:2320 #, c-format msgid "bad magic number 0x%x on inode %%c" msgstr "" -#: .././repair/dinode.c:2454 +#: .././repair/dinode.c:2325 msgid " resetting magic number\n" msgstr "" -#: .././repair/dinode.c:2458 +#: .././repair/dinode.c:2329 msgid " would reset magic number\n" msgstr "" -#: .././repair/dinode.c:2466 +#: .././repair/dinode.c:2338 #, c-format msgid "bad version number 0x%x on inode %%c" msgstr "" -#: .././repair/dinode.c:2471 +#: .././repair/dinode.c:2343 msgid " resetting version number\n" msgstr "" -#: .././repair/dinode.c:2475 +#: .././repair/dinode.c:2349 msgid " would reset version number\n" msgstr "" -#: .././repair/dinode.c:2485 +#: .././repair/dinode.c:2362 +#, c-format +msgid "inode identifier %llu mismatch on inode %\n" +msgstr "" + +#: .././repair/dinode.c:2371 +#, c-format +msgid "UUID mismatch on inode %\n" +msgstr "" + +#: .././repair/dinode.c:2384 #, c-format msgid "bad (negative) size % on inode %\n" msgstr "" -#: .././repair/dinode.c:2518 +#: .././repair/dinode.c:2417 #, c-format msgid "imap claims a free inode % is in use, " msgstr "" -#: .././repair/dinode.c:2520 +#: .././repair/dinode.c:2419 msgid "correcting imap and clearing inode\n" msgstr "" -#: .././repair/dinode.c:2524 +#: .././repair/dinode.c:2423 msgid "would correct imap and clear inode\n" msgstr "" -#: .././repair/dinode.c:2541 +#: .././repair/dinode.c:2440 #, c-format msgid "bad inode format in inode %\n" msgstr "" -#: .././repair/dinode.c:2557 +#: .././repair/dinode.c:2456 #, c-format msgid "Bad flags set in inode %\n" msgstr "" -#: .././repair/dinode.c:2568 +#: .././repair/dinode.c:2467 #, c-format msgid "inode % has RT flag set but there is no RT device\n" msgstr "" -#: .././repair/dinode.c:2580 +#: .././repair/dinode.c:2479 #, c-format msgid "inode % not rt bitmap\n" msgstr "" -#: .././repair/dinode.c:2594 +#: .././repair/dinode.c:2493 #, c-format msgid "directory flags set on non-directory inode %\n" msgstr "" -#: .././repair/dinode.c:2608 +#: .././repair/dinode.c:2507 #, c-format msgid "file flags set on non-file inode %\n" msgstr "" -#: .././repair/dinode.c:2617 +#: .././repair/dinode.c:2516 msgid ", fixing bad flags.\n" msgstr "" -#: .././repair/dinode.c:2621 +#: .././repair/dinode.c:2520 msgid ", would fix bad flags.\n" msgstr "" -#: .././repair/dinode.c:2672 +#: .././repair/dinode.c:2571 #, c-format msgid "bad inode type %#o inode %\n" msgstr "" -#: .././repair/dinode.c:2696 +#: .././repair/dinode.c:2595 #, c-format msgid "bad non-zero extent size %u for non-realtime/extsize inode %, " msgstr "" -#: .././repair/dinode.c:2699 +#: .././repair/dinode.c:2598 msgid "resetting to zero\n" msgstr "" -#: .././repair/dinode.c:2703 +#: .././repair/dinode.c:2602 msgid "would reset to zero\n" msgstr "" -#: .././repair/dinode.c:2759 +#: .././repair/dinode.c:2655 #, c-format msgid "problem with directory contents in inode %\n" msgstr "" -#: .././repair/dinode.c:2767 +#: .././repair/dinode.c:2663 #, c-format msgid "problem with symbolic link in inode %\n" msgstr "" -#: .././repair/dinode.c:2862 +#: .././repair/dinode.c:2758 #, c-format msgid "processing inode %d/%d\n" msgstr "" -#: .././repair/dir2.c:57 -#, c-format -msgid "malloc failed (%zu bytes) dir2_add_badlist:ino %\n" -msgstr "" - -#: .././repair/dir2.c:98 .././repair/dir2.c:209 .././repair/dir2.c:245 -msgid "couldn't malloc dir2 buffer list\n" -msgstr "" - -#: .././repair/dir2.c:125 -msgid "couldn't malloc dir2 buffer header\n" -msgstr "" - -#: .././repair/dir2.c:142 -msgid "couldn't malloc dir2 buffer data\n" -msgstr "" - -#: .././repair/dir2.c:315 -#, c-format -msgid "found non-root LEAFN node in inode % bno = %u\n" -msgstr "" - -#: .././repair/dir2.c:324 -#, c-format -msgid "bad dir magic number 0x%x in inode % bno = %u\n" -msgstr "" - -#: .././repair/dir2.c:345 -#, c-format -msgid "bad header depth for directory inode %\n" -msgstr "" - -#: .././repair/dir2.c:406 -#, c-format -msgid "release_dir2_cursor_int got unexpected non-null bp, dabno = %u\n" -msgstr "" - -#: .././repair/dir2.c:469 -#, c-format -msgid "directory block used/count inconsistency - %d / %hu\n" -msgstr "" - -#: .././repair/dir2.c:491 -#, c-format -msgid "bad directory block in inode %\n" -msgstr "" - -#: .././repair/dir2.c:512 -#, c-format -msgid "" -"correcting bad hashval in non-leaf dir block\n" -"\tin (level %d) in inode %.\n" -msgstr "" - -#: .././repair/dir2.c:520 -#, c-format -msgid "" -"would correct bad hashval in non-leaf dir block\n" -"\tin (level %d) in inode %.\n" -msgstr "" - -#: .././repair/dir2.c:676 -#, c-format -msgid "bad magic number %x in block %u for directory inode %\n" -msgstr "" - -#: .././repair/dir2.c:684 -#, c-format -msgid "bad back pointer in block %u for directory inode %\n" -msgstr "" - -#: .././repair/dir2.c:690 -#, c-format -msgid "entry count %d too large in block %u for directory inode %\n" -msgstr "" - -#: .././repair/dir2.c:697 -#, c-format -msgid "bad level %d in block %u for directory inode %\n" -msgstr "" - -#: .././repair/dir2.c:740 -#, c-format -msgid "" -"correcting bad hashval in interior dir block\n" -"\tin (level %d) in inode %.\n" -msgstr "" - -#: .././repair/dir2.c:748 -#, c-format -msgid "" -"would correct bad hashval in interior dir block\n" -"\tin (level %d) in inode %.\n" -msgstr "" - -#: .././repair/dir2.c:782 -msgid "couldn't malloc dir2 shortform copy\n" -msgstr "" - -#: .././repair/dir2.c:920 -msgid "current" -msgstr "" - -#: .././repair/dir2.c:923 .././repair/dir2.c:1443 -msgid "invalid" -msgstr "" - -#: .././repair/dir2.c:926 .././repair/dir2.c:1445 -msgid "realtime bitmap" -msgstr "" - -#: .././repair/dir2.c:929 .././repair/dir2.c:1447 -msgid "realtime summary" -msgstr "" - -#: .././repair/dir2.c:932 .././repair/dir2.c:1449 -msgid "user quota" -msgstr "" - -#: .././repair/dir2.c:935 .././repair/dir2.c:1451 -msgid "group quota" -msgstr "" - -#: .././repair/dir2.c:953 .././repair/dir2.c:1481 -msgid "free" -msgstr "" - -#: .././repair/dir2.c:970 .././repair/dir2.c:1461 -msgid "non-existent" -msgstr "" - -#: .././repair/dir2.c:975 -#, c-format -msgid "" -"entry \"%*.*s\" in shortform directory % references %s inode %" -"\n" -msgstr "" - -#: .././repair/dir2.c:1005 -#, c-format -msgid "zero length entry in shortform dir %" -msgstr "" - -#: .././repair/dir2.c:1008 -#, c-format -msgid ", junking %d entries\n" -msgstr "" - -#: .././repair/dir2.c:1011 -#, c-format -msgid ", would junk %d entries\n" -msgstr "" - -#: .././repair/dir2.c:1086 -#, c-format -msgid "entry contains offset out of order in shortform dir %\n" -msgstr "" - -#: .././repair/dir2.c:1189 -#, c-format -msgid "would have corrected i8 count in directory % from %d to %d\n" -msgstr "" - -#: .././repair/dir2.c:1193 -#, c-format -msgid "corrected i8 count in directory %, was %d, now %d\n" -msgstr "" - -#: .././repair/dir2.c:1207 -#, c-format -msgid "" -"would have corrected directory % size from % to %\n" -msgstr "" - -#: .././repair/dir2.c:1224 -#, c-format -msgid "directory % offsets too high\n" -msgstr "" - -#: .././repair/dir2.c:1230 -#, c-format -msgid "would have corrected entry offsets in directory %\n" -msgstr "" - -#: .././repair/dir2.c:1234 -#, c-format -msgid "corrected entry offsets in directory %\n" -msgstr "" - -#: .././repair/dir2.c:1289 -#, c-format -msgid "bad .. entry in directory inode %, points to self, " -msgstr "" - -#: .././repair/dir2.c:1401 -#, c-format -msgid "corrupt block %u in directory inode %\n" +#: .././repair/incore_ino.c:47 +msgid "could not allocate nlink array\n" msgstr "" -#: .././repair/dir2.c:1404 -msgid "\twill junk block\n" +#: .././repair/incore_ino.c:225 +msgid "could not allocate ftypes array\n" msgstr "" -#: .././repair/dir2.c:1406 -msgid "\twould junk block\n" +#: .././repair/incore_ino.c:251 +msgid "inode map malloc failed\n" msgstr "" -#: .././repair/dir2.c:1490 -#, c-format -msgid "" -"entry \"%*.*s\" at block %d offset % in directory inode % " -"references %s inode %\n" +#: .././repair/incore_ino.c:364 +msgid "add_aginode_uncertain - duplicate inode range\n" msgstr "" -#: .././repair/dir2.c:1501 -#, c-format -msgid "" -"entry at block %u offset % in directory inode %has 0 " -"namelength\n" +#: .././repair/incore_ino.c:459 +msgid "add_inode - duplicate inode range\n" msgstr "" -#: .././repair/dir2.c:1514 +#: .././repair/incore_ino.c:553 #, c-format -msgid "\tclearing inode number in entry at offset %...\n" +msgid "good inode list is --\n" msgstr "" -#: .././repair/dir2.c:1521 +#: .././repair/incore_ino.c:556 #, c-format -msgid "\twould clear inode number in entry at offset %...\n" +msgid "uncertain inode list is --\n" msgstr "" -#: .././repair/dir2.c:1534 +#: .././repair/incore_ino.c:561 #, c-format -msgid "" -"entry at block %u offset % in directory inode % has illegal " -"name \"%*.*s\": " +msgid "agno %d -- no inodes\n" msgstr "" -#: .././repair/dir2.c:1564 +#: .././repair/incore_ino.c:565 #, c-format -msgid "bad .. entry in directory inode %, points to self: " +msgid "agno %d\n" msgstr "" -#: .././repair/dir2.c:1575 +#: .././repair/incore_ino.c:569 #, c-format -msgid "bad .. entry in root directory inode %, was %: " +msgid "\tptr = %lx, start = 0x%x, free = 0x%llx, confirmed = 0x%llx\n" msgstr "" -#: .././repair/dir2.c:1594 -#, c-format -msgid "multiple .. entries in directory inode %: " +#: .././repair/incore_ino.c:620 +msgid "couldn't malloc parent list table\n" msgstr "" -#: .././repair/dir2.c:1607 -#, c-format -msgid "bad . entry in directory inode %, was %: " +#: .././repair/incore_ino.c:631 .././repair/incore_ino.c:677 +msgid "couldn't memalign pentries table\n" msgstr "" -#: .././repair/dir2.c:1619 -#, c-format -msgid "multiple . entries in directory inode %: " +#: .././repair/incore_ino.c:735 +msgid "could not malloc inode extra data\n" msgstr "" -#: .././repair/dir2.c:1629 -#, c-format -msgid "entry \"%*.*s\" in directory inode % points to self: " +#: .././repair/incore_ino.c:801 +msgid "couldn't malloc inode tree descriptor table\n" msgstr "" -#: .././repair/dir2.c:1640 -msgid "clearing entry\n" +#: .././repair/incore_ino.c:805 +msgid "couldn't malloc uncertain ino tree descriptor table\n" msgstr "" -#: .././repair/dir2.c:1655 -#, c-format -msgid "bad bestfree table in block %u in directory inode %: " +#: .././repair/incore_ino.c:810 +msgid "couldn't malloc inode tree descriptor\n" msgstr "" -#: .././repair/dir2.c:1658 -msgid "repairing table\n" +#: .././repair/incore_ino.c:814 +msgid "couldn't malloc uncertain ino tree descriptor\n" msgstr "" -#: .././repair/dir2.c:1662 -msgid "would repair table\n" +#: .././repair/incore_ino.c:822 +msgid "couldn't malloc uncertain inode cache area\n" msgstr "" -#: .././repair/dir2.c:1700 +#: .././repair/phase7.c:43 #, c-format -msgid "block %u for directory inode % is missing\n" +msgid "resetting inode % nlinks from %u to %u\n" msgstr "" -#: .././repair/dir2.c:1719 +#: .././repair/phase7.c:49 #, c-format msgid "" -"bad directory block magic # %#x in block %u for directory inode %\n" +"nlinks %u will overflow v1 ino, ino % will be converted to version " +"2\n" msgstr "" -#: .././repair/dir2.c:1763 +#: .././repair/phase7.c:56 #, c-format -msgid "bad entry count in block %u of directory inode %\n" +msgid "would have reset inode % nlinks from %u to %u\n" msgstr "" -#: .././repair/dir2.c:1771 +#: .././repair/phase7.c:88 #, c-format -msgid "bad hash ordering in block %u of directory inode %\n" +msgid "couldn't map inode %, err = %d, can't compare link counts\n" msgstr "" -#: .././repair/dir2.c:1780 -#, c-format -msgid "bad stale count in block %u of directory inode %\n" +#: .././repair/phase7.c:127 +msgid "Phase 7 - verify and correct link counts...\n" msgstr "" -#: .././repair/dir2.c:1838 -#, c-format -msgid "can't read file block %u for directory inode %\n" +#: .././repair/phase7.c:129 +msgid "Phase 7 - verify link counts...\n" msgstr "" -#: .././repair/dir2.c:1849 -#, c-format -msgid "bad directory leaf magic # %#x for directory inode % block %u\n" +#: .././repair/rt.c:47 +msgid "couldn't allocate memory for incore realtime bitmap.\n" msgstr "" -#: .././repair/dir2.c:1879 -#, c-format -msgid "bad sibling back pointer for block %u in directory inode %\n" +#: .././repair/rt.c:51 +msgid "couldn't allocate memory for incore realtime summary info.\n" msgstr "" -#: .././repair/dir2.c:2013 +#: .././repair/rt.c:203 #, c-format -msgid "block % for directory inode % is missing\n" +msgid "can't find block %d for rtbitmap inode\n" msgstr "" -#: .././repair/dir2.c:2022 +#: .././repair/rt.c:211 #, c-format -msgid "can't read block % for directory inode %\n" +msgid "can't read block %d for rtbitmap inode\n" msgstr "" -#: .././repair/dir2.c:2029 +#: .././repair/rt.c:265 #, c-format -msgid "" -"bad directory block magic # %#x in block % for directory inode %" -"\n" +msgid "block %d for rtsummary inode is missing\n" msgstr "" -#: .././repair/dir2.c:2106 +#: .././repair/rt.c:273 #, c-format -msgid "bad size/format for directory %\n" +msgid "can't read block %d for rtsummary inode\n" msgstr "" -#: .././repair/phase7.c:43 +#: .././repair/versions.c:70 #, c-format -msgid "resetting inode % nlinks from %u to %u\n" +msgid "bogus quota flags 0x%x set in superblock" msgstr "" -#: .././repair/phase7.c:49 -#, c-format -msgid "" -"nlinks %u will overflow v1 ino, ino % will be converted to version " -"2\n" +#: .././repair/versions.c:76 +msgid ", bogus flags will be cleared\n" msgstr "" -#: .././repair/phase7.c:56 -#, c-format -msgid "would have reset inode % nlinks from %u to %u\n" +#: .././repair/versions.c:78 +msgid ", bogus flags would be cleared\n" +msgstr "" + +#: .././repair/versions.c:132 +msgid "This filesystem has uninitialized extent flags.\n" +msgstr "" + +#: .././repair/versions.c:140 +msgid "This filesystem is marked shared.\n" +msgstr "" + +#: .././repair/versions.c:146 +msgid "" +"This filesystem uses feature(s) not yet supported in this release.\n" +"Please run a more recent version of xfs_repair.\n" msgstr "" -#: .././repair/phase7.c:89 +#: .././repair/versions.c:152 #, c-format -msgid "couldn't map inode %, err = %d, can't compare link counts\n" +msgid "WARNING: unknown superblock version %d\n" msgstr "" -#: .././repair/phase7.c:128 -msgid "Phase 7 - verify and correct link counts...\n" +#: .././repair/versions.c:155 +msgid "This filesystem contains features not understood by this program.\n" msgstr "" -#: .././repair/phase7.c:130 -msgid "Phase 7 - verify link counts...\n" +#: .././repair/versions.c:163 +msgid "" +"WARNING: you have disallowed superblock-feature-bits-allowed\n" +"\tbut this superblock has feature bits. The superblock\n" +"\twill be downgraded. This may cause loss of filesystem meta-data\n" msgstr "" -#: .././repair/phase4.c:202 -msgid "Phase 4 - check for duplicate blocks...\n" +#: .././repair/versions.c:168 +msgid "" +"WARNING: you have disallowed superblock-feature-bits-allowed\n" +"\tbut this superblock has feature bits. The superblock\n" +"\twould be downgraded. This might cause loss of filesystem\n" +"\tmeta-data.\n" msgstr "" -#: .././repair/phase4.c:203 -msgid " - setting up duplicate extent list...\n" +#: .././repair/versions.c:182 +msgid "" +"WARNING: you have disallowed attributes but this filesystem\n" +"\thas attributes. The filesystem will be downgraded and\n" +"\tall attributes will be removed.\n" msgstr "" -#: .././repair/phase4.c:217 -msgid "root inode would be lost\n" +#: .././repair/versions.c:187 +msgid "" +"WARNING: you have disallowed attributes but this filesystem\n" +"\thas attributes. The filesystem would be downgraded and\n" +"\tall attributes would be removed.\n" msgstr "" -#: .././repair/phase4.c:219 -msgid "root inode lost\n" +#: .././repair/versions.c:200 +msgid "" +"WARNING: you have disallowed attr2 attributes but this filesystem\n" +"\thas attributes. The filesystem will be downgraded and\n" +"\tall attr2 attributes will be removed.\n" msgstr "" -#: .././repair/phase4.c:236 -#, c-format -msgid "unknown block state, ag %d, block %d\n" +#: .././repair/versions.c:205 +msgid "" +"WARNING: you have disallowed attr2 attributes but this filesystem\n" +"\thas attributes. The filesystem would be downgraded and\n" +"\tall attr2 attributes would be removed.\n" msgstr "" -#: .././repair/phase4.c:269 -#, c-format -msgid "unknown rt extent state, extent %\n" +#: .././repair/versions.c:218 +msgid "" +"WARNING: you have disallowed version 2 inodes but this filesystem\n" +"\thas version 2 inodes. The filesystem will be downgraded and\n" +"\tall version 2 inodes will be converted to version 1 inodes.\n" +"\tThis may cause some hard links to files to be destroyed\n" msgstr "" -#: .././repair/phase4.c:318 -msgid " - check for inodes claiming duplicate blocks...\n" +#: .././repair/versions.c:224 +msgid "" +"WARNING: you have disallowed version 2 inodes but this filesystem\n" +"\thas version 2 inodes. The filesystem would be downgraded and\n" +"\tall version 2 inodes would be converted to version 1 inodes.\n" +"\tThis might cause some hard links to files to be destroyed\n" msgstr "" -#: .././repair/prefetch.c:465 -msgid "prefetch corruption\n" +#: .././repair/versions.c:238 +msgid "" +"WARNING: you have disallowed quotas but this filesystem\n" +"\thas quotas. The filesystem will be downgraded and\n" +"\tall quota information will be removed.\n" msgstr "" -#: .././repair/prefetch.c:611 .././repair/prefetch.c:711 -#, c-format -msgid "failed to create prefetch thread: %s\n" +#: .././repair/versions.c:243 +msgid "" +"WARNING: you have disallowed quotas but this filesystem\n" +"\thas quotas. The filesystem would be downgraded and\n" +"\tall quota information would be removed.\n" msgstr "" -#: .././repair/prefetch.c:748 -msgid "failed to initialize prefetch mutex\n" +#: .././repair/versions.c:271 +msgid "" +"WARNING: you have disallowed aligned inodes but this filesystem\n" +"\thas aligned inodes. The filesystem will be downgraded.\n" +"\tThis will permanently degrade the performance of this filesystem.\n" msgstr "" -#: .././repair/prefetch.c:750 .././repair/prefetch.c:752 -msgid "failed to initialize prefetch cond var\n" +#: .././repair/versions.c:276 +msgid "" +"WARNING: you have disallowed aligned inodes but this filesystem\n" +"\thas aligned inodes. The filesystem would be downgraded.\n" +"\tThis would permanently degrade the performance of this filesystem.\n" msgstr "" #: .././repair/xfs_repair.c:81 @@ -11903,7 +11634,7 @@ " -v Verbose output.\n" " -c subopts Change filesystem parameters - use xfs_admin.\n" " -o subopts Override default behaviour, refer to man page.\n" -" -t interval Reporting interval in minutes.\n" +" -t interval Reporting interval in seconds.\n" " -d Repair dangerously.\n" " -V Reports version and exits.\n" msgstr "" @@ -11988,283 +11719,363 @@ msgid "bad shared version number in superblock" msgstr "" -#: .././repair/xfs_repair.c:144 +#: .././repair/xfs_repair.c:141 +msgid "bad CRC in superblock" +msgstr "" + +#: .././repair/xfs_repair.c:146 #, c-format msgid "bad error code - %d\n" msgstr "" -#: .././repair/xfs_repair.c:152 +#: .././repair/xfs_repair.c:154 #, c-format msgid "-%c %s option cannot have a value\n" msgstr "" -#: .././repair/xfs_repair.c:248 +#: .././repair/xfs_repair.c:245 +msgid "-o ihash option has been removed and will be ignored\n" +msgstr "" + +#: .././repair/xfs_repair.c:250 msgid "-o bhash option cannot be used with -m option\n" msgstr "" -#: .././repair/xfs_repair.c:300 +#: .././repair/xfs_repair.c:302 msgid "-m option cannot be used with -o bhash option\n" msgstr "" -#: .././repair/xfs_repair.c:342 +#: .././repair/xfs_repair.c:344 #, c-format msgid "" "\n" "fatal error -- " msgstr "" -#: .././repair/xfs_repair.c:454 +#: .././repair/xfs_repair.c:460 #, c-format msgid "sb root inode value % %sinconsistent with calculated value %u\n" msgstr "" -#: .././repair/xfs_repair.c:461 +#: .././repair/xfs_repair.c:467 #, c-format msgid "resetting superblock root inode pointer to %u\n" msgstr "" -#: .././repair/xfs_repair.c:465 +#: .././repair/xfs_repair.c:471 #, c-format msgid "would reset superblock root inode pointer to %u\n" msgstr "" -#: .././repair/xfs_repair.c:477 +#: .././repair/xfs_repair.c:483 #, c-format msgid "" "sb realtime bitmap inode % %sinconsistent with calculated value %u\n" msgstr "" -#: .././repair/xfs_repair.c:484 +#: .././repair/xfs_repair.c:490 #, c-format msgid "resetting superblock realtime bitmap ino pointer to %u\n" msgstr "" -#: .././repair/xfs_repair.c:488 +#: .././repair/xfs_repair.c:494 #, c-format msgid "would reset superblock realtime bitmap ino pointer to %u\n" msgstr "" -#: .././repair/xfs_repair.c:500 +#: .././repair/xfs_repair.c:506 #, c-format msgid "" "sb realtime summary inode % %sinconsistent with calculated value %u\n" msgstr "" -#: .././repair/xfs_repair.c:507 +#: .././repair/xfs_repair.c:513 #, c-format msgid "resetting superblock realtime summary ino pointer to %u\n" msgstr "" -#: .././repair/xfs_repair.c:511 +#: .././repair/xfs_repair.c:517 #, c-format msgid "would reset superblock realtime summary ino pointer to %u\n" msgstr "" -#: .././repair/xfs_repair.c:554 +#: .././repair/xfs_repair.c:563 msgid "" "Primary superblock would have been modified.\n" "Cannot proceed further in no_modify mode.\n" "Exiting now.\n" msgstr "" -#: .././repair/xfs_repair.c:577 +#: .././repair/xfs_repair.c:571 +msgid "" +"Primary superblock bad after phase 1!\n" +"Exiting now.\n" +msgstr "" + +#: .././repair/xfs_repair.c:587 msgid "" "Cannot get host filesystem geometry.\n" "Repair may fail if there is a sector size mismatch between\n" "the image and the host filesystem.\n" msgstr "" -#: .././repair/xfs_repair.c:589 +#: .././repair/xfs_repair.c:599 msgid "" "Sector size on host filesystem larger than image sector size.\n" "Cannot turn off direct IO, so exiting.\n" msgstr "" -#: .././repair/xfs_repair.c:599 +#: .././repair/xfs_repair.c:612 #, c-format msgid "%s: cannot repair this filesystem. Sorry.\n" msgstr "" -#: .././repair/xfs_repair.c:624 +#: .././repair/xfs_repair.c:671 #, c-format msgid " - reporting progress in intervals of %s\n" msgstr "" -#: .././repair/xfs_repair.c:671 +#: .././repair/xfs_repair.c:716 #, c-format msgid "" -" - max_mem = %lu, icount = %, imem = %, dblock = %" -", dmem = %\n" +" - max_mem = %lu, icount = %, imem = %, dblock = " +"%, dmem = %\n" msgstr "" -#: .././repair/xfs_repair.c:684 +#: .././repair/xfs_repair.c:725 #, c-format msgid "" "Required memory for repair is greater that the maximum specified\n" "with the -m option. Please increase it to at least %lu.\n" msgstr "" -#: .././repair/xfs_repair.c:689 +#: .././repair/xfs_repair.c:730 #, c-format msgid "" -"Not enough RAM available for repair to enable prefetching.\n" -"This will be _slow_.\n" -"You need at least %luMB RAM to run with prefetching enabled.\n" +"Memory available for repair (%luMB) may not be sufficient.\n" +"At least %luMB is needed to repair this filesystem efficiently\n" +"If repair fails due to lack of memory, please\n" +msgstr "" + +#: .././repair/xfs_repair.c:736 +msgid "turn prefetching off (-P) to reduce the memory footprint.\n" +msgstr "" + +#: .././repair/xfs_repair.c:739 +#, c-format +msgid "increase system RAM and/or swap space to at least %luMB.\n" msgstr "" -#: .././repair/xfs_repair.c:707 +#: .././repair/xfs_repair.c:754 #, c-format msgid " - block cache size set to %d entries\n" msgstr "" -#: .././repair/xfs_repair.c:736 +#: .././repair/xfs_repair.c:778 msgid "Found unsupported filesystem features. Exiting now.\n" msgstr "" -#: .././repair/xfs_repair.c:754 +#: .././repair/xfs_repair.c:796 #, c-format msgid "No modify flag set, skipping phase 5\n" msgstr "" -#: .././repair/xfs_repair.c:773 +#: .././repair/xfs_repair.c:815 msgid "Inode allocation btrees are too corrupted, skipping phases 6 and 7\n" msgstr "" -#: .././repair/xfs_repair.c:779 +#: .././repair/xfs_repair.c:821 msgid "Warning: no quota inodes were found. Quotas disabled.\n" msgstr "" -#: .././repair/xfs_repair.c:782 +#: .././repair/xfs_repair.c:824 msgid "Warning: no quota inodes were found. Quotas would be disabled.\n" msgstr "" -#: .././repair/xfs_repair.c:787 +#: .././repair/xfs_repair.c:829 msgid "Warning: quota inodes were cleared. Quotas disabled.\n" msgstr "" -#: .././repair/xfs_repair.c:790 +#: .././repair/xfs_repair.c:832 msgid "Warning: quota inodes would be cleared. Quotas would be disabled.\n" msgstr "" -#: .././repair/xfs_repair.c:796 +#: .././repair/xfs_repair.c:838 msgid "" "Warning: user quota information was cleared.\n" "User quotas can not be enforced until limit information is recreated.\n" msgstr "" -#: .././repair/xfs_repair.c:800 +#: .././repair/xfs_repair.c:842 msgid "" "Warning: user quota information would be cleared.\n" "User quotas could not be enforced until limit information was recreated.\n" msgstr "" -#: .././repair/xfs_repair.c:808 +#: .././repair/xfs_repair.c:850 msgid "" "Warning: group quota information was cleared.\n" "Group quotas can not be enforced until limit information is recreated.\n" msgstr "" -#: .././repair/xfs_repair.c:812 +#: .././repair/xfs_repair.c:854 msgid "" "Warning: group quota information would be cleared.\n" "Group quotas could not be enforced until limit information was recreated.\n" msgstr "" -#: .././repair/xfs_repair.c:820 +#: .././repair/xfs_repair.c:862 msgid "" "Warning: project quota information was cleared.\n" "Project quotas can not be enforced until limit information is recreated.\n" msgstr "" -#: .././repair/xfs_repair.c:824 +#: .././repair/xfs_repair.c:866 msgid "" "Warning: project quota information would be cleared.\n" "Project quotas could not be enforced until limit information was recreated.\n" msgstr "" -#: .././repair/xfs_repair.c:835 +#: .././repair/xfs_repair.c:877 msgid "No modify flag set, skipping filesystem flush and exiting.\n" msgstr "" -#: .././repair/xfs_repair.c:854 +#: .././repair/xfs_repair.c:891 .././repair/phase5.c:1471 +msgid "couldn't get superblock\n" +msgstr "" + +#: .././repair/xfs_repair.c:896 msgid "Note - quota info will be regenerated on next quota mount.\n" msgstr "" -#: .././repair/xfs_repair.c:862 +#: .././repair/xfs_repair.c:903 #, c-format msgid "" "Note - stripe unit (%d) and width (%d) fields have been reset.\n" "Please set with mount -o sunit=,swidth=\n" msgstr "" -#: .././repair/xfs_repair.c:885 +#: .././repair/xfs_repair.c:926 msgid "done\n" msgstr "" -#: .././repair/bmap.c:53 +#: .././repair/xfs_repair.c:930 +msgid "Repair of readonly mount complete. Immediate reboot encouraged.\n" +msgstr "" + +#: .././repair/incore.c:230 #, c-format -msgid "" -"Number of extents requested in blkmap_alloc (%d) overflows 32 bits.\n" -"If this is not a corruption, then you will need a 64 bit system\n" -"to repair this filesystem.\n" +msgid "couldn't allocate realtime block map, size = %\n" msgstr "" -#: .././repair/bmap.c:66 +#: .././repair/incore.c:295 +msgid "couldn't allocate block map btree roots\n" +msgstr "" + +#: .././repair/incore.c:299 +msgid "couldn't allocate block map locks\n" +msgstr "" + +#: .././repair/phase3.c:45 #, c-format -msgid "malloc failed in blkmap_alloc (%zu bytes)\n" +msgid "cannot read agi block % for ag %u\n" msgstr "" -#: .././repair/bmap.c:174 +#: .././repair/phase3.c:93 +msgid "Phase 3 - for each AG...\n" +msgstr "" + +#: .././repair/phase3.c:95 +msgid " - scan and clear agi unlinked lists...\n" +msgstr "" + +#: .././repair/phase3.c:97 +msgid " - scan (but don't clear) agi unlinked lists...\n" +msgstr "" + +#: .././repair/phase3.c:117 +msgid " - process known inodes and perform inode discovery...\n" +msgstr "" + +#: .././repair/phase3.c:128 +msgid " - process newly discovered inodes...\n" +msgstr "" + +#: .././repair/phase5.c:219 +msgid "could not set up btree block array\n" +msgstr "" + +#: .././repair/phase5.c:231 +msgid "error - not enough free space in filesystem\n" +msgstr "" + +#: .././repair/phase5.c:445 #, c-format -msgid "blkmap_getn malloc failed (% bytes)\n" +msgid "can't rebuild fs trees -- not enough free space on ag %u\n" msgstr "" -#: .././repair/bmap.c:273 +#: .././repair/phase5.c:468 #, c-format -msgid "" -"Number of extents requested in blkmap_grow (%d) overflows 32 bits.\n" -"You need a 64 bit system to repair this filesystem.\n" +msgid "ag %u - not enough free space to build freespace btrees\n" msgstr "" -#: .././repair/bmap.c:281 +#: .././repair/phase5.c:503 #, c-format -msgid "" -"Number of extents requested in blkmap_grow (%d) overflowed the\n" -"maximum number of supported extents (%d).\n" +msgid "not enough free blocks left to describe all free blocks in AG %u\n" msgstr "" -#: .././repair/bmap.c:289 -msgid "realloc failed in blkmap_grow\n" +#: .././repair/phase5.c:1399 +#, c-format +msgid "lost %d blocks in ag %u\n" msgstr "" -#: .././repair/phase3.c:45 +#: .././repair/phase5.c:1402 #, c-format -msgid "cannot read agi block % for ag %u\n" +msgid "thought we were going to lose %d blocks in ag %u, actually lost %d\n" msgstr "" -#: .././repair/phase3.c:127 -msgid "Phase 3 - for each AG...\n" +#: .././repair/phase5.c:1548 +#, c-format +msgid "unable to rebuild AG %u. Not enough free space in on-disk AG.\n" msgstr "" -#: .././repair/phase3.c:129 -msgid " - scan and clear agi unlinked lists...\n" +#: .././repair/phase5.c:1588 +#, c-format +msgid "unable to rebuild AG %u. No free space.\n" msgstr "" -#: .././repair/phase3.c:131 -msgid " - scan (but don't clear) agi unlinked lists...\n" +#: .././repair/phase5.c:1615 +#, c-format +msgid "lost %d blocks in agno %d, sorry.\n" msgstr "" -#: .././repair/phase3.c:151 -msgid " - process known inodes and perform inode discovery...\n" +#: .././repair/phase5.c:1704 +msgid "Phase 5 - rebuild AG headers and trees...\n" msgstr "" -#: .././repair/phase3.c:162 -msgid " - process newly discovered inodes...\n" +#: .././repair/phase5.c:1734 +msgid "cannot alloc sb_icount_ag buffers\n" +msgstr "" + +#: .././repair/phase5.c:1738 +msgid "cannot alloc sb_ifree_ag buffers\n" +msgstr "" + +#: .././repair/phase5.c:1742 +msgid "cannot alloc sb_fdblocks_ag buffers\n" +msgstr "" + +#: .././repair/phase5.c:1761 +msgid " - generate realtime summary info and bitmap...\n" +msgstr "" + +#: .././repair/phase5.c:1766 +msgid " - reset superblock...\n" msgstr "" #: .././rtcp/xfs_rtcp.c:30 #, c-format -msgid "%s [-e extsize] [-p] source target\n" +msgid "%s [-e extsize] [-p] [-V] source target\n" msgstr "" #: .././rtcp/xfs_rtcp.c:69 @@ -12307,53 +12118,53 @@ msgid "%s: get attributes of %s failed: %s\n" msgstr "" -#: .././rtcp/xfs_rtcp.c:225 .././rtcp/xfs_rtcp.c:260 +#: .././rtcp/xfs_rtcp.c:225 .././rtcp/xfs_rtcp.c:262 #, c-format msgid "%s: %s is not a realtime file.\n" msgstr "" -#: .././rtcp/xfs_rtcp.c:234 +#: .././rtcp/xfs_rtcp.c:235 #, c-format msgid "%s: %s file extent size is %d, instead of %d.\n" msgstr "" -#: .././rtcp/xfs_rtcp.c:246 .././rtcp/xfs_rtcp.c:269 +#: .././rtcp/xfs_rtcp.c:248 .././rtcp/xfs_rtcp.c:271 #, c-format msgid "%s: open of %s source failed: %s\n" msgstr "" -#: .././rtcp/xfs_rtcp.c:283 +#: .././rtcp/xfs_rtcp.c:285 #, c-format msgid "%s: couldn't get direct I/O information: %s\n" msgstr "" -#: .././rtcp/xfs_rtcp.c:293 +#: .././rtcp/xfs_rtcp.c:295 #, c-format msgid "%s: extent size %d not a multiple of %d.\n" msgstr "" -#: .././rtcp/xfs_rtcp.c:307 +#: .././rtcp/xfs_rtcp.c:309 #, c-format msgid "The size of %s is not a multiple of %d.\n" msgstr "" -#: .././rtcp/xfs_rtcp.c:310 +#: .././rtcp/xfs_rtcp.c:312 #, c-format msgid "%s will be padded to %lld bytes.\n" msgstr "" -#: .././rtcp/xfs_rtcp.c:316 +#: .././rtcp/xfs_rtcp.c:318 #, c-format msgid "" "Use the -p option to pad %s to a size which is a multiple of %d bytes.\n" msgstr "" -#: .././rtcp/xfs_rtcp.c:358 +#: .././rtcp/xfs_rtcp.c:360 #, c-format msgid "%s: write error: %s\n" msgstr "" -#: .././rtcp/xfs_rtcp.c:386 +#: .././rtcp/xfs_rtcp.c:388 #, c-format msgid "%s: could not open %s: %s\n" msgstr "" diff -Nru xfsprogs-3.1.9ubuntu2/quota/init.c xfsprogs-3.2.1ubuntu1/quota/init.c --- xfsprogs-3.1.9ubuntu2/quota/init.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/quota/init.c 2013-06-06 22:52:59.000000000 +0000 @@ -45,7 +45,7 @@ usage(void) { fprintf(stderr, - _("Usage: %s [-p prog] [-c cmd]... [-d project]... [path]\n"), + _("Usage: %s [-V] [-x] [-p prog] [-c cmd]... [-d project]... [path]\n"), progname); exit(1); } diff -Nru xfsprogs-3.1.9ubuntu2/quota/path.c xfsprogs-3.2.1ubuntu1/quota/path.c --- xfsprogs-3.1.9ubuntu2/quota/path.c 2011-07-06 01:35:29.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/quota/path.c 2014-05-02 00:09:16.000000000 +0000 @@ -54,17 +54,17 @@ c = 0; printf(" ("); if (qstat.qs_flags & XFS_QUOTA_UDQ_ENFD) - c = printf("%suquota", c ? ", " : ""); + c = printf("uquota"); else if (qstat.qs_flags & XFS_QUOTA_UDQ_ACCT) - c = printf("%suqnoenforce", c ? ", " : ""); + c = printf("uqnoenforce"); if (qstat.qs_flags & XFS_QUOTA_GDQ_ENFD) c = printf("%sgquota", c ? ", " : ""); else if (qstat.qs_flags & XFS_QUOTA_GDQ_ACCT) c = printf("%sgqnoenforce", c ? ", " : ""); if (qstat.qs_flags & XFS_QUOTA_PDQ_ENFD) - c = printf("%spquota", c ? ", " : ""); + printf("%spquota", c ? ", " : ""); else if (qstat.qs_flags & XFS_QUOTA_PDQ_ACCT) - c = printf("%spqnoenforce", c ? ", " : ""); + printf("%spqnoenforce", c ? ", " : ""); printf(")"); } printf("\n"); diff -Nru xfsprogs-3.1.9ubuntu2/quota/quota.c xfsprogs-3.2.1ubuntu1/quota/quota.c --- xfsprogs-3.1.9ubuntu2/quota/quota.c 2011-07-06 01:35:29.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/quota/quota.c 2014-05-02 00:09:16.000000000 +0000 @@ -224,7 +224,7 @@ uid_t id; if (name) { - if (isdigit(name[0])) { + if (isdigits_only(name)) { id = atoi(name); name = getusername(id, flags & NO_LOOKUP_FLAG); } else if ((u = getpwnam(name))) { @@ -273,7 +273,7 @@ int i, ngroups, dofree = 0; if (name) { - if (isdigit(name[0])) { + if (isdigits_only(name)) { gid = atoi(name); name = getgroupname(gid, flags & NO_LOOKUP_FLAG); } else { @@ -289,15 +289,19 @@ } gids = &gid; ngroups = 1; - } else if ( ((ngroups = sysconf(_SC_NGROUPS_MAX)) < 0) || - ((gids = malloc(ngroups * sizeof(gid_t))) == NULL) || - ((ngroups = getgroups(ngroups, gids)) < 0)) { - dofree = (gids != NULL); - gid = getgid(); - gids = &gid; - ngroups = 1; } else { - dofree = (gids != NULL); + if ( ((ngroups = sysconf(_SC_NGROUPS_MAX)) < 0) || + ((gids = malloc(ngroups * sizeof(gid_t))) == NULL) || + ((ngroups = getgroups(ngroups, gids)) < 0)) { + /* something failed. Fall back to 1 group */ + free(gids); + gid = getgid(); + gids = &gid; + ngroups = 1; + } else { + /* It all worked, and we allocated memory */ + dofree = 1; + } } for (i = 0; i < ngroups; i++, name = NULL) { @@ -344,7 +348,7 @@ return; } - if (isdigit(name[0])) { + if (isdigits_only(name)) { id = atoi(name); name = getprojectname(id, flags & NO_LOOKUP_FLAG); } else if ((p = getprnam(name))) { diff -Nru xfsprogs-3.1.9ubuntu2/quota/quota.h xfsprogs-3.2.1ubuntu1/quota/quota.h --- xfsprogs-3.1.9ubuntu2/quota/quota.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/quota/quota.h 2013-06-06 22:52:59.000000000 +0000 @@ -19,6 +19,7 @@ #include #include #include +#include /* * Different forms of XFS quota @@ -80,4 +81,5 @@ extern char *uid_to_name(__uint32_t __uid); extern char *gid_to_name(__uint32_t __gid); extern char *prid_to_name(__uint32_t __prid); +extern bool isdigits_only(const char *); diff -Nru xfsprogs-3.1.9ubuntu2/quota/quot.c xfsprogs-3.2.1ubuntu1/quota/quot.c --- xfsprogs-3.1.9ubuntu2/quota/quot.c 2011-07-06 01:35:29.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/quota/quot.c 2014-05-02 00:09:16.000000000 +0000 @@ -165,6 +165,7 @@ buf = (xfs_bstat_t *)calloc(NBSTAT, sizeof(xfs_bstat_t)); if (!buf) { perror("calloc"); + close(fsfd); return; } diff -Nru xfsprogs-3.1.9ubuntu2/release.sh xfsprogs-3.2.1ubuntu1/release.sh --- xfsprogs-3.1.9ubuntu2/release.sh 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/release.sh 2014-05-02 00:09:16.000000000 +0000 @@ -1,6 +1,6 @@ -#!/bin/bash +#!/bin/sh # -# Automate generation a new release +# Automate generation of a new release # . ./VERSION @@ -8,16 +8,23 @@ version=${PKG_MAJOR}.${PKG_MINOR}.${PKG_REVISION} date=`date +"%-d %B %Y"` +echo "Cleaning up" +make realclean + echo "Updating CHANGES" sed -e "s/${version}.*/${version} (${date})/" doc/CHANGES > doc/CHANGES.tmp && \ mv doc/CHANGES.tmp doc/CHANGES echo "Commiting CHANGES update to git" -git commit -s -a -m "${version} release" +git commit -a -m "${version} release" echo "Tagging git repository" -git tag -s -a -m "${version} release" v${version} +git tag -a -m "${version} release" v${version} -echo "Done. Please remember to push out tags using \"git push --tags\"" -echo "If you wish to create a source tarball, run \"make dist\"" +echo "Making source tarball" +make dist +#echo "Sign the source tarball" +#gpg --detach-sign xfsprogs-${version}.tar.gz + +echo "Done. Please remember to push out tags using \"git push --tags\"" diff -Nru xfsprogs-3.1.9ubuntu2/repair/agheader.c xfsprogs-3.2.1ubuntu1/repair/agheader.c --- xfsprogs-3.1.9ubuntu2/repair/agheader.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/agheader.c 2014-07-21 09:13:53.000000000 +0000 @@ -22,6 +22,11 @@ #include "protos.h" #include "err_protos.h" +/* + * XXX (dgc): What is the point of all the check and repair here when phase 5 + * recreates the AGF/AGI/AGFL completely from scratch? + */ + static int verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i) { @@ -104,7 +109,20 @@ /* don't check freespace btrees -- will be checked by caller */ - return(retval); + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return retval; + + if (platform_uuid_compare(&agf->agf_uuid, &mp->m_sb.sb_uuid)) { + char uu[64]; + + retval = XR_AG_AGF; + platform_uuid_unparse(&agf->agf_uuid, uu); + do_warn(_("bad uuid %s for agf %d\n"), uu, i); + + if (!no_modify) + platform_uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_uuid); + } + return retval; } static int @@ -169,7 +187,21 @@ /* don't check inode btree -- will be checked by caller */ - return(retval); + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return retval; + + if (platform_uuid_compare(&agi->agi_uuid, &mp->m_sb.sb_uuid)) { + char uu[64]; + + retval = XR_AG_AGI; + platform_uuid_unparse(&agi->agi_uuid, uu); + do_warn(_("bad uuid %s for agi %d\n"), uu, agno); + + if (!no_modify) + platform_uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_uuid); + } + + return retval; } /* @@ -213,71 +245,78 @@ * superblocks, not just the secondary superblocks. */ static int -secondary_sb_wack(xfs_mount_t *mp, xfs_buf_t *sbuf, xfs_sb_t *sb, - xfs_agnumber_t i) +secondary_sb_wack( + struct xfs_mount *mp, + struct xfs_buf *sbuf, + struct xfs_sb *sb, + xfs_agnumber_t i) { - int do_bzero; - int size; - char *ip; - int rval; + struct xfs_dsb *dsb = XFS_BUF_TO_SBP(sbuf); + int do_bzero = 0; + int size; + char *ip; + int rval = 0;; rval = do_bzero = 0; /* - * mkfs's that stamped a feature bit besides the ones in the mask - * (e.g. were pre-6.5 beta) could leave garbage in the secondary - * superblock sectors. Anything stamping the shared fs bit or better - * into the secondaries is ok and should generate clean secondary - * superblock sectors. so only run the zero check on the - * potentially garbaged secondaries. + * Check for garbage beyond the last valid field. + * Use field addresses instead so this code will still + * work against older filesystems when the superblock + * gets rev'ed again with new fields appended. + * + * size is the size of data which is valid for this sb. */ - if (pre_65_beta || - (sb->sb_versionnum & XR_GOOD_SECSB_VNMASK) == 0 || - sb->sb_versionnum < XFS_SB_VERSION_4) { - /* - * Check for garbage beyond the last field. - * Use field addresses instead so this code will still - * work against older filesystems when the superblock - * gets rev'ed again with new fields appended. - */ - if (xfs_sb_version_hasmorebits(sb)) - size = (__psint_t)&sb->sb_features2 - + sizeof(sb->sb_features2) - (__psint_t)sb; - else if (xfs_sb_version_haslogv2(sb)) - size = (__psint_t)&sb->sb_logsunit - + sizeof(sb->sb_logsunit) - (__psint_t)sb; - else if (xfs_sb_version_hassector(sb)) - size = (__psint_t)&sb->sb_logsectsize - + sizeof(sb->sb_logsectsize) - (__psint_t)sb; - else if (xfs_sb_version_hasdirv2(sb)) - size = (__psint_t)&sb->sb_dirblklog - + sizeof(sb->sb_dirblklog) - (__psint_t)sb; - else - size = (__psint_t)&sb->sb_width - + sizeof(sb->sb_width) - (__psint_t)sb; - for (ip = (char *)((__psint_t)sb + size); - ip < (char *)((__psint_t)sb + mp->m_sb.sb_sectsize); - ip++) { - if (*ip) { - do_bzero = 1; - break; - } - } - - if (do_bzero) { - rval |= XR_AG_SB_SEC; - if (!no_modify) { - do_warn( - _("zeroing unused portion of %s superblock (AG #%u)\n"), - !i ? _("primary") : _("secondary"), i); - memset((void *)((__psint_t)sb + size), 0, - mp->m_sb.sb_sectsize - size); - } else - do_warn( - _("would zero unused portion of %s superblock (AG #%u)\n"), - !i ? _("primary") : _("secondary"), i); + if (xfs_sb_version_hascrc(sb)) + size = offsetof(xfs_sb_t, sb_lsn) + + sizeof(sb->sb_lsn); + else if (xfs_sb_version_hasmorebits(sb)) + size = offsetof(xfs_sb_t, sb_bad_features2) + + sizeof(sb->sb_bad_features2); + else if (xfs_sb_version_haslogv2(sb)) + size = offsetof(xfs_sb_t, sb_logsunit) + + sizeof(sb->sb_logsunit); + else if (xfs_sb_version_hassector(sb)) + size = offsetof(xfs_sb_t, sb_logsectsize) + + sizeof(sb->sb_logsectsize); + else if (xfs_sb_version_hasdirv2(sb)) + size = offsetof(xfs_sb_t, sb_dirblklog) + + sizeof(sb->sb_dirblklog); + else + size = offsetof(xfs_sb_t, sb_width) + + sizeof(sb->sb_width); + + /* Check the buffer we read from disk for garbage outside size */ + for (ip = XFS_BUF_PTR(sbuf) + size; + ip < XFS_BUF_PTR(sbuf) + mp->m_sb.sb_sectsize; + ip++) { + if (*ip) { + do_bzero = 1; + break; } } + if (do_bzero) { + rval |= XR_AG_SB_SEC; + if (!no_modify) { + do_warn( + _("zeroing unused portion of %s superblock (AG #%u)\n"), + !i ? _("primary") : _("secondary"), i); + /* + * zero both the in-memory sb and the disk buffer, + * because the former was read from disk and + * may contain newer version fields that shouldn't + * be set, and the latter is never updated past + * the last field - just zap them both. + */ + memset((void *)((__psint_t)sb + size), 0, + mp->m_sb.sb_sectsize - size); + memset(XFS_BUF_PTR(sbuf) + size, 0, + mp->m_sb.sb_sectsize - size); + } else + do_warn( + _("would zero unused portion of %s superblock (AG #%u)\n"), + !i ? _("primary") : _("secondary"), i); + } /* * now look for the fields we can manipulate directly. @@ -299,12 +338,18 @@ } /* - * quota inodes and flags in secondary superblocks - * are never set by mkfs. However, they could be set - * in a secondary if a fs with quotas was growfs'ed since - * growfs copies the new primary into the secondaries. + * quota inodes and flags in secondary superblocks are never set by + * mkfs. However, they could be set in a secondary if a fs with quotas + * was growfs'ed since growfs copies the new primary into the + * secondaries. + * + * Also, the in-core inode flags now have different meaning to the + * on-disk flags, and so libxfs_sb_to_disk cannot directly write the + * sb_gquotino/sb_pquotino fields without specific sb_qflags being set. + * Hence we need to zero those fields directly in the sb buffer here. */ - if (sb->sb_inprogress == 1 && sb->sb_uquotino) { + + if (sb->sb_inprogress == 1 && sb->sb_uquotino != NULLFSINO) { if (!no_modify) sb->sb_uquotino = 0; if (sb->sb_versionnum & XR_PART_SECSB_VNMASK || !do_bzero) { @@ -317,9 +362,11 @@ rval |= XR_AG_SB_SEC; } - if (sb->sb_inprogress == 1 && sb->sb_gquotino) { - if (!no_modify) + if (sb->sb_inprogress == 1 && sb->sb_gquotino != NULLFSINO) { + if (!no_modify) { sb->sb_gquotino = 0; + dsb->sb_gquotino = 0; + } if (sb->sb_versionnum & XR_PART_SECSB_VNMASK || !do_bzero) { rval |= XR_AG_SB; do_warn( @@ -330,6 +377,21 @@ rval |= XR_AG_SB_SEC; } + if (sb->sb_inprogress == 1 && sb->sb_pquotino != NULLFSINO) { + if (!no_modify) { + sb->sb_pquotino = 0; + dsb->sb_pquotino = 0; + } + if (sb->sb_versionnum & XR_PART_SECSB_VNMASK || !do_bzero) { + rval |= XR_AG_SB; + do_warn( + _("non-null project quota inode field in superblock %d\n"), + i); + + } else + rval |= XR_AG_SB_SEC; + } + if (sb->sb_inprogress == 1 && sb->sb_qflags) { if (!no_modify) sb->sb_qflags = 0; @@ -424,7 +486,7 @@ int status = XR_OK; int status_sb = XR_OK; - status = verify_sb(sb, (i == 0)); + status = verify_sb(sbuf->b_addr, sb, (i == 0)); if (status != XR_OK) { do_warn(_("bad on-disk superblock %d - %s\n"), diff -Nru xfsprogs-3.1.9ubuntu2/repair/attr_repair.c xfsprogs-3.2.1ubuntu1/repair/attr_repair.c --- xfsprogs-3.1.9ubuntu2/repair/attr_repair.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/attr_repair.c 2014-07-21 09:13:53.000000000 +0000 @@ -20,14 +20,667 @@ #include "globals.h" #include "err_protos.h" #include "attr_repair.h" -#include "dir.h" #include "dinode.h" #include "bmap.h" #include "protos.h" +#include "dir2.h" -static int xfs_acl_valid(xfs_acl_disk_t *daclp); +static int xfs_acl_valid(struct xfs_mount *mp, struct xfs_acl *daclp); static int xfs_mac_valid(xfs_mac_label_t *lp); +/* + * da node check/verify functions that the attribute tree relies on are first in + * the file before the actual attribute code. This used to be shared with the + * dir v1 code, but that format is no longer supported yb the userspace + * utilities and hence is now specific to the attribute tree implementation. + */ +#define XR_DA_LEAF_MAPSIZE XFS_ATTR_LEAF_MAPSIZE + +typedef unsigned char da_freemap_t; + +/* + * the cursor gets passed up and down the da btree processing + * routines. The interior block processing routines use the + * cursor to determine if the pointers to and from the preceding + * and succeeding sibling blocks are ok and whether the values in + * the current block are consistent with the entries in the parent + * nodes. When a block is traversed, a parent-verification routine + * is called to verify if the next logical entry in the next level up + * is consistent with the greatest hashval in the next block of the + * current level. The verification routine is itself recursive and + * calls itself if it has to traverse an interior block to get + * the next logical entry. The routine recurses upwards through + * the tree until it finds a block where it can simply step to + * the next entry. The hashval in that entry should be equal to + * the hashval being passed to it (the greatest hashval in the block + * that the entry points to). If that isn't true, then the tree + * is blown and we need to trash it, salvage and trash it, or fix it. + * Currently, we just trash it. + */ +typedef struct da_level_state { + xfs_buf_t *bp; /* block bp */ +#ifdef XR_DIR_TRACE + xfs_da_intnode_t *n; /* bp data */ +#endif + xfs_dablk_t bno; /* file block number */ + xfs_dahash_t hashval; /* last verified hashval */ + int index; /* current index in block */ + int dirty; /* is buffer dirty ? (1 == yes) */ +} da_level_state_t; + +typedef struct da_bt_cursor { + int active; /* highest level in tree (# levels-1) */ + int type; /* 0 if dir, 1 if attr */ + xfs_ino_t ino; + xfs_dablk_t greatest_bno; + xfs_dinode_t *dip; + da_level_state_t level[XFS_DA_NODE_MAXDEPTH]; + struct blkmap *blkmap; +} da_bt_cursor_t; + + +/* + * Allocate a freespace map for directory or attr leaf blocks (1 bit per byte) + * 1 == used, 0 == free. + */ +static da_freemap_t * +alloc_da_freemap(struct xfs_mount *mp) +{ + return calloc(1, mp->m_sb.sb_blocksize / NBBY); +} + +/* + * Set the he range [start, stop) in the directory freemap. + * + * Returns 1 if there is a conflict or 0 if everything's good. + * + * Within a char, the lowest bit of the char represents the byte with + * the smallest address + */ +static int +set_da_freemap(xfs_mount_t *mp, da_freemap_t *map, int start, int stop) +{ + const da_freemap_t mask = 0x1; + int i; + + if (start > stop) { + /* + * allow == relation since [x, x) claims 1 byte + */ + do_warn(_("bad range claimed [%d, %d) in da block\n"), + start, stop); + return(1); + } + + if (stop > mp->m_sb.sb_blocksize) { + do_warn( + _("byte range end [%d %d) in da block larger than blocksize %d\n"), + start, stop, mp->m_sb.sb_blocksize); + return(1); + } + + for (i = start; i < stop; i ++) { + if (map[i / NBBY] & (mask << i % NBBY)) { + do_warn(_("multiply claimed byte %d in da block\n"), i); + return(1); + } + map[i / NBBY] |= (mask << i % NBBY); + } + + return(0); +} + +/* + * walk tree from root to the left-most leaf block reading in + * blocks and setting up cursor. passes back file block number of the + * left-most leaf block if successful (bno). returns 1 if successful, + * 0 if unsuccessful. + */ +static int +traverse_int_dablock(xfs_mount_t *mp, + da_bt_cursor_t *da_cursor, + xfs_dablk_t *rbno, + int whichfork) +{ + xfs_dablk_t bno; + int i; + xfs_da_intnode_t *node; + xfs_dfsbno_t fsbno; + xfs_buf_t *bp; + struct xfs_da_node_entry *btree; + struct xfs_da3_icnode_hdr nodehdr; + + /* + * traverse down left-side of tree until we hit the + * left-most leaf block setting up the btree cursor along + * the way. + */ + bno = 0; + i = -1; + node = NULL; + da_cursor->active = 0; + + do { + /* + * read in each block along the way and set up cursor + */ + fsbno = blkmap_get(da_cursor->blkmap, bno); + + if (fsbno == NULLDFSBNO) + goto error_out; + + bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), + XFS_FSB_TO_BB(mp, 1), 0, &xfs_da3_node_buf_ops); + if (!bp) { + if (whichfork == XFS_DATA_FORK) + do_warn( + _("can't read block %u (fsbno %" PRIu64 ") for directory inode %" PRIu64 "\n"), + bno, fsbno, da_cursor->ino); + else + do_warn( + _("can't read block %u (fsbno %" PRIu64 ") for attrbute fork of inode %" PRIu64 "\n"), + bno, fsbno, da_cursor->ino); + goto error_out; + } + + node = (xfs_da_intnode_t *)XFS_BUF_PTR(bp); + btree = xfs_da3_node_tree_p(node); + xfs_da3_node_hdr_from_disk(&nodehdr, node); + + if (nodehdr.magic != XFS_DA_NODE_MAGIC && + nodehdr.magic != XFS_DA3_NODE_MAGIC) { + do_warn(_("bad dir/attr magic number in inode %" PRIu64 ", " + "file bno = %u, fsbno = %" PRIu64 "\n"), + da_cursor->ino, bno, fsbno); + libxfs_putbuf(bp); + goto error_out; + } + + if (nodehdr.count > mp->m_dir_node_ents) { + do_warn(_("bad record count in inode %" PRIu64 ", " + "count = %d, max = %d\n"), + da_cursor->ino, + nodehdr.count, + mp->m_dir_node_ents); + libxfs_putbuf(bp); + goto error_out; + } + + /* + * maintain level counter + */ + if (i == -1) + i = da_cursor->active = nodehdr.level; + else { + if (nodehdr.level == i - 1) { + i--; + } else { + if (whichfork == XFS_DATA_FORK) + do_warn(_("bad directory btree for " + "directory inode %" PRIu64 "\n"), + da_cursor->ino); + else + do_warn(_("bad attribute fork btree " + "for inode %" PRIu64 "\n"), + da_cursor->ino); + libxfs_putbuf(bp); + goto error_out; + } + } + + da_cursor->level[i].hashval = be32_to_cpu(btree[0].hashval); + da_cursor->level[i].bp = bp; + da_cursor->level[i].bno = bno; + da_cursor->level[i].index = 0; +#ifdef XR_DIR_TRACE + da_cursor->level[i].n = XFS_BUF_TO_DA_INTNODE(bp); +#endif + + /* + * set up new bno for next level down + */ + bno = be32_to_cpu(btree[0].before); + } while (node != NULL && i > 1); + + /* + * now return block number and get out + */ + *rbno = da_cursor->level[0].bno = bno; + return(1); + +error_out: + while (i > 1 && i <= da_cursor->active) { + libxfs_putbuf(da_cursor->level[i].bp); + i++; + } + + return(0); +} + +/* + * blow out buffer for this level and all the rest above as well + * if error == 0, we are not expecting to encounter any unreleased + * buffers (e.g. if we do, it's a mistake). if error == 1, we're + * in an error-handling case so unreleased buffers may exist. + */ +static void +release_da_cursor_int(xfs_mount_t *mp, + da_bt_cursor_t *cursor, + int prev_level, + int error) +{ + int level = prev_level + 1; + + if (cursor->level[level].bp != NULL) { + if (!error) { + do_warn(_("release_da_cursor_int got unexpected " + "non-null bp, dabno = %u\n"), + cursor->level[level].bno); + } + ASSERT(error != 0); + + libxfs_putbuf(cursor->level[level].bp); + cursor->level[level].bp = NULL; + } + + if (level < cursor->active) + release_da_cursor_int(mp, cursor, level, error); + + return; +} + +static void +release_da_cursor(xfs_mount_t *mp, + da_bt_cursor_t *cursor, + int prev_level) +{ + release_da_cursor_int(mp, cursor, prev_level, 0); +} + +static void +err_release_da_cursor(xfs_mount_t *mp, + da_bt_cursor_t *cursor, + int prev_level) +{ + release_da_cursor_int(mp, cursor, prev_level, 1); +} + +/* + * make sure that all entries in all blocks along the right side of + * of the tree are used and hashval's are consistent. level is the + * level of the descendent block. returns 0 if good (even if it had + * to be fixed up), and 1 if bad. The right edge of the tree is + * technically a block boundary. this routine should be used then + * instead of verify_da_path(). + */ +static int +verify_final_da_path(xfs_mount_t *mp, + da_bt_cursor_t *cursor, + const int p_level) +{ + xfs_da_intnode_t *node; + xfs_dahash_t hashval; + int bad = 0; + int entry; + int this_level = p_level + 1; + struct xfs_da_node_entry *btree; + struct xfs_da3_icnode_hdr nodehdr; + +#ifdef XR_DIR_TRACE + fprintf(stderr, "in verify_final_da_path, this_level = %d\n", + this_level); +#endif + /* + * the index should point to the next "unprocessed" entry + * in the block which should be the final (rightmost) entry + */ + entry = cursor->level[this_level].index; + node = (xfs_da_intnode_t *)XFS_BUF_PTR(cursor->level[this_level].bp); + btree = xfs_da3_node_tree_p(node); + xfs_da3_node_hdr_from_disk(&nodehdr, node); + + /* + * check internal block consistency on this level -- ensure + * that all entries are used, encountered and expected hashvals + * match, etc. + */ + if (entry != nodehdr.count - 1) { + do_warn(_("directory/attribute block used/count " + "inconsistency - %d/%hu\n"), + entry, nodehdr.count); + bad++; + } + /* + * hash values monotonically increasing ??? + */ + if (cursor->level[this_level].hashval >= + be32_to_cpu(btree[entry].hashval)) { + do_warn(_("directory/attribute block hashvalue inconsistency, " + "expected > %u / saw %u\n"), + cursor->level[this_level].hashval, + be32_to_cpu(btree[entry].hashval)); + bad++; + } + if (nodehdr.forw != 0) { + do_warn(_("bad directory/attribute forward block pointer, " + "expected 0, saw %u\n"), + nodehdr.forw); + bad++; + } + if (bad) { + do_warn(_("bad directory block in dir ino %" PRIu64 "\n"), + cursor->ino); + return(1); + } + /* + * keep track of greatest block # -- that gets + * us the length of the directory + */ + if (cursor->level[this_level].bno > cursor->greatest_bno) + cursor->greatest_bno = cursor->level[this_level].bno; + + /* + * ok, now check descendant block number against this level + */ + if (cursor->level[p_level].bno != be32_to_cpu(btree[entry].before)) { +#ifdef XR_DIR_TRACE + fprintf(stderr, "bad directory btree pointer, child bno should " + "be %d, block bno is %d, hashval is %u\n", + be16_to_cpu(btree[entry].before), + cursor->level[p_level].bno, + cursor->level[p_level].hashval); + fprintf(stderr, "verify_final_da_path returns 1 (bad) #1a\n"); +#endif + return(1); + } + + if (cursor->level[p_level].hashval != be32_to_cpu(btree[entry].hashval)) { + if (!no_modify) { + do_warn(_("correcting bad hashval in non-leaf " + "dir/attr block\n\tin (level %d) in " + "inode %" PRIu64 ".\n"), + this_level, cursor->ino); + btree[entry].hashval = cpu_to_be32( + cursor->level[p_level].hashval); + cursor->level[this_level].dirty++; + } else { + do_warn(_("would correct bad hashval in non-leaf " + "dir/attr block\n\tin (level %d) in " + "inode %" PRIu64 ".\n"), + this_level, cursor->ino); + } + } + + /* + * Note: squirrel hashval away _before_ releasing the + * buffer, preventing a use-after-free problem. + */ + hashval = be32_to_cpu(btree[entry].hashval); + + /* + * release/write buffer + */ + ASSERT(cursor->level[this_level].dirty == 0 || + (cursor->level[this_level].dirty && !no_modify)); + + if (cursor->level[this_level].dirty && !no_modify) + libxfs_writebuf(cursor->level[this_level].bp, 0); + else + libxfs_putbuf(cursor->level[this_level].bp); + + cursor->level[this_level].bp = NULL; + + /* + * bail out if this is the root block (top of tree) + */ + if (this_level >= cursor->active) { +#ifdef XR_DIR_TRACE + fprintf(stderr, "verify_final_da_path returns 0 (ok)\n"); +#endif + return(0); + } + /* + * set hashvalue to correctly reflect the now-validated + * last entry in this block and continue upwards validation + */ + cursor->level[this_level].hashval = hashval; + return(verify_final_da_path(mp, cursor, this_level)); +} + +/* + * Verifies the path from a descendant block up to the root. + * Should be called when the descendant level traversal hits + * a block boundary before crossing the boundary (reading in a new + * block). + * + * the directory/attr btrees work differently to the other fs btrees. + * each interior block contains records that are + * pairs. The bno is a file bno, not a filesystem bno. The last + * hashvalue in the block will be . BUT unlike + * the freespace btrees, the *last* value in each block gets + * propagated up the tree instead of the first value in each block. + * that is, the interior records point to child blocks and the *greatest* + * hash value contained by the child block is the one the block above + * uses as the key for the child block. + * + * level is the level of the descendent block. returns 0 if good, + * and 1 if bad. The descendant block may be a leaf block. + * + * the invariant here is that the values in the cursor for the + * levels beneath this level (this_level) and the cursor index + * for this level *must* be valid. + * + * that is, the hashval/bno info is accurate for all + * DESCENDANTS and match what the node[index] information + * for the current index in the cursor for this level. + * + * the index values in the cursor for the descendant level + * are allowed to be off by one as they will reflect the + * next entry at those levels to be processed. + * + * the hashvalue for the current level can't be set until + * we hit the last entry in the block so, it's garbage + * until set by this routine. + * + * bno and bp for the current block/level are always valid + * since they have to be set so we can get a buffer for the + * block. + */ +static int +verify_da_path(xfs_mount_t *mp, + da_bt_cursor_t *cursor, + const int p_level) +{ + xfs_da_intnode_t *node; + xfs_da_intnode_t *newnode; + xfs_dfsbno_t fsbno; + xfs_dablk_t dabno; + xfs_buf_t *bp; + int bad; + int entry; + int this_level = p_level + 1; + struct xfs_da_node_entry *btree; + struct xfs_da3_icnode_hdr nodehdr; + + /* + * index is currently set to point to the entry that + * should be processed now in this level. + */ + entry = cursor->level[this_level].index; + node = (xfs_da_intnode_t *)XFS_BUF_PTR(cursor->level[this_level].bp); + btree = xfs_da3_node_tree_p(node); + xfs_da3_node_hdr_from_disk(&nodehdr, node); + + /* + * if this block is out of entries, validate this + * block and move on to the next block. + * and update cursor value for said level + */ + if (entry >= nodehdr.count) { + /* + * update the hash value for this level before + * validating it. bno value should be ok since + * it was set when the block was first read in. + */ + cursor->level[this_level].hashval = + be32_to_cpu(btree[entry - 1].hashval); + + /* + * keep track of greatest block # -- that gets + * us the length of the directory + */ + if (cursor->level[this_level].bno > cursor->greatest_bno) + cursor->greatest_bno = cursor->level[this_level].bno; + + /* + * validate the path for the current used-up block + * before we trash it + */ + if (verify_da_path(mp, cursor, this_level)) + return(1); + /* + * ok, now get the next buffer and check sibling pointers + */ + dabno = nodehdr.forw; + ASSERT(dabno != 0); + fsbno = blkmap_get(cursor->blkmap, dabno); + + if (fsbno == NULLDFSBNO) { + do_warn(_("can't get map info for block %u " + "of directory inode %" PRIu64 "\n"), + dabno, cursor->ino); + return(1); + } + + bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), + XFS_FSB_TO_BB(mp, 1), 0, &xfs_da3_node_buf_ops); + if (!bp) { + do_warn( + _("can't read block %u (%" PRIu64 ") for directory inode %" PRIu64 "\n"), + dabno, fsbno, cursor->ino); + return(1); + } + + newnode = (xfs_da_intnode_t *)XFS_BUF_PTR(bp); + btree = xfs_da3_node_tree_p(node); + xfs_da3_node_hdr_from_disk(&nodehdr, newnode); + /* + * verify magic number and back pointer, sanity-check + * entry count, verify level + */ + bad = 0; + if (nodehdr.magic != XFS_DA_NODE_MAGIC || + nodehdr.magic != XFS_DA3_NODE_MAGIC) { + do_warn( + _("bad magic number %x in block %u (%" PRIu64 ") for directory inode %" PRIu64 "\n"), + nodehdr.magic, + dabno, fsbno, cursor->ino); + bad++; + } + if (nodehdr.back != cursor->level[this_level].bno) { + do_warn( + _("bad back pointer in block %u (%"PRIu64 ") for directory inode %" PRIu64 "\n"), + dabno, fsbno, cursor->ino); + bad++; + } + if (nodehdr.count > mp->m_dir_node_ents) { + do_warn( + _("entry count %d too large in block %u (%" PRIu64 ") for directory inode %" PRIu64 "\n"), + nodehdr.count, + dabno, fsbno, cursor->ino); + bad++; + } + if (nodehdr.level != this_level) { + do_warn( + _("bad level %d in block %u (%" PRIu64 ") for directory inode %" PRIu64 "\n"), + nodehdr.level, + dabno, fsbno, cursor->ino); + bad++; + } + if (bad) { +#ifdef XR_DIR_TRACE + fprintf(stderr, "verify_da_path returns 1 (bad) #4\n"); +#endif + libxfs_putbuf(bp); + return(1); + } + + /* + * update cursor, write out the *current* level if + * required. don't write out the descendant level + */ + ASSERT(cursor->level[this_level].dirty == 0 || + (cursor->level[this_level].dirty && !no_modify)); + + if (cursor->level[this_level].dirty && !no_modify) + libxfs_writebuf(cursor->level[this_level].bp, 0); + else + libxfs_putbuf(cursor->level[this_level].bp); + + /* switch cursor to point at the new buffer we just read */ + cursor->level[this_level].bp = bp; + cursor->level[this_level].dirty = 0; + cursor->level[this_level].bno = dabno; + cursor->level[this_level].hashval = + be32_to_cpu(btree[0].hashval); +#ifdef XR_DIR_TRACE + cursor->level[this_level].n = newnode; +#endif + entry = cursor->level[this_level].index = 0; + + /* + * We want to rewrite the buffer on a CRC error seeing as it + * contains what appears to be a valid node block, but only if + * we are fixing errors. + */ + if (bp->b_error == EFSBADCRC && !no_modify) + cursor->level[this_level].dirty++; + } + /* + * ditto for block numbers + */ + if (cursor->level[p_level].bno != be32_to_cpu(btree[entry].before)) { +#ifdef XR_DIR_TRACE + fprintf(stderr, "bad directory btree pointer, child bno " + "should be %d, block bno is %d, hashval is %u\n", + be32_to_cpu(btree[entry].before), + cursor->level[p_level].bno, + cursor->level[p_level].hashval); + fprintf(stderr, "verify_da_path returns 1 (bad) #1a\n"); +#endif + return(1); + } + /* + * ok, now validate last hashvalue in the descendant + * block against the hashval in the current entry + */ + if (cursor->level[p_level].hashval != + be32_to_cpu(btree[entry].hashval)) { + if (!no_modify) { + do_warn(_("correcting bad hashval in interior " + "dir/attr block\n\tin (level %d) in " + "inode %" PRIu64 ".\n"), + this_level, cursor->ino); + btree[entry].hashval = cpu_to_be32( + cursor->level[p_level].hashval); + cursor->level[this_level].dirty++; + } else { + do_warn(_("would correct bad hashval in interior " + "dir/attr block\n\tin (level %d) in " + "inode %" PRIu64 ".\n"), + this_level, cursor->ino); + } + } + /* + * increment index for this level to point to next entry + * (which should point to the next descendant block) + */ + cursor->level[this_level].index++; +#ifdef XR_DIR_TRACE + fprintf(stderr, "verify_da_path returns 0 (ok)\n"); +#endif + return(0); +} /* * For attribute repair, there are 3 formats to worry about. First, is @@ -81,11 +734,15 @@ * If value is non-zero, then a remote attribute is being passed in */ static int -valuecheck(char *namevalue, char *value, int namelen, int valuelen) +valuecheck( + struct xfs_mount *mp, + char *namevalue, + char *value, + int namelen, + int valuelen) { /* for proper alignment issues, get the structs and memmove the values */ xfs_mac_label_t macl; - xfs_acl_t thisacl; void *valuep; int clearit = 0; @@ -93,18 +750,23 @@ (strncmp(namevalue, SGI_ACL_DEFAULT, SGI_ACL_DEFAULT_SIZE) == 0)) { if (value == NULL) { - memset(&thisacl, 0, sizeof(xfs_acl_t)); - memmove(&thisacl, namevalue+namelen, valuelen); - valuep = &thisacl; + valuep = malloc(valuelen); + if (!valuep) + do_error(_("No memory for ACL check!\n")); + memcpy(valuep, namevalue + namelen, valuelen); } else valuep = value; - if (xfs_acl_valid((xfs_acl_disk_t *)valuep) != 0) { + if (xfs_acl_valid(mp, valuep) != 0) { clearit = 1; do_warn( _("entry contains illegal value in attribute named SGI_ACL_FILE " "or SGI_ACL_DEFAULT\n")); } + + if (valuep != value) + free(valuep); + } else if (strncmp(namevalue, SGI_MAC_FILE, SGI_MAC_FILE_SIZE) == 0) { if (value == NULL) { memset(&macl, 0, sizeof(xfs_mac_label_t)); @@ -147,6 +809,7 @@ */ static int process_shortform_attr( + struct xfs_mount *mp, xfs_ino_t ino, xfs_dinode_t *dip, int *repair) @@ -251,7 +914,7 @@ /* Only check values for root security attributes */ if (currententry->flags & XFS_ATTR_ROOT) - junkit = valuecheck((char *)¤tentry->nameval[0], + junkit = valuecheck(mp, (char *)¤tentry->nameval[0], NULL, currententry->namelen, currententry->valuelen); @@ -332,6 +995,10 @@ xfs_dfsbno_t bno; xfs_buf_t *bp; int clearit = 0, i = 0, length = 0, amountdone = 0; + int hdrsize = 0; + + if (xfs_sb_version_hascrc(&mp->m_sb)) + hdrsize = sizeof(struct xfs_attr3_rmt_hdr); /* ASSUMPTION: valuelen is a valid number, so use it for looping */ /* Note that valuelen is not a multiple of blocksize */ @@ -344,16 +1011,26 @@ break; } bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno), - XFS_FSB_TO_BB(mp, 1), 0); + XFS_FSB_TO_BB(mp, 1), 0, + &xfs_attr3_rmt_buf_ops); if (!bp) { do_warn( _("can't read remote block for attributes of inode %" PRIu64 "\n"), ino); clearit = 1; break; } + + if (bp->b_error == EFSBADCRC || bp->b_error == EFSCORRUPTED) { + do_warn( + _("Corrupt remote block for attributes of inode %" PRIu64 "\n"), ino); + clearit = 1; + break; + } + ASSERT(mp->m_sb.sb_blocksize == XFS_BUF_COUNT(bp)); - length = MIN(XFS_BUF_COUNT(bp), valuelen - amountdone); - memmove(value, XFS_BUF_PTR(bp), length); + + length = MIN(XFS_BUF_COUNT(bp) - hdrsize, valuelen - amountdone); + memmove(value, XFS_BUF_PTR(bp) + hdrsize, length); amountdone += length; value += length; i++; @@ -372,6 +1049,7 @@ static int process_leaf_attr_local( + struct xfs_mount *mp, xfs_attr_leafblock_t *leaf, int i, xfs_attr_leaf_entry_t *entry, @@ -381,7 +1059,7 @@ { xfs_attr_leaf_name_local_t *local; - local = xfs_attr_leaf_name_local(leaf, i); + local = xfs_attr3_leaf_name_local(leaf, i); if (local->namelen == 0 || namecheck((char *)&local->nameval[0], local->namelen)) { do_warn( @@ -409,7 +1087,7 @@ /* Only check values for root security attributes */ if (entry->flags & XFS_ATTR_ROOT) { - if (valuecheck((char *)&local->nameval[0], NULL, + if (valuecheck(mp, (char *)&local->nameval[0], NULL, local->namelen, be16_to_cpu(local->valuelen))) { do_warn( _("bad security value for attribute entry %d in attr block %u, inode %" PRIu64 "\n"), @@ -435,7 +1113,7 @@ xfs_attr_leaf_name_remote_t *remotep; char* value; - remotep = xfs_attr_leaf_name_remote(leaf, i); + remotep = xfs_attr3_leaf_name_remote(leaf, i); if (remotep->namelen == 0 || namecheck((char *)&remotep->name[0], remotep->namelen) || @@ -467,7 +1145,7 @@ i, ino); goto bad_free_out; } - if (valuecheck((char *)&remotep->name[0], value, remotep->namelen, + if (valuecheck(mp, (char *)&remotep->name[0], value, remotep->namelen, be32_to_cpu(remotep->valuelen))) { do_warn( _("remote attribute value check failed for entry %d, inode %" PRIu64 "\n"), @@ -497,27 +1175,28 @@ xfs_attr_leaf_entry_t *entry; int i, start, stop, clearit, usedbs, firstb, thissize; da_freemap_t *attr_freemap; + struct xfs_attr3_icleaf_hdr leafhdr; + xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf); clearit = usedbs = 0; - *repair = 0; firstb = mp->m_sb.sb_blocksize; - stop = sizeof(xfs_attr_leaf_hdr_t); + stop = xfs_attr3_leaf_hdr_size(leaf); /* does the count look sorta valid? */ - if (be16_to_cpu(leaf->hdr.count) * sizeof(xfs_attr_leaf_entry_t) - + sizeof(xfs_attr_leaf_hdr_t) > XFS_LBSIZE(mp)) { + if (leafhdr.count * sizeof(xfs_attr_leaf_entry_t) + stop > + XFS_LBSIZE(mp)) { do_warn( _("bad attribute count %d in attr block %u, inode %" PRIu64 "\n"), - be16_to_cpu(leaf->hdr.count), da_bno, ino); - return (1); + leafhdr.count, da_bno, ino); + return 1; } attr_freemap = alloc_da_freemap(mp); (void) set_da_freemap(mp, attr_freemap, 0, stop); /* go thru each entry checking for problems */ - for (i = 0, entry = &leaf->entries[0]; - i < be16_to_cpu(leaf->hdr.count); i++, entry++) { + for (i = 0, entry = xfs_attr3_leaf_entryp(leaf); + i < leafhdr.count; i++, entry++) { /* check if index is within some boundary. */ if (be16_to_cpu(entry->nameidx) > XFS_LBSIZE(mp)) { @@ -538,7 +1217,7 @@ } /* mark the entry used */ - start = (__psint_t)&leaf->entries[i] - (__psint_t)leaf; + start = (__psint_t)entry - (__psint_t)leaf; stop = start + sizeof(xfs_attr_leaf_entry_t); if (set_da_freemap(mp, attr_freemap, start, stop)) { do_warn( @@ -548,15 +1227,15 @@ break; /* got an overlap */ } - if (entry->flags & XFS_ATTR_LOCAL) - thissize = process_leaf_attr_local(leaf, i, entry, + if (entry->flags & XFS_ATTR_LOCAL) + thissize = process_leaf_attr_local(mp, leaf, i, entry, last_hashval, da_bno, ino); else thissize = process_leaf_attr_remote(leaf, i, entry, last_hashval, da_bno, ino, mp, blkmap); if (thissize < 0) { - clearit = 1; + clearit = 1; break; } @@ -584,40 +1263,40 @@ * since the block will get compacted anyhow by the kernel. */ - if ((leaf->hdr.holes == 0 && - firstb != be16_to_cpu(leaf->hdr.firstused)) || - be16_to_cpu(leaf->hdr.firstused) > firstb) { + if ((leafhdr.holes == 0 && + firstb != leafhdr.firstused) || + leafhdr.firstused > firstb) { if (!no_modify) { do_warn( _("- resetting first used heap value from %d to %d in " "block %u of attribute fork of inode %" PRIu64 "\n"), - be16_to_cpu(leaf->hdr.firstused), + leafhdr.firstused, firstb, da_bno, ino); - leaf->hdr.firstused = cpu_to_be16(firstb); + leafhdr.firstused = firstb; *repair = 1; } else { do_warn( _("- would reset first used value from %d to %d in " "block %u of attribute fork of inode %" PRIu64 "\n"), - be16_to_cpu(leaf->hdr.firstused), + leafhdr.firstused, firstb, da_bno, ino); } } - if (usedbs != be16_to_cpu(leaf->hdr.usedbytes)) { + if (usedbs != leafhdr.usedbytes) { if (!no_modify) { do_warn( _("- resetting usedbytes cnt from %d to %d in " "block %u of attribute fork of inode %" PRIu64 "\n"), - be16_to_cpu(leaf->hdr.usedbytes), + leafhdr.usedbytes, usedbs, da_bno, ino); - leaf->hdr.usedbytes = cpu_to_be16(usedbs); + leafhdr.usedbytes = usedbs; *repair = 1; } else { do_warn( _("- would reset usedbytes cnt from %d to %d in " "block %u of attribute fork of %" PRIu64 "\n"), - be16_to_cpu(leaf->hdr.usedbytes), + leafhdr.usedbytes, usedbs, da_bno, ino); } } @@ -629,6 +1308,8 @@ * we can add it then. */ } + if (*repair) + xfs_attr3_leaf_hdr_to_disk(leaf, &leafhdr); free(attr_freemap); return (clearit); /* and repair */ @@ -651,6 +1332,7 @@ xfs_dablk_t prev_bno; xfs_dahash_t current_hashval = 0; xfs_dahash_t greatest_hashval; + struct xfs_attr3_icleaf_hdr leafhdr; da_bno = da_cursor->level[0].bno; ino = da_cursor->ino; @@ -673,21 +1355,26 @@ } bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, dev_bno), - XFS_FSB_TO_BB(mp, 1), 0); + XFS_FSB_TO_BB(mp, 1), 0, + &xfs_attr3_leaf_buf_ops); if (!bp) { do_warn( _("can't read file block %u (fsbno %" PRIu64 ") for attribute fork of inode %" PRIu64 "\n"), da_bno, dev_bno, ino); goto error_out; } + if (bp->b_error == EFSBADCRC) + repair++; - leaf = (xfs_attr_leafblock_t *)XFS_BUF_PTR(bp); + leaf = bp->b_addr; + xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf); /* check magic number for leaf directory btree block */ - if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) { + if (!(leafhdr.magic == XFS_ATTR_LEAF_MAGIC || + leafhdr.magic == XFS_ATTR3_LEAF_MAGIC)) { do_warn( _("bad attribute leaf magic %#x for inode %" PRIu64 "\n"), - leaf->hdr.info.magic, ino); + leafhdr.magic, ino); libxfs_putbuf(bp); goto error_out; } @@ -712,10 +1399,10 @@ da_cursor->level[0].hashval = greatest_hashval; da_cursor->level[0].bp = bp; da_cursor->level[0].bno = da_bno; - da_cursor->level[0].index = be16_to_cpu(leaf->hdr.count); + da_cursor->level[0].index = leafhdr.count; da_cursor->level[0].dirty = repair; - if (be32_to_cpu(leaf->hdr.info.back) != prev_bno) { + if (leafhdr.back != prev_bno) { do_warn( _("bad sibling back pointer for block %u in attribute fork for inode %" PRIu64 "\n"), da_bno, ino); @@ -724,7 +1411,7 @@ } prev_bno = da_bno; - da_bno = be32_to_cpu(leaf->hdr.info.forw); + da_bno = leafhdr.forw; if (da_bno != 0 && verify_da_path(mp, da_cursor, 0)) { libxfs_putbuf(bp); @@ -733,9 +1420,9 @@ current_hashval = greatest_hashval; - if (repair && !no_modify) + if (repair && !no_modify) libxfs_writebuf(bp, 0); - else + else libxfs_putbuf(bp); } while (da_bno != 0); @@ -833,6 +1520,7 @@ xfs_buf_t *bp; xfs_dahash_t next_hashval; int repairlinks = 0; + struct xfs_attr3_icleaf_hdr leafhdr; *repair = 0; @@ -855,29 +1543,32 @@ } bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno), - XFS_FSB_TO_BB(mp, 1), 0); + XFS_FSB_TO_BB(mp, 1), 0, &xfs_da3_node_buf_ops); if (!bp) { do_warn( _("can't read block 0 of inode %" PRIu64 " attribute fork\n"), ino); return(1); } + if (bp->b_error == EFSBADCRC) + (*repair)++; /* verify leaf block */ leaf = (xfs_attr_leafblock_t *)XFS_BUF_PTR(bp); + xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf); /* check sibling pointers in leaf block or root block 0 before * we have to release the btree block */ - if (be32_to_cpu(leaf->hdr.info.forw) != 0 || - be32_to_cpu(leaf->hdr.info.back) != 0) { + if (leafhdr.forw != 0 || leafhdr.back != 0) { if (!no_modify) { do_warn( _("clearing forw/back pointers in block 0 for attributes in inode %" PRIu64 "\n"), ino); repairlinks = 1; - leaf->hdr.info.forw = cpu_to_be32(0); - leaf->hdr.info.back = cpu_to_be32(0); + leafhdr.forw = 0; + leafhdr.back = 0; + xfs_attr3_leaf_hdr_to_disk(leaf, &leafhdr); } else { do_warn( _("would clear forw/back pointers in block 0 for attributes in inode %" PRIu64 "\n"), ino); @@ -889,8 +1580,9 @@ * it's possible to have a node or leaf attribute in either an * extent format or btree format attribute fork. */ - switch (be16_to_cpu(leaf->hdr.info.magic)) { + switch (leafhdr.magic) { case XFS_ATTR_LEAF_MAGIC: /* leaf-form attribute */ + case XFS_ATTR3_LEAF_MAGIC: if (process_leaf_attr_block(mp, leaf, 0, ino, blkmap, 0, &next_hashval, repair)) { /* the block is bad. lose the attribute fork. */ @@ -901,8 +1593,9 @@ break; case XFS_DA_NODE_MAGIC: /* btree-form attribute */ + case XFS_DA3_NODE_MAGIC: /* must do this now, to release block 0 before the traversal */ - if (repairlinks) { + if ((*repair || repairlinks) && !no_modify) { *repair = 1; libxfs_writebuf(bp, 0); } else @@ -926,23 +1619,27 @@ static int -xfs_acl_from_disk(struct xfs_acl **aclp, struct xfs_acl_disk *dacl) +xfs_acl_from_disk( + struct xfs_mount *mp, + struct xfs_icacl **aclp, + struct xfs_acl *dacl) { + struct xfs_icacl *acl; + struct xfs_icacl_entry *ace; + struct xfs_acl_entry *dace; int count; - xfs_acl_t *acl; - xfs_acl_entry_t *ace; - xfs_acl_entry_disk_t *dace, *end; + int i; count = be32_to_cpu(dacl->acl_cnt); - if (count > XFS_ACL_MAX_ENTRIES) { + if (count > XFS_ACL_MAX_ENTRIES(mp)) { do_warn(_("Too many ACL entries, count %d\n"), count); *aclp = NULL; return EINVAL; } - end = &dacl->acl_entry[0] + count; - acl = malloc((int)((char *)end - (char *)dacl)); + acl = malloc(sizeof(struct xfs_icacl) + + count * sizeof(struct xfs_icacl_entry)); if (!acl) { do_warn(_("cannot malloc enough for ACL attribute\n")); do_warn(_("SKIPPING this ACL\n")); @@ -951,8 +1648,10 @@ } acl->acl_cnt = count; - ace = &acl->acl_entry[0]; - for (dace = &dacl->acl_entry[0]; dace < end; ace++, dace++) { + for (i = 0; i < count; i++) { + ace = &acl->acl_entry[i]; + dace = &dacl->acl_entry[i]; + ace->ae_tag = be32_to_cpu(dace->ae_tag); ace->ae_id = be32_to_cpu(dace->ae_id); ace->ae_perm = be16_to_cpu(dace->ae_perm); @@ -976,14 +1675,16 @@ { int err; __u8 aformat = dip->di_aformat; +#ifdef DEBUG xfs_attr_shortform_t *asf; asf = (xfs_attr_shortform_t *) XFS_DFORK_APTR(dip); +#endif if (aformat == XFS_DINODE_FMT_LOCAL) { ASSERT(be16_to_cpu(asf->hdr.totsize) <= XFS_DFORK_ASIZE(dip, mp)); - err = process_shortform_attr(ino, dip, repair); + err = process_shortform_attr(mp, ino, dip, repair); } else if (aformat == XFS_DINODE_FMT_EXTENTS || aformat == XFS_DINODE_FMT_BTREE) { err = process_longform_attr(mp, ino, dip, blkmap, @@ -1002,17 +1703,19 @@ * Validate an ACL */ static int -xfs_acl_valid(xfs_acl_disk_t *daclp) +xfs_acl_valid( + struct xfs_mount *mp, + struct xfs_acl *daclp) { - xfs_acl_t *aclp; - xfs_acl_entry_t *entry, *e; + struct xfs_icacl *aclp = NULL; + struct xfs_icacl_entry *entry, *e; int user = 0, group = 0, other = 0, mask = 0, mask_required = 0; int i, j; if (daclp == NULL) goto acl_invalid; - switch (xfs_acl_from_disk(&aclp, daclp)) { + switch (xfs_acl_from_disk(mp, &aclp, daclp)) { case ENOMEM: return 0; case EINVAL: diff -Nru xfsprogs-3.1.9ubuntu2/repair/attr_repair.h xfsprogs-3.2.1ubuntu1/repair/attr_repair.h --- xfsprogs-3.1.9ubuntu2/repair/attr_repair.h 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/attr_repair.h 2014-07-21 09:13:53.000000000 +0000 @@ -37,29 +37,49 @@ typedef __int32_t xfs_acl_tag_t; typedef __int32_t xfs_acl_id_t; -typedef struct xfs_acl_entry { +/* + * "icacl" = in-core ACL. There is no equivalent in the XFS kernel code, + * so they are magic names just for repair. The "acl" types are what the kernel + * code uses for the on-disk format names, so use them here too for the on-disk + * ACL format definitions. + */ +struct xfs_icacl_entry { xfs_acl_tag_t ae_tag; xfs_acl_id_t ae_id; xfs_acl_perm_t ae_perm; -} xfs_acl_entry_t; +}; -#define XFS_ACL_MAX_ENTRIES 25 -typedef struct xfs_acl { - __int32_t acl_cnt; - xfs_acl_entry_t acl_entry[XFS_ACL_MAX_ENTRIES]; -} xfs_acl_t; +struct xfs_icacl { + __int32_t acl_cnt; + struct xfs_icacl_entry acl_entry[0]; +}; -typedef struct xfs_acl_entry_disk { +struct xfs_acl_entry { __be32 ae_tag; __be32 ae_id; __be16 ae_perm; -} xfs_acl_entry_disk_t; - -typedef struct xfs_acl_disk { - __be32 acl_cnt; - xfs_acl_entry_disk_t acl_entry[XFS_ACL_MAX_ENTRIES]; -} xfs_acl_disk_t; + __be16 ae_pad; +}; +struct xfs_acl { + __be32 acl_cnt; + struct xfs_acl_entry acl_entry[0]; +}; + +/* + * The number of ACL entries allowed is defined by the on-disk format. + * For v4 superblocks, that is limited to 25 entries. For v5 superblocks, it is + * limited only by the maximum size of the xattr that stores the information. + */ +#define XFS_ACL_MAX_ENTRIES(mp) \ + (xfs_sb_version_hascrc(&mp->m_sb) \ + ? (XATTR_SIZE_MAX - sizeof(struct xfs_acl)) / \ + sizeof(struct xfs_acl_entry) \ + : 25) + +#define XFS_ACL_MAX_SIZE(mp) \ + (sizeof(struct xfs_acl) + \ + sizeof(struct xfs_acl_entry) * XFS_ACL_MAX_ENTRIES((mp))) #define SGI_ACL_FILE "SGI_ACL_FILE" #define SGI_ACL_DEFAULT "SGI_ACL_DEFAULT" diff -Nru xfsprogs-3.1.9ubuntu2/repair/bmap.c xfsprogs-3.2.1ubuntu1/repair/bmap.c --- xfsprogs-3.1.9ubuntu2/repair/bmap.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/bmap.c 2014-05-19 03:19:14.000000000 +0000 @@ -47,16 +47,16 @@ if (nex < 1) nex = 1; +#if (BITS_PER_LONG == 32) /* on 64-bit platforms this is never true */ if (nex > BLKMAP_NEXTS_MAX) { -#if (BITS_PER_LONG == 32) do_warn( _("Number of extents requested in blkmap_alloc (%d) overflows 32 bits.\n" "If this is not a corruption, then you will need a 64 bit system\n" "to repair this filesystem.\n"), nex); -#endif return NULL; } +#endif key = whichfork ? ablkmap_key : dblkmap_key; blkmap = pthread_getspecific(key); @@ -260,22 +260,30 @@ { pthread_key_t key = dblkmap_key; blkmap_t *new_blkmap; - int new_naexts = blkmap->naexts + 4; + int new_naexts; + + /* reduce the number of reallocations for large files */ + if (blkmap->naexts < 1000) + new_naexts = blkmap->naexts + 4; + else if (blkmap->naexts < 10000) + new_naexts = blkmap->naexts + 100; + else + new_naexts = blkmap->naexts + 1000; if (pthread_getspecific(key) != blkmap) { key = ablkmap_key; ASSERT(pthread_getspecific(key) == blkmap); } +#if (BITS_PER_LONG == 32) /* on 64-bit platforms this is never true */ if (new_naexts > BLKMAP_NEXTS_MAX) { -#if (BITS_PER_LONG == 32) do_error( _("Number of extents requested in blkmap_grow (%d) overflows 32 bits.\n" "You need a 64 bit system to repair this filesystem.\n"), new_naexts); -#endif return NULL; } +#endif if (new_naexts <= 0) { do_error( _("Number of extents requested in blkmap_grow (%d) overflowed the\n" @@ -318,15 +326,33 @@ } ASSERT(blkmap->nexts < blkmap->naexts); - for (i = 0; i < blkmap->nexts; i++) { - if (blkmap->exts[i].startoff > o) { - memmove(blkmap->exts + i + 1, - blkmap->exts + i, - sizeof(bmap_ext_t) * (blkmap->nexts - i)); + + if (blkmap->nexts == 0) { + i = 0; + goto insert; + } + + /* + * The most common insert pattern comes from an ascending offset order + * bmapbt scan. In this case, the extent being added will end up at the + * end of the array. Hence do a reverse order search for the insertion + * point so we don't needlessly scan the entire array on every + * insertion. + * + * Also, use "plus 1" indexing for the loop counter so when we break out + * of the loop we are at the correct index for insertion. + */ + for (i = blkmap->nexts; i > 0; i--) { + if (blkmap->exts[i - 1].startoff < o) break; - } } + /* make space for the new extent */ + memmove(blkmap->exts + i + 1, + blkmap->exts + i, + sizeof(bmap_ext_t) * (blkmap->nexts - i)); + +insert: blkmap->exts[i].startoff = o; blkmap->exts[i].startblock = b; blkmap->exts[i].blockcount = c; diff -Nru xfsprogs-3.1.9ubuntu2/repair/dino_chunks.c xfsprogs-3.2.1ubuntu1/repair/dino_chunks.c --- xfsprogs-3.1.9ubuntu2/repair/dino_chunks.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/dino_chunks.c 2014-05-02 00:09:16.000000000 +0000 @@ -23,7 +23,6 @@ #include "incore.h" #include "protos.h" #include "err_protos.h" -#include "dir.h" #include "dinode.h" #include "versions.h" #include "prefetch.h" @@ -53,7 +52,7 @@ * so no one else will overlap them. */ bp = libxfs_readbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, agbno), - XFS_FSB_TO_BB(mp, 1), 0); + XFS_FSB_TO_BB(mp, 1), 0, NULL); if (!bp) { do_warn(_("cannot read agbno (%u/%u), disk block %" PRId64 "\n"), agno, agbno, XFS_AGB_TO_DADDR(mp, agno, agbno)); @@ -66,6 +65,8 @@ XFS_OFFBNO_TO_AGINO(mp, agbno, i))) cnt++; } + if (cnt) + bp->b_ops = &xfs_inode_buf_ops; libxfs_putbuf(bp); return(cnt); @@ -140,7 +141,7 @@ if (check_aginode_block(mp, agno, agino) == 0) return 0; - pthread_mutex_lock(&ag_locks[agno]); + pthread_mutex_lock(&ag_locks[agno].lock); state = get_bmap(agno, agbno); switch (state) { @@ -165,7 +166,7 @@ _("inode block %d/%d multiply claimed, (state %d)\n"), agno, agbno, state); set_bmap(agno, agbno, XR_E_MULT); - pthread_mutex_unlock(&ag_locks[agno]); + pthread_mutex_unlock(&ag_locks[agno].lock); return(0); default: do_warn( @@ -175,7 +176,7 @@ break; } - pthread_mutex_unlock(&ag_locks[agno]); + pthread_mutex_unlock(&ag_locks[agno].lock); start_agino = XFS_OFFBNO_TO_AGINO(mp, agbno, 0); *start_ino = XFS_AGINO_TO_INO(mp, agno, start_agino); @@ -423,7 +424,7 @@ * user data -- we're probably here as a result of a directory * entry or an iunlinked pointer */ - pthread_mutex_lock(&ag_locks[agno]); + pthread_mutex_lock(&ag_locks[agno].lock); for (cur_agbno = chunk_start_agbno; cur_agbno < chunk_stop_agbno; cur_agbno += blen) { @@ -437,7 +438,7 @@ _("inode block %d/%d multiply claimed, (state %d)\n"), agno, cur_agbno, state); set_bmap_ext(agno, cur_agbno, blen, XR_E_MULT); - pthread_mutex_unlock(&ag_locks[agno]); + pthread_mutex_unlock(&ag_locks[agno].lock); return 0; case XR_E_INO: do_error( @@ -448,7 +449,7 @@ break; } } - pthread_mutex_unlock(&ag_locks[agno]); + pthread_mutex_unlock(&ag_locks[agno].lock); /* * ok, chunk is good. put the record into the tree if required, @@ -471,7 +472,7 @@ set_inode_used(irec_p, agino - start_agino); - pthread_mutex_lock(&ag_locks[agno]); + pthread_mutex_lock(&ag_locks[agno].lock); for (cur_agbno = chunk_start_agbno; cur_agbno < chunk_stop_agbno; @@ -504,7 +505,7 @@ break; } } - pthread_mutex_unlock(&ag_locks[agno]); + pthread_mutex_unlock(&ag_locks[agno].lock); return(ino_cnt); } @@ -626,7 +627,8 @@ bplist[bp_index] = libxfs_readbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, agbno), - XFS_FSB_TO_BB(mp, blks_per_cluster), 0); + XFS_FSB_TO_BB(mp, blks_per_cluster), 0, + &xfs_inode_buf_ops); if (!bplist[bp_index]) { do_warn(_("cannot read inode %" PRIu64 ", disk block %" PRId64 ", cnt %d\n"), XFS_AGINO_TO_INO(mp, agno, first_irec->ino_startnum), @@ -640,6 +642,7 @@ return(1); } agbno += blks_per_cluster; + bplist[bp_index]->b_ops = &xfs_inode_buf_ops; pftrace("readbuf %p (%llu, %d) in AG %d", bplist[bp_index], (long long)XFS_BUF_ADDR(bplist[bp_index]), @@ -733,7 +736,7 @@ /* * mark block as an inode block in the incore bitmap */ - pthread_mutex_lock(&ag_locks[agno]); + pthread_mutex_lock(&ag_locks[agno].lock); state = get_bmap(agno, agbno); switch (state) { case XR_E_INO: /* already marked */ @@ -752,7 +755,7 @@ XFS_AGB_TO_FSB(mp, agno, agbno), state); break; } - pthread_mutex_unlock(&ag_locks[agno]); + pthread_mutex_unlock(&ag_locks[agno].lock); for (;;) { /* @@ -772,8 +775,11 @@ extra_attr_check, &isa_dir, &parent); ASSERT(is_used != 3); - if (ino_dirty) + if (ino_dirty) { dirty = 1; + libxfs_dinode_calc_crc(mp, dino); + } + /* * XXX - if we want to try and keep * track of whether we need to bang on @@ -782,6 +788,8 @@ * we do now, this is where to start. */ if (is_used) { + __uint16_t di_mode; + if (is_inode_free(ino_rec, irec_offset)) { if (verbose || no_modify) { do_warn( @@ -797,6 +805,15 @@ set_inode_used(ino_rec, irec_offset); /* + * store the on-disk file type for comparing in + * phase 6. + */ + di_mode = be16_to_cpu(dino->di_mode); + di_mode = (di_mode & S_IFMT) >> S_SHIFT; + set_inode_ftype(ino_rec, irec_offset, + xfs_mode_to_ftype[di_mode]); + + /* * store on-disk nlink count for comparing in phase 7 */ set_inode_disk_nlinks(ino_rec, irec_offset, @@ -908,7 +925,7 @@ ibuf_offset = 0; agbno++; - pthread_mutex_lock(&ag_locks[agno]); + pthread_mutex_lock(&ag_locks[agno].lock); state = get_bmap(agno, agbno); switch (state) { case XR_E_INO: /* already marked */ @@ -929,7 +946,7 @@ XFS_AGB_TO_FSB(mp, agno, agbno), state); break; } - pthread_mutex_unlock(&ag_locks[agno]); + pthread_mutex_unlock(&ag_locks[agno].lock); } else if (irec_offset == XFS_INODES_PER_CHUNK) { /* diff -Nru xfsprogs-3.1.9ubuntu2/repair/dinode.c xfsprogs-3.2.1ubuntu1/repair/dinode.c --- xfsprogs-3.1.9ubuntu2/repair/dinode.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/dinode.c 2014-05-02 00:09:16.000000000 +0000 @@ -23,7 +23,6 @@ #include "incore.h" #include "protos.h" #include "err_protos.h" -#include "dir.h" #include "dir2.h" #include "dinode.h" #include "scan.h" @@ -33,6 +32,37 @@ #include "threads.h" /* + * gettext lookups for translations of strings use mutexes internally to + * the library. Hence when we come through here doing parallel scans in + * multiple AGs, then all do concurrent text conversions and serialise + * on the translation string lookups. Let's avoid doing repeated lookups + * by making them static variables and only assigning the translation + * once. + */ +static char *forkname_data; +static char *forkname_attr; +static char *ftype_real_time; +static char *ftype_regular; + +void +dinode_bmbt_translation_init(void) +{ + forkname_data = _("data"); + forkname_attr = _("attr"); + ftype_real_time = _("real-time"); + ftype_regular = _("regular"); +} + +char * +get_forkname(int whichfork) +{ + + if (whichfork == XFS_DATA_FORK) + return forkname_data; + return forkname_attr; +} + +/* * inode clearing routines */ @@ -86,139 +116,127 @@ } static int -clear_dinode_core(xfs_dinode_t *dinoc, xfs_ino_t ino_num) +clear_dinode_core(struct xfs_mount *mp, xfs_dinode_t *dinoc, xfs_ino_t ino_num) { int dirty = 0; + int i; - if (be16_to_cpu(dinoc->di_magic) != XFS_DINODE_MAGIC) { - dirty = 1; - - if (no_modify) - return(1); +#define __dirty_no_modify_ret(dirty) \ + ({ (dirty) = 1; if (no_modify) return 1; }) + if (be16_to_cpu(dinoc->di_magic) != XFS_DINODE_MAGIC) { + __dirty_no_modify_ret(dirty); dinoc->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); } if (!XFS_DINODE_GOOD_VERSION(dinoc->di_version) || (!fs_inode_nlink && dinoc->di_version > 1)) { - dirty = 1; - - if (no_modify) - return(1); - - dinoc->di_version = (fs_inode_nlink) ? 2 : 1; + __dirty_no_modify_ret(dirty); + if (xfs_sb_version_hascrc(&mp->m_sb)) + dinoc->di_version = 3; + else + dinoc->di_version = (fs_inode_nlink) ? 2 : 1; } if (be16_to_cpu(dinoc->di_mode) != 0) { - dirty = 1; - - if (no_modify) - return(1); - + __dirty_no_modify_ret(dirty); dinoc->di_mode = 0; } if (be16_to_cpu(dinoc->di_flags) != 0) { - dirty = 1; - - if (no_modify) - return(1); - + __dirty_no_modify_ret(dirty); dinoc->di_flags = 0; } if (be32_to_cpu(dinoc->di_dmevmask) != 0) { - dirty = 1; - - if (no_modify) - return(1); - + __dirty_no_modify_ret(dirty); dinoc->di_dmevmask = 0; } if (dinoc->di_forkoff != 0) { - dirty = 1; - - if (no_modify) - return(1); - + __dirty_no_modify_ret(dirty); dinoc->di_forkoff = 0; } if (dinoc->di_format != XFS_DINODE_FMT_EXTENTS) { - dirty = 1; - - if (no_modify) - return(1); - + __dirty_no_modify_ret(dirty); dinoc->di_format = XFS_DINODE_FMT_EXTENTS; } if (dinoc->di_aformat != XFS_DINODE_FMT_EXTENTS) { - dirty = 1; - - if (no_modify) - return(1); - + __dirty_no_modify_ret(dirty); dinoc->di_aformat = XFS_DINODE_FMT_EXTENTS; } if (be64_to_cpu(dinoc->di_size) != 0) { - dirty = 1; - - if (no_modify) - return(1); - + __dirty_no_modify_ret(dirty); dinoc->di_size = 0; } if (be64_to_cpu(dinoc->di_nblocks) != 0) { - dirty = 1; - - if (no_modify) - return(1); - + __dirty_no_modify_ret(dirty); dinoc->di_nblocks = 0; } if (be16_to_cpu(dinoc->di_onlink) != 0) { - dirty = 1; - - if (no_modify) - return(1); - + __dirty_no_modify_ret(dirty); dinoc->di_onlink = 0; } if (be32_to_cpu(dinoc->di_nextents) != 0) { - dirty = 1; - - if (no_modify) - return(1); - + __dirty_no_modify_ret(dirty); dinoc->di_nextents = 0; } if (be16_to_cpu(dinoc->di_anextents) != 0) { - dirty = 1; - - if (no_modify) - return(1); - + __dirty_no_modify_ret(dirty); dinoc->di_anextents = 0; } if (dinoc->di_version > 1 && be32_to_cpu(dinoc->di_nlink) != 0) { - dirty = 1; + __dirty_no_modify_ret(dirty); + dinoc->di_nlink = 0; + } - if (no_modify) - return(1); + /* we are done for version 1/2 inodes */ + if (dinoc->di_version < 3) + return dirty; - dinoc->di_nlink = 0; + if (be64_to_cpu(dinoc->di_ino) != ino_num) { + __dirty_no_modify_ret(dirty); + dinoc->di_ino = cpu_to_be64(ino_num); } - return(dirty); + if (platform_uuid_compare(&dinoc->di_uuid, &mp->m_sb.sb_uuid)) { + __dirty_no_modify_ret(dirty); + platform_uuid_copy(&dinoc->di_uuid, &mp->m_sb.sb_uuid); + } + + for (i = 0; i < sizeof(dinoc->di_pad2)/sizeof(dinoc->di_pad2[0]); i++) { + if (dinoc->di_pad2[i] != 0) { + __dirty_no_modify_ret(dirty); + memset(dinoc->di_pad2, 0, sizeof(dinoc->di_pad2)); + break; + } + } + + if (be64_to_cpu(dinoc->di_flags2) != 0) { + __dirty_no_modify_ret(dirty); + dinoc->di_flags2 = 0; + } + + if (be64_to_cpu(dinoc->di_lsn) != 0) { + __dirty_no_modify_ret(dirty); + dinoc->di_lsn = 0; + } + + if (be64_to_cpu(dinoc->di_changecount) != 0) { + __dirty_no_modify_ret(dirty); + dinoc->di_changecount = 0; + } + + return dirty; } static int @@ -244,13 +262,14 @@ { int dirty; - dirty = clear_dinode_core(dino, ino_num); + dirty = clear_dinode_core(mp, dino, ino_num); dirty += clear_dinode_unlinked(mp, dino); /* and clear the forks */ if (dirty && !no_modify) - memset(XFS_DFORK_DPTR(dino), 0, XFS_LITINO(mp)); + memset(XFS_DFORK_DPTR(dino), 0, + XFS_LITINO(mp, dino->di_version)); return(dirty); } @@ -554,7 +573,7 @@ xfs_dfiloff_t op = 0; /* prev offset */ xfs_dfsbno_t b; char *ftype; - char *forkname; + char *forkname = get_forkname(whichfork); int i; int state; xfs_agnumber_t agno; @@ -564,15 +583,10 @@ xfs_agnumber_t locked_agno = -1; int error = 1; - if (whichfork == XFS_DATA_FORK) - forkname = _("data"); - else - forkname = _("attr"); - if (type == XR_INO_RTDATA) - ftype = _("real-time"); + ftype = ftype_real_time; else - ftype = _("regular"); + ftype = ftype_regular; for (i = 0; i < *numrecs; i++) { libxfs_bmbt_disk_get_all(rp + i, &irec); @@ -663,9 +677,10 @@ } if (blkmapp && *blkmapp) { - error = blkmap_set_ext(blkmapp, irec.br_startoff, + int error2; + error2 = blkmap_set_ext(blkmapp, irec.br_startoff, irec.br_startblock, irec.br_blockcount); - if (error) { + if (error2) { /* * we don't want to clear the inode due to an * internal bmap tracking error, but if we've @@ -677,7 +692,7 @@ do_abort( _("Fatal error: inode %" PRIu64 " - blkmap_set_ext(): %s\n" "\t%s fork, off - %" PRIu64 ", start - %" PRIu64 ", cnt %" PRIu64 "\n"), - ino, strerror(error), forkname, + ino, strerror(error2), forkname, irec.br_startoff, irec.br_startblock, irec.br_blockcount); } @@ -692,8 +707,8 @@ ebno = agbno + irec.br_blockcount; if (agno != locked_agno) { if (locked_agno != -1) - pthread_mutex_unlock(&ag_locks[locked_agno]); - pthread_mutex_lock(&ag_locks[agno]); + pthread_mutex_unlock(&ag_locks[locked_agno].lock); + pthread_mutex_lock(&ag_locks[agno].lock); locked_agno = agno; } @@ -762,7 +777,7 @@ error = 0; done: if (locked_agno != -1) - pthread_mutex_unlock(&ag_locks[locked_agno]); + pthread_mutex_unlock(&ag_locks[locked_agno].lock); if (i != *numrecs) { ASSERT(i < *numrecs); @@ -836,7 +851,8 @@ size = XFS_FSB_TO_BB(mp, MAX(1, XFS_INODES_PER_CHUNK/inodes_per_block)); bp = libxfs_readbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, - XFS_AGINO_TO_AGBNO(mp, irec->ino_startnum)), size, 0); + XFS_AGINO_TO_AGBNO(mp, irec->ino_startnum)), size, 0, + &xfs_inode_buf_ops); if (!bp) { do_warn(_("cannot read inode (%u/%u), disk block %" PRIu64 "\n"), agno, irec->ino_startnum, @@ -854,245 +870,6 @@ } /* - * these next routines return the filesystem blockno of the - * block containing the block "bno" in the file whose bmap - * tree (or extent list) is rooted by "rootblock". - * - * the next routines are utility routines for the third - * routine, get_bmapi(). - * - * NOTE: getfunc_extlist only used by dirv1 checking code - */ -static xfs_dfsbno_t -getfunc_extlist(xfs_mount_t *mp, - xfs_ino_t ino, - xfs_dinode_t *dip, - xfs_dfiloff_t bno, - int whichfork) -{ - xfs_bmbt_irec_t irec; - xfs_dfsbno_t final_fsbno = NULLDFSBNO; - xfs_bmbt_rec_t *rootblock = (xfs_bmbt_rec_t *) - XFS_DFORK_PTR(dip, whichfork); - xfs_extnum_t nextents = XFS_DFORK_NEXTENTS(dip, whichfork); - int i; - - for (i = 0; i < nextents; i++) { - libxfs_bmbt_disk_get_all(rootblock + i, &irec); - if (irec.br_startoff <= bno && - bno < irec.br_startoff + irec.br_blockcount) { - final_fsbno = bno - irec.br_startoff + irec.br_startblock; - break; - } - } - - return(final_fsbno); -} - -/* - * NOTE: getfunc_btree only used by dirv1 checking code... - */ -static xfs_dfsbno_t -getfunc_btree(xfs_mount_t *mp, - xfs_ino_t ino, - xfs_dinode_t *dip, - xfs_dfiloff_t bno, - int whichfork) -{ - int i; -#ifdef DEBUG - int prev_level; -#endif - int found; - int numrecs; - xfs_bmbt_rec_t *rec; - xfs_bmbt_irec_t irec; - xfs_bmbt_ptr_t *pp; - xfs_bmbt_key_t *key; - xfs_bmdr_key_t *rkey; - xfs_bmdr_ptr_t *rp; - xfs_dfsbno_t fsbno; - xfs_buf_t *bp; - xfs_dfsbno_t final_fsbno = NULLDFSBNO; - struct xfs_btree_block *block; - xfs_bmdr_block_t *rootblock = (xfs_bmdr_block_t *) - XFS_DFORK_PTR(dip, whichfork); - - ASSERT(rootblock->bb_level != 0); - /* - * deal with root block, it's got a slightly different - * header structure than interior nodes. We know that - * a btree should have at least 2 levels otherwise it - * would be an extent list. - */ - rkey = XFS_BMDR_KEY_ADDR(rootblock, 1); - rp = XFS_BMDR_PTR_ADDR(rootblock, 1, - xfs_bmdr_maxrecs(mp, XFS_DFORK_SIZE(dip, mp, whichfork), 1)); - found = -1; - for (i = 0; i < be16_to_cpu(rootblock->bb_numrecs) - 1; i++) { - if (be64_to_cpu(rkey[i].br_startoff) <= bno && - bno < be64_to_cpu(rkey[i + 1].br_startoff)) { - found = i; - break; - } - } - if (i == be16_to_cpu(rootblock->bb_numrecs) - 1 && - bno >= be64_to_cpu(rkey[i].br_startoff)) - found = i; - - ASSERT(found != -1); - - fsbno = be64_to_cpu(rp[found]); - - ASSERT(verify_dfsbno(mp, fsbno)); - - bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), - XFS_FSB_TO_BB(mp, 1), 0); - if (!bp) { - do_error(_("cannot read bmap block %" PRIu64 "\n"), fsbno); - return(NULLDFSBNO); - } - block = XFS_BUF_TO_BLOCK(bp); - numrecs = be16_to_cpu(block->bb_numrecs); - - /* - * ok, now traverse any interior btree nodes - */ -#ifdef DEBUG - prev_level = be16_to_cpu(block->bb_level); -#endif - - while (be16_to_cpu(block->bb_level) > 0) { -#ifdef DEBUG - ASSERT(be16_to_cpu(block->bb_level) < prev_level); - - prev_level = be16_to_cpu(block->bb_level); -#endif - if (numrecs > mp->m_bmap_dmxr[1]) { - do_warn( -_("# of bmap records in inode %" PRIu64 " exceeds max (%u, max - %u)\n"), - ino, numrecs, - mp->m_bmap_dmxr[1]); - libxfs_putbuf(bp); - return(NULLDFSBNO); - } - if (verbose && numrecs < mp->m_bmap_dmnr[1]) { - do_warn( -_("- # of bmap records in inode %" PRIu64 " less than minimum (%u, min - %u), proceeding ...\n"), - ino, numrecs, mp->m_bmap_dmnr[1]); - } - key = XFS_BMBT_KEY_ADDR(mp, block, 1); - pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); - for (found = -1, i = 0; i < numrecs - 1; i++) { - if (be64_to_cpu(key[i].br_startoff) <= bno && bno < - be64_to_cpu(key[i + 1].br_startoff)) { - found = i; - break; - } - } - if (i == numrecs - 1 && bno >= be64_to_cpu(key[i].br_startoff)) - found = i; - - ASSERT(found != -1); - fsbno = be64_to_cpu(pp[found]); - - ASSERT(verify_dfsbno(mp, fsbno)); - - /* - * release current btree block and read in the - * next btree block to be traversed - */ - libxfs_putbuf(bp); - bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), - XFS_FSB_TO_BB(mp, 1), 0); - if (!bp) { - do_error(_("cannot read bmap block %" PRIu64 "\n"), - fsbno); - return(NULLDFSBNO); - } - block = XFS_BUF_TO_BLOCK(bp); - numrecs = be16_to_cpu(block->bb_numrecs); - } - - /* - * current block must be a leaf block - */ - ASSERT(be16_to_cpu(block->bb_level) == 0); - if (numrecs > mp->m_bmap_dmxr[0]) { - do_warn( -_("# of bmap records in inode %" PRIu64 " greater than maximum (%u, max - %u)\n"), - ino, numrecs, mp->m_bmap_dmxr[0]); - libxfs_putbuf(bp); - return(NULLDFSBNO); - } - if (verbose && numrecs < mp->m_bmap_dmnr[0]) - do_warn( -_("- # of bmap records in inode %" PRIu64 " less than minimum (%u, min - %u), continuing...\n"), - ino, numrecs, mp->m_bmap_dmnr[0]); - - rec = XFS_BMBT_REC_ADDR(mp, block, 1); - for (i = 0; i < numrecs; i++) { - libxfs_bmbt_disk_get_all(rec + i, &irec); - if (irec.br_startoff <= bno && - bno < irec.br_startoff + irec.br_blockcount) { - final_fsbno = bno - irec.br_startoff + - irec.br_startblock; - break; - } - } - libxfs_putbuf(bp); - - if (final_fsbno == NULLDFSBNO) - do_warn(_("could not map block %" PRIu64 "\n"), bno); - - return(final_fsbno); -} - -/* - * this could be smarter. maybe we should have an open inode - * routine that would get the inode buffer and return back - * an inode handle. I'm betting for the moment that this - * is used only by the directory and attribute checking code - * and that the avl tree find and buffer cache search are - * relatively cheap. If they're too expensive, we'll just - * have to fix this and add an inode handle to the da btree - * cursor. - * - * caller is responsible for checking doubly referenced blocks - * and references to holes - * - * NOTE: get_bmapi only used by dirv1 checking code - */ -xfs_dfsbno_t -get_bmapi(xfs_mount_t *mp, xfs_dinode_t *dino_p, - xfs_ino_t ino_num, xfs_dfiloff_t bno, int whichfork) -{ - xfs_dfsbno_t fsbno; - - switch (XFS_DFORK_FORMAT(dino_p, whichfork)) { - case XFS_DINODE_FMT_EXTENTS: - fsbno = getfunc_extlist(mp, ino_num, dino_p, bno, whichfork); - break; - case XFS_DINODE_FMT_BTREE: - fsbno = getfunc_btree(mp, ino_num, dino_p, bno, whichfork); - break; - case XFS_DINODE_FMT_LOCAL: - do_error(_("get_bmapi() called for local inode %" PRIu64 "\n"), - ino_num); - fsbno = NULLDFSBNO; - break; - default: - /* - * shouldn't happen - */ - do_error(_("bad inode format for inode %" PRIu64 "\n"), ino_num); - fsbno = NULLDFSBNO; - } - - return(fsbno); -} - -/* * higher level inode processing stuff starts here: * first, one utility routine for each type of inode */ @@ -1120,21 +897,20 @@ xfs_ino_t lino; xfs_bmbt_ptr_t *pp; xfs_bmbt_key_t *pkey; - char *forkname; + char *forkname = get_forkname(whichfork); int i; int level; int numrecs; bmap_cursor_t cursor; + __uint64_t magic; dib = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); lino = XFS_AGINO_TO_INO(mp, agno, ino); *tot = 0; *nex = 0; - if (whichfork == XFS_DATA_FORK) - forkname = _("data"); - else - forkname = _("attr"); + magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_BMAP_CRC_MAGIC + : XFS_BMAP_MAGIC; level = be16_to_cpu(dib->bb_level); numrecs = be16_to_cpu(dib->bb_numrecs); @@ -1189,9 +965,9 @@ return(1); } - if (scan_lbtree(be64_to_cpu(pp[i]), level, scanfunc_bmap, type, + if (scan_lbtree(be64_to_cpu(pp[i]), level, scan_bmapbt, type, whichfork, lino, tot, nex, blkmapp, &cursor, - 1, check_dups)) + 1, check_dups, magic, &xfs_bmbt_buf_ops)) return(1); /* * fix key (offset) mismatches between the keys in root @@ -1293,7 +1069,7 @@ xfs_bmbt_rec_t *rp; xfs_dfiloff_t first_key; xfs_dfiloff_t last_key; - int numrecs; + int32_t numrecs; int ret; lino = XFS_AGINO_TO_INO(mp, agno, ino); @@ -1302,6 +1078,15 @@ numrecs = XFS_DFORK_NEXTENTS(dip, whichfork); /* + * We've already decided on the maximum number of extents on the inode, + * and numrecs may be corrupt. Hence make sure we only allow numrecs to + * be in the range of valid on-disk numbers, which is: + * 0 < numrecs < 2^31 - 1 + */ + if (numrecs < 0) + numrecs = *nex; + + /* * XXX - if we were going to fix up the btree record, * we'd do it right here. For now, if there's a problem, * we'll bail out and presumably clear the inode. @@ -1447,6 +1232,96 @@ return(0); } +static int +process_symlink_remote( + struct xfs_mount *mp, + xfs_ino_t lino, + struct xfs_dinode *dino, + struct blkmap *blkmap, + char *dst) +{ + xfs_dfsbno_t fsbno; + struct xfs_buf *bp; + char *src; + int pathlen; + int offset; + int i; + + offset = 0; + pathlen = be64_to_cpu(dino->di_size); + i = 0; + + while (pathlen > 0) { + int blk_cnt = 1; + int byte_cnt; + int badcrc = 0; + + fsbno = blkmap_get(blkmap, i); + if (fsbno == NULLDFSBNO) { + do_warn( +_("cannot read inode %" PRIu64 ", file block %d, NULL disk block\n"), + lino, i); + return 1; + } + + /* + * There's a symlink header for each contiguous extent. If + * there are contiguous blocks, read them in one go. + */ + while (blk_cnt <= max_symlink_blocks) { + if (blkmap_get(blkmap, i + 1) != fsbno + 1) + break; + blk_cnt++; + i++; + } + + byte_cnt = XFS_FSB_TO_B(mp, blk_cnt); + + bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), + BTOBB(byte_cnt), 0, &xfs_symlink_buf_ops); + if (!bp) { + do_warn( +_("cannot read inode %" PRIu64 ", file block %d, disk block %" PRIu64 "\n"), + lino, i, fsbno); + return 1; + } + if (bp->b_error == EFSBADCRC) { + do_warn( +_("Bad symlink buffer CRC, block %" PRIu64 ", inode %" PRIu64 ".\n" + "Correcting CRC, but symlink may be bad.\n"), fsbno, lino); + badcrc = 1; + } + + byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt); + byte_cnt = MIN(pathlen, byte_cnt); + + src = bp->b_addr; + if (xfs_sb_version_hascrc(&mp->m_sb)) { + if (!libxfs_symlink_hdr_ok(mp, lino, offset, + byte_cnt, bp)) { + do_warn( +_("bad symlink header ino %" PRIu64 ", file block %d, disk block %" PRIu64 "\n"), + lino, i, fsbno); + libxfs_putbuf(bp); + return 1; + } + src += sizeof(struct xfs_dsymlink_hdr); + } + + memmove(dst + offset, src, byte_cnt); + + pathlen -= byte_cnt; + offset += byte_cnt; + i++; + + if (badcrc && !no_modify) + libxfs_writebuf(bp, 0); + else + libxfs_putbuf(bp); + } + return 0; +} + /* * like usual, returns 0 if everything's ok and 1 if something's * bogus @@ -1458,10 +1333,7 @@ xfs_dinode_t *dino, blkmap_t *blkmap) { - xfs_dfsbno_t fsbno; - xfs_buf_t *bp = NULL; - char *symlink, *cptr, *buf_data; - int i, size, amountdone; + char *symlink, *cptr; char data[MAXPATHLEN]; /* @@ -1489,36 +1361,13 @@ memmove(symlink, XFS_DFORK_DPTR(dino), be64_to_cpu(dino->di_size)); } else { - /* - * stored in a meta-data file, have to bmap one block - * at a time and copy the symlink into the data area - */ - i = size = amountdone = 0; - cptr = symlink; + int error; - while (amountdone < be64_to_cpu(dino->di_size)) { - fsbno = blkmap_get(blkmap, i); - if (fsbno != NULLDFSBNO) - bp = libxfs_readbuf(mp->m_dev, - XFS_FSB_TO_DADDR(mp, fsbno), - XFS_FSB_TO_BB(mp, 1), 0); - if (!bp || fsbno == NULLDFSBNO) { - do_warn( -_("cannot read inode %" PRIu64 ", file block %d, disk block %" PRIu64 "\n"), - lino, i, fsbno); - return(1); - } - - buf_data = (char *)XFS_BUF_PTR(bp); - size = MIN(be64_to_cpu(dino->di_size) - amountdone, - XFS_FSB_TO_BB(mp, 1) * BBSIZE); - memmove(cptr, buf_data, size); - cptr += size; - amountdone += size; - i++; - libxfs_putbuf(bp); - } + error = process_symlink_remote(mp, lino, dino, blkmap, symlink); + if (error) + return error; } + data[be64_to_cpu(dino->di_size)] = '\0'; /* @@ -1756,6 +1605,15 @@ } return 0; } + if (lino == mp->m_sb.sb_pquotino) { + if (*type != XR_INO_DATA) { + do_warn(_("project quota inode %" PRIu64 " has bad type 0x%x\n"), + lino, dinode_fmt(dinoc)); + mp->m_sb.sb_pquotino = NULLFSINO; + return 1; + } + return 0; + } if (lino == mp->m_sb.sb_rsumino) { if (*type != XR_INO_RTSUM) { do_warn( @@ -1919,11 +1777,12 @@ case XFS_DINODE_FMT_LOCAL: /* fall through ... */ case XFS_DINODE_FMT_EXTENTS: /* fall through ... */ case XFS_DINODE_FMT_BTREE: - if (dino->di_forkoff >= (XFS_LITINO(mp) >> 3)) { + if (dino->di_forkoff >= + (XFS_LITINO(mp, dino->di_version) >> 3)) { do_warn( _("bad attr fork offset %d in inode %" PRIu64 ", max=%d\n"), dino->di_forkoff, lino, - XFS_LITINO(mp) >> 3); + XFS_LITINO(mp, dino->di_version) >> 3); return 1; } break; @@ -2038,11 +1897,23 @@ { xfs_ino_t lino = XFS_AGINO_TO_INO(mp, agno, ino); int err = 0; + int nex; + + /* + * extent count on disk is only valid for positive values. The kernel + * uses negative values in memory. hence if we see negative numbers + * here, trash it! + */ + nex = be32_to_cpu(dino->di_nextents); + if (nex < 0) + *nextents = 1; + else + *nextents = nex; - *nextents = be32_to_cpu(dino->di_nextents); if (*nextents > be64_to_cpu(dino->di_nblocks)) *nextents = 1; + if (dino->di_format != XFS_DINODE_FMT_LOCAL && type != XR_INO_RTDATA) *dblkmap = blkmap_alloc(*nextents, XFS_DATA_FORK); *nextents = 0; @@ -2460,7 +2331,8 @@ } if (!XFS_DINODE_GOOD_VERSION(dino->di_version) || - (!fs_inode_nlink && dino->di_version > 1)) { + (!fs_inode_nlink && dino->di_version > 1) || + (xfs_sb_version_hascrc(&mp->m_sb) && dino->di_version < 3) ) { retval = 1; if (!uncertain) do_warn(_("bad version number 0x%x on inode %" PRIu64 "%c"), @@ -2469,7 +2341,9 @@ if (!verify_mode) { if (!no_modify) { do_warn(_(" resetting version number\n")); - dino->di_version = (fs_inode_nlink) ? 2 : 1; + dino->di_version = + xfs_sb_version_hascrc(&mp->m_sb) ? 3 : + (fs_inode_nlink) ? 2 : 1; *dirty = 1; } else do_warn(_(" would reset version number\n")); @@ -2477,6 +2351,31 @@ } /* + * We don't bother checking the CRC here - we cannot guarantee that when + * we are called here that the inode has not already been modified in + * memory and hence invalidated the CRC. + */ + if (xfs_sb_version_hascrc(&mp->m_sb)) { + if (be64_to_cpu(dino->di_ino) != lino) { + if (!uncertain) + do_warn( +_("inode identifier %llu mismatch on inode %" PRIu64 "\n"), + be64_to_cpu(dino->di_ino), lino); + if (verify_mode) + return 1; + goto clear_bad_out; + } + if (platform_uuid_compare(&dino->di_uuid, &mp->m_sb.sb_uuid)) { + if (!uncertain) + do_warn( + _("UUID mismatch on inode %" PRIu64 "\n"), lino); + if (verify_mode) + return 1; + goto clear_bad_out; + } + } + + /* * blow out of here if the inode size is < 0 */ if ((xfs_fsize_t)be64_to_cpu(dino->di_size) < 0) { @@ -2750,10 +2649,7 @@ */ switch (type) { case XR_INO_DIR: - if (xfs_sb_version_hasdirv2(&mp->m_sb) ? - process_dir2(mp, lino, dino, ino_discovery, - dirty, "", parent, dblkmap) : - process_dir(mp, lino, dino, ino_discovery, + if (process_dir2(mp, lino, dino, ino_discovery, dirty, "", parent, dblkmap)) { do_warn( _("problem with directory contents in inode %" PRIu64 "\n"), diff -Nru xfsprogs-3.1.9ubuntu2/repair/dinode.h xfsprogs-3.2.1ubuntu1/repair/dinode.h --- xfsprogs-3.1.9ubuntu2/repair/dinode.h 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/dinode.h 2014-05-02 00:09:16.000000000 +0000 @@ -18,9 +18,8 @@ #ifndef _XR_DINODE_H #define _XR_DINODE_H -#include "prefetch.h" - struct blkmap; +struct prefetch_args; int verify_agbno(xfs_mount_t *mp, @@ -103,12 +102,12 @@ process_uncertain_aginodes(xfs_mount_t *mp, xfs_agnumber_t agno); void -process_aginodes(xfs_mount_t *mp, - prefetch_args_t *pf_args, - xfs_agnumber_t agno, - int check_dirs, - int check_dups, - int extra_attr_check); +process_aginodes(xfs_mount_t *mp, + struct prefetch_args *pf_args, + xfs_agnumber_t agno, + int check_dirs, + int check_dups, + int extra_attr_check); void check_uncertain_aginodes(xfs_mount_t *mp, @@ -120,11 +119,8 @@ xfs_agino_t agino, xfs_dinode_t **dipp); -xfs_dfsbno_t -get_bmapi(xfs_mount_t *mp, - xfs_dinode_t *dip, - xfs_ino_t ino_num, - xfs_dfiloff_t bno, - int whichfork ); + +void dinode_bmbt_translation_init(void); +char * get_forkname(int whichfork); #endif /* _XR_DINODE_H */ diff -Nru xfsprogs-3.1.9ubuntu2/repair/dir2.c xfsprogs-3.2.1ubuntu1/repair/dir2.c --- xfsprogs-3.1.9ubuntu2/repair/dir2.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/dir2.c 2014-07-21 09:13:53.000000000 +0000 @@ -22,20 +22,12 @@ #include "incore.h" #include "err_protos.h" #include "dinode.h" -#include "dir.h" #include "dir2.h" #include "bmap.h" #include "prefetch.h" #include "progress.h" /* - * Tag bad directory entries with this. - * We can't tag them with -1 since that will look like a - * data_unused_t instead of a data_entry_t. - */ -#define BADFSINO ((xfs_ino_t)0xfeffffffffffffffULL) - -/* * Known bad inode list. These are seen when the leaf and node * block linkages are incorrect. */ @@ -76,185 +68,61 @@ } /* - * Multibuffer handling. - * V2 directory blocks can be noncontiguous, needing multiple buffers. + * takes a name and length (name need not be null-terminated) + * and returns 1 if the name contains a '/' or a \0, returns 0 + * otherwise */ -static xfs_dabuf_t * -da_read_buf( - xfs_mount_t *mp, - int nex, - bmap_ext_t *bmp) +int +namecheck(char *name, int length) { - xfs_buf_t *bp; - xfs_buf_t *bparray[4]; - xfs_buf_t **bplist; - xfs_dabuf_t *dabuf; - int i; - int off; - - if (nex > (sizeof(bparray)/sizeof(xfs_buf_t *))) { - bplist = calloc(nex, sizeof(*bplist)); - if (bplist == NULL) { - do_error(_("couldn't malloc dir2 buffer list\n")); - exit(1); - } - } - else { - /* common case avoids calloc/free */ - bplist = bparray; - } - for (i = 0; i < nex; i++) { - pftrace("about to read off %llu (len = %d)", - (long long)XFS_FSB_TO_DADDR(mp, bmp[i].startblock), - XFS_FSB_TO_BB(mp, bmp[i].blockcount)); - - bplist[i] = libxfs_readbuf(mp->m_dev, - XFS_FSB_TO_DADDR(mp, bmp[i].startblock), - XFS_FSB_TO_BB(mp, bmp[i].blockcount), 0); - if (!bplist[i]) { - nex = i; - goto failed; - } - - pftrace("readbuf %p (%llu, %d)", bplist[i], - (long long)XFS_BUF_ADDR(bplist[i]), - XFS_BUF_COUNT(bplist[i])); - } - dabuf = malloc(XFS_DA_BUF_SIZE(nex)); - if (dabuf == NULL) { - do_error(_("couldn't malloc dir2 buffer header\n")); - exit(1); - } - dabuf->dirty = 0; - dabuf->nbuf = nex; - if (nex == 1) { - bp = bplist[0]; - dabuf->bbcount = (short)BTOBB(XFS_BUF_COUNT(bp)); - dabuf->data = XFS_BUF_PTR(bp); - dabuf->bps[0] = bp; - } else { - for (i = 0, dabuf->bbcount = 0; i < nex; i++) { - dabuf->bps[i] = bp = bplist[i]; - dabuf->bbcount += BTOBB(XFS_BUF_COUNT(bp)); - } - dabuf->data = malloc(BBTOB(dabuf->bbcount)); - if (dabuf->data == NULL) { - do_error(_("couldn't malloc dir2 buffer data\n")); - exit(1); - } - for (i = off = 0; i < nex; i++, off += XFS_BUF_COUNT(bp)) { - bp = bplist[i]; - memmove((char *)dabuf->data + off, XFS_BUF_PTR(bp), - XFS_BUF_COUNT(bp)); - } - } - if (bplist != bparray) - free(bplist); - return dabuf; -failed: - for (i = 0; i < nex; i++) - libxfs_putbuf(bplist[i]); - if (bplist != bparray) - free(bplist); - return NULL; -} + char *c; + int i; -static void -da_buf_clean( - xfs_dabuf_t *dabuf) -{ - xfs_buf_t *bp; - int i; - int off; + ASSERT(length < MAXNAMELEN); - if (dabuf->dirty) { - dabuf->dirty = 0; - for (i=off=0; i < dabuf->nbuf; i++, off += XFS_BUF_COUNT(bp)) { - bp = dabuf->bps[i]; - memmove(XFS_BUF_PTR(bp), (char *)dabuf->data + off, - XFS_BUF_COUNT(bp)); - } + for (c = name, i = 0; i < length; i++, c++) { + if (*c == '/' || *c == '\0') + return(1); } -} -static void -da_buf_done( - xfs_dabuf_t *dabuf) -{ - da_buf_clean(dabuf); - if (dabuf->nbuf > 1) - free(dabuf->data); - free(dabuf); + return(0); } -static int -da_bwrite( +/* + * Multibuffer handling. + * V2 directory blocks can be noncontiguous, needing multiple buffers. + */ +static struct xfs_buf * +da_read_buf( xfs_mount_t *mp, - xfs_dabuf_t *dabuf) + int nex, + bmap_ext_t *bmp, + const struct xfs_buf_ops *ops) { - xfs_buf_t *bp; - xfs_buf_t **bplist; - int e; - int error; +#define MAP_ARRAY_SZ 4 + struct xfs_buf_map map_array[MAP_ARRAY_SZ]; + struct xfs_buf_map *map; + struct xfs_buf *bp; int i; - int nbuf; - int off; - if ((nbuf = dabuf->nbuf) == 1) { - bplist = &bp; - bp = dabuf->bps[0]; - } else { - bplist = malloc(nbuf * sizeof(*bplist)); - if (bplist == NULL) { + if (nex > MAP_ARRAY_SZ) { + map = calloc(nex, sizeof(*map)); + if (map == NULL) { do_error(_("couldn't malloc dir2 buffer list\n")); exit(1); } - memmove(bplist, dabuf->bps, nbuf * sizeof(*bplist)); - for (i = off = 0; i < nbuf; i++, off += XFS_BUF_COUNT(bp)) { - bp = bplist[i]; - memmove(XFS_BUF_PTR(bp), (char *)dabuf->data + off, - XFS_BUF_COUNT(bp)); - } - } - da_buf_done(dabuf); - for (i = error = 0; i < nbuf; i++) { - e = libxfs_writebuf(bplist[i], 0); - if (e) - error = e; - } - if (bplist != &bp) - free(bplist); - return error; -} - -static void -da_brelse( - xfs_dabuf_t *dabuf) -{ - xfs_buf_t *bp; - xfs_buf_t **bplist; - int i; - int nbuf; - - if ((nbuf = dabuf->nbuf) == 1) { - bplist = &bp; - bp = dabuf->bps[0]; } else { - bplist = malloc(nbuf * sizeof(*bplist)); - if (bplist == NULL) { - do_error(_("couldn't malloc dir2 buffer list\n")); - exit(1); - } - memmove(bplist, dabuf->bps, nbuf * sizeof(*bplist)); + /* common case avoids calloc/free */ + map = map_array; } - da_buf_done(dabuf); - for (i = 0; i < nbuf; i++) { - pftrace("putbuf %p (%llu)", bplist[i], - (long long)XFS_BUF_ADDR(bplist[i])); - libxfs_putbuf(bplist[i]); + for (i = 0; i < nex; i++) { + map[i].bm_bn = XFS_FSB_TO_DADDR(mp, bmp[i].startblock); + map[i].bm_len = XFS_FSB_TO_BB(mp, bmp[i].blockcount); } - if (bplist != &bp) - free(bplist); + bp = libxfs_readbuf_map(mp->m_dev, map, nex, 0, ops); + if (map != map_array) + free(map); + return bp; } /* @@ -270,12 +138,13 @@ { bmap_ext_t *bmp; xfs_dablk_t bno; - xfs_dabuf_t *bp; + struct xfs_buf *bp; int i; int nex; - xfs_da_blkinfo_t *info; xfs_da_intnode_t *node; bmap_ext_t lbmp; + struct xfs_da_node_entry *btree; + struct xfs_da3_icnode_hdr nodehdr; /* * traverse down left-side of tree until we hit the @@ -284,7 +153,7 @@ */ bno = mp->m_dirleafblk; i = -1; - info = NULL; + node = NULL; da_cursor->active = 0; do { @@ -297,7 +166,7 @@ if (nex == 0) goto error_out; - bp = da_read_buf(mp, nex, bmp); + bp = da_read_buf(mp, nex, bmp, &xfs_da3_node_buf_ops); if (bmp != &lbmp) free(bmp); if (bp == NULL) { @@ -307,31 +176,35 @@ goto error_out; } - info = bp->data; + node = bp->b_addr; + xfs_da3_node_hdr_from_disk(&nodehdr, node); - if (be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC) { + if (nodehdr.magic == XFS_DIR2_LEAFN_MAGIC || + nodehdr.magic == XFS_DIR3_LEAFN_MAGIC) { if ( i != -1 ) { do_warn( _("found non-root LEAFN node in inode %" PRIu64 " bno = %u\n"), da_cursor->ino, bno); } *rbno = 0; - da_brelse(bp); + libxfs_putbuf(bp); return(1); - } else if (be16_to_cpu(info->magic) != XFS_DA_NODE_MAGIC) { - da_brelse(bp); + } else if (!(nodehdr.magic == XFS_DA_NODE_MAGIC || + nodehdr.magic == XFS_DA3_NODE_MAGIC)) { + libxfs_putbuf(bp); do_warn( _("bad dir magic number 0x%x in inode %" PRIu64 " bno = %u\n"), - be16_to_cpu(info->magic), + nodehdr.magic, da_cursor->ino, bno); goto error_out; } - node = (xfs_da_intnode_t*)info; - if (be16_to_cpu(node->hdr.count) > mp->m_dir_node_ents) { - da_brelse(bp); - do_warn( -_("bad record count in inode %" PRIu64 ", count = %d, max = %d\n"), da_cursor->ino, - be16_to_cpu(node->hdr.count), + btree = xfs_da3_node_tree_p(node); + if (nodehdr.count > mp->m_dir_node_ents) { + libxfs_putbuf(bp); + do_warn( +_("bad record count in inode %" PRIu64 ", count = %d, max = %d\n"), + da_cursor->ino, + nodehdr.count, mp->m_dir_node_ents); goto error_out; } @@ -339,29 +212,28 @@ * maintain level counter */ if (i == -1) { - i = da_cursor->active = be16_to_cpu(node->hdr.level); - if (i >= XFS_DA_NODE_MAXDEPTH) { + i = da_cursor->active = nodehdr.level; + if (i < 1 || i >= XFS_DA_NODE_MAXDEPTH) { do_warn( _("bad header depth for directory inode %" PRIu64 "\n"), da_cursor->ino); - da_brelse(bp); + libxfs_putbuf(bp); i = -1; goto error_out; } } else { - if (be16_to_cpu(node->hdr.level) == i - 1) { + if (nodehdr.level == i - 1) { i--; } else { do_warn( _("bad directory btree for directory inode %" PRIu64 "\n"), da_cursor->ino); - da_brelse(bp); + libxfs_putbuf(bp); goto error_out; } } - da_cursor->level[i].hashval = - be32_to_cpu(node->btree[0].hashval); + da_cursor->level[i].hashval = be32_to_cpu(btree[0].hashval); da_cursor->level[i].bp = bp; da_cursor->level[i].bno = bno; da_cursor->level[i].index = 0; @@ -369,8 +241,8 @@ /* * set up new bno for next level down */ - bno = be32_to_cpu(node->btree[0].before); - } while (info != NULL && i > 1); + bno = be32_to_cpu(btree[0].before); + } while (node != NULL && i > 1); /* * now return block number and get out @@ -380,7 +252,7 @@ error_out: while (i > 1 && i <= da_cursor->active) { - da_brelse(da_cursor->level[i].bp); + libxfs_putbuf(da_cursor->level[i].bp); i++; } @@ -409,7 +281,7 @@ } ASSERT(error != 0); - da_brelse(cursor->level[level].bp); + libxfs_putbuf(cursor->level[level].bp); cursor->level[level].bp = NULL; } @@ -452,39 +324,43 @@ int bad = 0; int entry; int this_level = p_level + 1; + struct xfs_da_node_entry *btree; + struct xfs_da3_icnode_hdr nodehdr; /* * the index should point to the next "unprocessed" entry * in the block which should be the final (rightmost) entry */ entry = cursor->level[this_level].index; - node = (xfs_da_intnode_t *)(cursor->level[this_level].bp->data); + node = (xfs_da_intnode_t *)(cursor->level[this_level].bp->b_addr); + btree = xfs_da3_node_tree_p(node); + xfs_da3_node_hdr_from_disk(&nodehdr, node); /* * check internal block consistency on this level -- ensure * that all entries are used, encountered and expected hashvals * match, etc. */ - if (entry != be16_to_cpu(node->hdr.count) - 1) { + if (entry != nodehdr.count - 1) { do_warn( _("directory block used/count inconsistency - %d / %hu\n"), - entry, be16_to_cpu(node->hdr.count)); + entry, nodehdr.count); bad++; } /* * hash values monotonically increasing ??? */ if (cursor->level[this_level].hashval >= - be32_to_cpu(node->btree[entry].hashval)) { + be32_to_cpu(btree[entry].hashval)) { do_warn(_("directory/attribute block hashvalue inconsistency, " "expected > %u / saw %u\n"), cursor->level[this_level].hashval, - be32_to_cpu(node->btree[entry].hashval)); + be32_to_cpu(btree[entry].hashval)); bad++; } - if (be32_to_cpu(node->hdr.info.forw) != 0) { + if (nodehdr.forw != 0) { do_warn(_("bad directory/attribute forward block pointer, " "expected 0, saw %u\n"), - be32_to_cpu(node->hdr.info.forw)); + nodehdr.forw); bad++; } if (bad) { @@ -501,18 +377,17 @@ /* * ok, now check descendant block number against this level */ - if (cursor->level[p_level].bno != - be32_to_cpu(node->btree[entry].before)) + if (cursor->level[p_level].bno != be32_to_cpu(btree[entry].before)) return(1); if (cursor->level[p_level].hashval != - be32_to_cpu(node->btree[entry].hashval)) { + be32_to_cpu(btree[entry].hashval)) { if (!no_modify) { do_warn( _("correcting bad hashval in non-leaf dir block\n" "\tin (level %d) in inode %" PRIu64 ".\n"), this_level, cursor->ino); - node->btree[entry].hashval = cpu_to_be32( + btree[entry].hashval = cpu_to_be32( cursor->level[p_level].hashval); cursor->level[this_level].dirty++; } else { @@ -530,9 +405,9 @@ (cursor->level[this_level].dirty && !no_modify)); if (cursor->level[this_level].dirty && !no_modify) - da_bwrite(mp, cursor->level[this_level].bp); + libxfs_writebuf(cursor->level[this_level].bp, 0); else - da_brelse(cursor->level[this_level].bp); + libxfs_putbuf(cursor->level[this_level].bp); cursor->level[this_level].bp = NULL; @@ -545,8 +420,7 @@ * set hashvalue to correctl reflect the now-validated * last entry in this block and continue upwards validation */ - cursor->level[this_level].hashval = - be32_to_cpu(node->btree[entry].hashval); + cursor->level[this_level].hashval = be32_to_cpu(btree[entry].hashval); return(verify_final_dir2_path(mp, cursor, this_level)); } @@ -598,34 +472,38 @@ xfs_da_intnode_t *node; xfs_da_intnode_t *newnode; xfs_dablk_t dabno; - xfs_dabuf_t *bp; + struct xfs_buf *bp; int bad; int entry; int this_level = p_level + 1; bmap_ext_t *bmp; int nex; bmap_ext_t lbmp; + struct xfs_da_node_entry *btree; + struct xfs_da3_icnode_hdr nodehdr; /* * index is currently set to point to the entry that * should be processed now in this level. */ entry = cursor->level[this_level].index; - node = cursor->level[this_level].bp->data; + node = cursor->level[this_level].bp->b_addr; + btree = xfs_da3_node_tree_p(node); + xfs_da3_node_hdr_from_disk(&nodehdr, node); /* * if this block is out of entries, validate this * block and move on to the next block. * and update cursor value for said level */ - if (entry >= be16_to_cpu(node->hdr.count)) { + if (entry >= nodehdr.count) { /* * update the hash value for this level before * validating it. bno value should be ok since * it was set when the block was first read in. */ cursor->level[this_level].hashval = - be32_to_cpu(node->btree[entry - 1].hashval); + be32_to_cpu(btree[entry - 1].hashval); /* * keep track of greatest block # -- that gets @@ -643,7 +521,7 @@ /* * ok, now get the next buffer and check sibling pointers */ - dabno = be32_to_cpu(node->hdr.info.forw); + dabno = nodehdr.forw; ASSERT(dabno != 0); nex = blkmap_getn(cursor->blkmap, dabno, mp->m_dirblkfsbs, &bmp, &lbmp); @@ -654,7 +532,7 @@ return(1); } - bp = da_read_buf(mp, nex, bmp); + bp = da_read_buf(mp, nex, bmp, &xfs_da3_node_buf_ops); if (bmp != &lbmp) free(bmp); @@ -665,42 +543,44 @@ return(1); } - newnode = bp->data; + newnode = bp->b_addr; + btree = xfs_da3_node_tree_p(newnode); + xfs_da3_node_hdr_from_disk(&nodehdr, newnode); /* * verify magic number and back pointer, sanity-check * entry count, verify level */ bad = 0; - if (XFS_DA_NODE_MAGIC != be16_to_cpu(newnode->hdr.info.magic)) { + if (!(nodehdr.magic == XFS_DA_NODE_MAGIC || + nodehdr.magic == XFS_DA3_NODE_MAGIC)) { do_warn( _("bad magic number %x in block %u for directory inode %" PRIu64 "\n"), - be16_to_cpu(newnode->hdr.info.magic), + nodehdr.magic, dabno, cursor->ino); bad++; } - if (be32_to_cpu(newnode->hdr.info.back) != - cursor->level[this_level].bno) { + if (nodehdr.back != cursor->level[this_level].bno) { do_warn( _("bad back pointer in block %u for directory inode %" PRIu64 "\n"), dabno, cursor->ino); bad++; } - if (be16_to_cpu(newnode->hdr.count) > mp->m_dir_node_ents) { + if (nodehdr.count > mp->m_dir_node_ents) { do_warn( _("entry count %d too large in block %u for directory inode %" PRIu64 "\n"), - be16_to_cpu(newnode->hdr.count), + nodehdr.count, dabno, cursor->ino); bad++; } - if (be16_to_cpu(newnode->hdr.level) != this_level) { + if (nodehdr.level != this_level) { do_warn( _("bad level %d in block %u for directory inode %" PRIu64 "\n"), - be16_to_cpu(newnode->hdr.level), + nodehdr.level, dabno, cursor->ino); bad++; } if (bad) { - da_brelse(bp); + libxfs_putbuf(bp); return(1); } /* @@ -709,38 +589,42 @@ */ ASSERT(cursor->level[this_level].dirty == 0 || (cursor->level[this_level].dirty && !no_modify)); - + /* + * If block looks ok but CRC didn't match, make sure to + * recompute it. + */ + if (!no_modify && + cursor->level[this_level].bp->b_error == EFSBADCRC) + cursor->level[this_level].dirty = 1; if (cursor->level[this_level].dirty && !no_modify) - da_bwrite(mp, cursor->level[this_level].bp); + libxfs_writebuf(cursor->level[this_level].bp, 0); else - da_brelse(cursor->level[this_level].bp); + libxfs_putbuf(cursor->level[this_level].bp); cursor->level[this_level].bp = bp; cursor->level[this_level].dirty = 0; cursor->level[this_level].bno = dabno; cursor->level[this_level].hashval = - be32_to_cpu(newnode->btree[0].hashval); - node = newnode; + be32_to_cpu(btree[0].hashval); entry = cursor->level[this_level].index = 0; } /* * ditto for block numbers */ - if (cursor->level[p_level].bno != - be32_to_cpu(node->btree[entry].before)) + if (cursor->level[p_level].bno != be32_to_cpu(btree[entry].before)) return(1); /* * ok, now validate last hashvalue in the descendant * block against the hashval in the current entry */ if (cursor->level[p_level].hashval != - be32_to_cpu(node->btree[entry].hashval)) { + be32_to_cpu(btree[entry].hashval)) { if (!no_modify) { do_warn( _("correcting bad hashval in interior dir block\n" "\tin (level %d) in inode %" PRIu64 ".\n"), this_level, cursor->ino); - node->btree[entry].hashval = cpu_to_be32( + btree[entry].hashval = cpu_to_be32( cursor->level[p_level].hashval); cursor->level[this_level].dirty++; } else { @@ -765,13 +649,14 @@ */ void process_sf_dir2_fixi8( - xfs_dir2_sf_t *sfp, + struct xfs_mount *mp, + struct xfs_dir2_sf_hdr *sfp, xfs_dir2_sf_entry_t **next_sfep) { xfs_ino_t ino; - xfs_dir2_sf_t *newsfp; + struct xfs_dir2_sf_hdr *newsfp; xfs_dir2_sf_entry_t *newsfep; - xfs_dir2_sf_t *oldsfp; + struct xfs_dir2_sf_hdr *oldsfp; xfs_dir2_sf_entry_t *oldsfep; int oldsize; @@ -783,10 +668,10 @@ exit(1); } memmove(oldsfp, newsfp, oldsize); - newsfp->hdr.count = oldsfp->hdr.count; - newsfp->hdr.i8count = 0; - ino = xfs_dir2_sf_get_inumber(oldsfp, &oldsfp->hdr.parent); - xfs_dir2_sf_put_inumber(newsfp, &ino, &newsfp->hdr.parent); + newsfp->count = oldsfp->count; + newsfp->i8count = 0; + ino = xfs_dir2_sf_get_parent_ino(sfp); + xfs_dir2_sf_put_parent_ino(newsfp, ino); oldsfep = xfs_dir2_sf_firstentry(oldsfp); newsfep = xfs_dir2_sf_firstentry(newsfp); while ((int)((char *)oldsfep - (char *)oldsfp) < oldsize) { @@ -794,12 +679,10 @@ xfs_dir2_sf_put_offset(newsfep, xfs_dir2_sf_get_offset(oldsfep)); memmove(newsfep->name, oldsfep->name, newsfep->namelen); - ino = xfs_dir2_sf_get_inumber(oldsfp, - xfs_dir2_sf_inumberp(oldsfep)); - xfs_dir2_sf_put_inumber(newsfp, &ino, - xfs_dir2_sf_inumberp(newsfep)); - oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep); - newsfep = xfs_dir2_sf_nextentry(newsfp, newsfep); + ino = xfs_dir3_sfe_get_ino(mp, oldsfp, oldsfep); + xfs_dir3_sfe_put_ino(mp, newsfp, newsfep, ino); + oldsfep = xfs_dir3_sf_nextentry(mp, oldsfp, oldsfep); + newsfep = xfs_dir3_sf_nextentry(mp, newsfp, newsfep); } *next_sfep = newsfep; free(oldsfp); @@ -810,21 +693,22 @@ */ static void process_sf_dir2_fixoff( + xfs_mount_t *mp, xfs_dinode_t *dip) { int i; int offset; xfs_dir2_sf_entry_t *sfep; - xfs_dir2_sf_t *sfp; + struct xfs_dir2_sf_hdr *sfp; - sfp = (xfs_dir2_sf_t *)XFS_DFORK_DPTR(dip); + sfp = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip); sfep = xfs_dir2_sf_firstentry(sfp); - offset = XFS_DIR2_DATA_FIRST_OFFSET; + offset = xfs_dir3_data_first_offset(mp); - for (i = 0; i < sfp->hdr.count; i++) { + for (i = 0; i < sfp->count; i++) { xfs_dir2_sf_put_offset(sfep, offset); - offset += xfs_dir2_data_entsize(sfep->namelen); - sfep = xfs_dir2_sf_nextentry(sfp, sfep); + offset += xfs_dir3_data_entsize(mp, sfep->namelen); + sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep); } } @@ -862,18 +746,18 @@ xfs_dir2_sf_entry_t *next_sfep; int num_entries; int offset; - xfs_dir2_sf_t *sfp; + struct xfs_dir2_sf_hdr *sfp; xfs_dir2_sf_entry_t *sfep; int tmp_elen; int tmp_len; xfs_dir2_sf_entry_t *tmp_sfep; xfs_ino_t zero = 0; - sfp = (xfs_dir2_sf_t *)XFS_DFORK_DPTR(dip); + sfp = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip); max_size = XFS_DFORK_DSIZE(dip, mp); - num_entries = sfp->hdr.count; + num_entries = sfp->count; ino_dir_size = be64_to_cpu(dip->di_size); - offset = XFS_DIR2_DATA_FIRST_OFFSET; + offset = xfs_dir3_data_first_offset(mp); bad_offset = *repair = 0; ASSERT(ino_dir_size <= max_size); @@ -881,13 +765,12 @@ /* * Initialize i8 based on size of parent inode number. */ - i8 = (xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent) - > XFS_DIR2_MAX_SHORT_INUM); + i8 = (xfs_dir2_sf_get_parent_ino(sfp) > XFS_DIR2_MAX_SHORT_INUM); /* * check for bad entry count */ - if (num_entries * xfs_dir2_sf_entsize_byname(sfp, 1) + + if (num_entries * xfs_dir3_sf_entsize(mp, sfp, 1) + xfs_dir2_sf_hdr_size(0) > max_size || num_entries == 0) num_entries = 0xFF; @@ -895,7 +778,7 @@ * run through entries, stop at first bad entry, don't need * to check for .. since that's encoded in its own field */ - sfep = next_sfep = xfs_dir2_sf_firstentry(sfp); + next_sfep = xfs_dir2_sf_firstentry(sfp); for (i = 0; i < num_entries && ino_dir_size > (char *)next_sfep - (char *)sfp; i++) { @@ -903,7 +786,7 @@ sfep = next_sfep; junkit = 0; bad_sfnamelen = 0; - lino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); + lino = xfs_dir3_sfe_get_ino(mp, sfp, sfep); /* * if entry points to self, junk it since only '.' or '..' * should do that and shortform dirs don't contain either @@ -933,6 +816,9 @@ } else if (lino == mp->m_sb.sb_gquotino) { junkit = 1; junkreason = _("group quota"); + } else if (lino == mp->m_sb.sb_pquotino) { + junkit = 1; + junkreason = _("project quota"); } else if ((irec_p = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, lino), XFS_INO_TO_AGINO(mp, lino))) != NULL) { @@ -1017,7 +903,7 @@ break; } } else if ((__psint_t) sfep - (__psint_t) sfp + - xfs_dir2_sf_entsize_byentry(sfp, sfep) + xfs_dir3_sf_entsize(mp, sfp, sfep->namelen) > ino_dir_size) { bad_sfnamelen = 1; @@ -1088,7 +974,7 @@ bad_offset = 1; } offset = xfs_dir2_sf_get_offset(sfep) + - xfs_dir2_data_entsize(namelen); + xfs_dir3_data_entsize(mp, namelen); /* * junk the entry by copying up the rest of the @@ -1105,8 +991,8 @@ name[namelen] = '\0'; if (!no_modify) { - tmp_elen = - xfs_dir2_sf_entsize_byentry(sfp, sfep); + tmp_elen = xfs_dir3_sf_entsize(mp, sfp, + sfep->namelen); be64_add_cpu(&dip->di_size, -tmp_elen); ino_dir_size -= tmp_elen; @@ -1117,7 +1003,7 @@ memmove(sfep, tmp_sfep, tmp_len); - sfp->hdr.count -= 1; + sfp->count -= 1; num_entries--; memset((void *) ((__psint_t) sfep + tmp_len), 0, tmp_elen); @@ -1158,44 +1044,42 @@ */ next_sfep = (tmp_sfep == NULL) ? (xfs_dir2_sf_entry_t *) ((__psint_t) sfep - + ((!bad_sfnamelen) - ? xfs_dir2_sf_entsize_byentry(sfp, - sfep) - : xfs_dir2_sf_entsize_byname(sfp, - namelen))) + + ((!bad_sfnamelen) + ? xfs_dir3_sf_entsize(mp, sfp, sfep->namelen) + : xfs_dir3_sf_entsize(mp, sfp, namelen))) : tmp_sfep; } /* sync up sizes and entry counts */ - if (sfp->hdr.count != i) { + if (sfp->count != i) { if (no_modify) { do_warn( _("would have corrected entry count in directory %" PRIu64 " from %d to %d\n"), - ino, sfp->hdr.count, i); + ino, sfp->count, i); } else { do_warn( _("corrected entry count in directory %" PRIu64 ", was %d, now %d\n"), - ino, sfp->hdr.count, i); - sfp->hdr.count = i; + ino, sfp->count, i); + sfp->count = i; *dino_dirty = 1; *repair = 1; } } - if (sfp->hdr.i8count != i8) { + if (sfp->i8count != i8) { if (no_modify) { do_warn( _("would have corrected i8 count in directory %" PRIu64 " from %d to %d\n"), - ino, sfp->hdr.i8count, i8); + ino, sfp->i8count, i8); } else { do_warn( _("corrected i8 count in directory %" PRIu64 ", was %d, now %d\n"), - ino, sfp->hdr.i8count, i8); + ino, sfp->i8count, i8); if (i8 == 0) - process_sf_dir2_fixi8(sfp, &next_sfep); + process_sf_dir2_fixi8(mp, sfp, &next_sfep); else - sfp->hdr.i8count = i8; + sfp->i8count = i8; *dino_dirty = 1; *repair = 1; } @@ -1219,7 +1103,7 @@ *repair = 1; } } - if (offset + (sfp->hdr.count + 2) * sizeof(xfs_dir2_leaf_entry_t) + + if (offset + (sfp->count + 2) * sizeof(xfs_dir2_leaf_entry_t) + sizeof(xfs_dir2_block_tail_t) > mp->m_dirblksize) { do_warn(_("directory %" PRIu64 " offsets too high\n"), ino); bad_offset = 1; @@ -1233,7 +1117,7 @@ do_warn( _("corrected entry offsets in directory %" PRIu64 "\n"), ino); - process_sf_dir2_fixoff(dip); + process_sf_dir2_fixoff(mp, dip); *dino_dirty = 1; *repair = 1; } @@ -1242,7 +1126,7 @@ /* * check parent (..) entry */ - *parent = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); + *parent = xfs_dir2_sf_get_parent_ino(sfp); /* * if parent entry is bogus, null it out. we'll fix it later . @@ -1256,7 +1140,7 @@ if (!no_modify) { do_warn(_("clearing inode number\n")); - xfs_dir2_sf_put_inumber(sfp, &zero, &sfp->hdr.parent); + xfs_dir2_sf_put_parent_ino(sfp, zero); *dino_dirty = 1; *repair = 1; } else { @@ -1271,7 +1155,7 @@ _("corrected root directory %" PRIu64 " .. entry, was %" PRIu64 ", now %" PRIu64 "\n"), ino, *parent, ino); *parent = ino; - xfs_dir2_sf_put_inumber(sfp, parent, &sfp->hdr.parent); + xfs_dir2_sf_put_parent_ino(sfp, ino); *dino_dirty = 1; *repair = 1; } else { @@ -1291,7 +1175,7 @@ if (!no_modify) { do_warn(_("clearing inode number\n")); - xfs_dir2_sf_put_inumber(sfp, &zero, &sfp->hdr.parent); + xfs_dir2_sf_put_parent_ino(sfp, zero); *dino_dirty = 1; *repair = 1; } else { @@ -1314,17 +1198,18 @@ int ino_discovery, char *dirname, /* directory pathname */ xfs_ino_t *parent, /* out - NULLFSINO if entry not exist */ - xfs_dabuf_t *bp, + struct xfs_buf *bp, int *dot, /* out - 1 if there is a dot, else 0 */ int *dotdot, /* out - 1 if there's a dotdot, else 0 */ xfs_dablk_t da_bno, - char *endptr) + char *endptr, + int *dirty) { int badbest; xfs_dir2_data_free_t *bf; int clearino; char *clearreason = NULL; - xfs_dir2_data_t *d; + struct xfs_dir2_data_hdr *d; xfs_dir2_data_entry_t *dep; xfs_dir2_data_free_t *dfp; xfs_dir2_data_unused_t *dup; @@ -1338,9 +1223,9 @@ char *ptr; xfs_ino_t ent_ino; - d = bp->data; - bf = d->hdr.bestfree; - ptr = (char *)d->u; + d = bp->b_addr; + bf = xfs_dir3_data_bestfree_p(d); + ptr = (char *)xfs_dir3_data_entry_p(d); badbest = lastfree = freeseen = 0; if (be16_to_cpu(bf[0].length) == 0) { badbest |= be16_to_cpu(bf[0].offset) != 0; @@ -1385,12 +1270,12 @@ continue; } dep = (xfs_dir2_data_entry_t *)ptr; - if (ptr + xfs_dir2_data_entsize(dep->namelen) > endptr) + if (ptr + xfs_dir3_data_entsize(mp, dep->namelen) > endptr) break; - if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) != + if (be16_to_cpu(*xfs_dir3_data_entry_tag_p(mp, dep)) != (char *)dep - (char *)d) break; - ptr += xfs_dir2_data_entsize(dep->namelen); + ptr += xfs_dir3_data_entsize(mp, dep->namelen); lastfree = 0; } /* @@ -1406,7 +1291,7 @@ do_warn(_("\twould junk block\n")); return 1; } - ptr = (char *)d->u; + ptr = (char *)xfs_dir3_data_entry_p(d); /* * Process the entries now. */ @@ -1428,7 +1313,7 @@ * Conditions must either set clearino to zero or set * clearreason why it's being cleared. */ - if (!ino_discovery && ent_ino == BADFSINO) { + if (!ino_discovery && dep->name[0] == '/') { /* * Don't do a damned thing. We already found this * (or did it ourselves) during phase 3. @@ -1449,6 +1334,8 @@ clearreason = _("user quota"); } else if (ent_ino == mp->m_sb.sb_gquotino) { clearreason = _("group quota"); + } else if (ent_ino == mp->m_sb.sb_pquotino) { + clearreason = _("project quota"); } else { irec_p = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, ent_ino), @@ -1513,9 +1400,8 @@ do_warn( _("\tclearing inode number in entry at offset %" PRIdPTR "...\n"), (intptr_t)ptr - (intptr_t)d); - dep->inumber = cpu_to_be64(BADFSINO); - ent_ino = BADFSINO; - bp->dirty = 1; + dep->name[0] = '/'; + *dirty = 1; } else { do_warn( _("\twould clear inode number in entry at offset %" PRIdPTR "...\n"), @@ -1527,7 +1413,7 @@ * discovery is turned on). Otherwise, we'd complain a lot * during phase 4. */ - junkit = ent_ino == BADFSINO; + junkit = dep->name[0] == '/'; nm_illegal = namecheck((char *)dep->name, dep->namelen); if (ino_discovery && nm_illegal) { do_warn( @@ -1536,14 +1422,15 @@ dep->namelen, dep->namelen, dep->name); junkit = 1; } + /* - * Now we can mark entries with BADFSINO's bad. + * Ensure we write back bad entries for later processing */ - if (!no_modify && ent_ino == BADFSINO) { - dep->name[0] = '/'; - bp->dirty = 1; + if (!no_modify && dep->name[0] == '/') { + *dirty = 1; junkit = 0; } + /* * Special .. entry processing. */ @@ -1577,7 +1464,7 @@ if (!no_modify) { do_warn(_("correcting\n")); dep->inumber = cpu_to_be64(ino); - bp->dirty = 1; + *dirty = 1; } else { do_warn(_("would correct\n")); } @@ -1609,7 +1496,7 @@ if (!no_modify) { do_warn(_("correcting\n")); dep->inumber = cpu_to_be64(ino); - bp->dirty = 1; + *dirty = 1; } else { do_warn(_("would correct\n")); } @@ -1636,7 +1523,7 @@ if (junkit) { if (!no_modify) { dep->name[0] = '/'; - bp->dirty = 1; + *dirty = 1; do_warn(_("clearing entry\n")); } else { do_warn(_("would clear entry\n")); @@ -1645,7 +1532,7 @@ /* * Advance to the next entry. */ - ptr += xfs_dir2_data_entsize(dep->namelen); + ptr += xfs_dir3_data_entsize(mp, dep->namelen); } /* * Check the bestfree table. @@ -1657,7 +1544,7 @@ if (!no_modify) { do_warn(_("repairing table\n")); libxfs_dir2_data_freescan(mp, d, &i); - bp->dirty = 1; + *dirty = 1; } else { do_warn(_("would repair table\n")); } @@ -1683,14 +1570,15 @@ int *dotdot, /* out - 1 if there's a dotdot, else 0 */ int *repair) /* out - 1 if something was fixed */ { - xfs_dir2_block_t *block; + struct xfs_dir2_data_hdr *block; xfs_dir2_leaf_entry_t *blp; bmap_ext_t *bmp; - xfs_dabuf_t *bp; + struct xfs_buf *bp; xfs_dir2_block_tail_t *btp; int nex; int rval; bmap_ext_t lbmp; + int dirty = 0; *repair = *dot = *dotdot = 0; *parent = NULLFSINO; @@ -1701,7 +1589,7 @@ mp->m_dirdatablk, ino); return 1; } - bp = da_read_buf(mp, nex, bmp); + bp = da_read_buf(mp, nex, bmp, &xfs_dir3_block_buf_ops); if (bmp != &lbmp) free(bmp); if (bp == NULL) { @@ -1713,11 +1601,12 @@ /* * Verify the block */ - block = bp->data; - if (be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC) + block = bp->b_addr; + if (!(be32_to_cpu(block->magic) == XFS_DIR2_BLOCK_MAGIC || + be32_to_cpu(block->magic) == XFS_DIR3_BLOCK_MAGIC)) do_warn( _("bad directory block magic # %#x in block %u for directory inode %" PRIu64 "\n"), - be32_to_cpu(block->hdr.magic), mp->m_dirdatablk, ino); + be32_to_cpu(block->magic), mp->m_dirdatablk, ino); /* * process the data area * this also checks & fixes the bestfree @@ -1730,12 +1619,15 @@ if ((char *)blp > (char *)btp) blp = (xfs_dir2_leaf_entry_t *)btp; rval = process_dir2_data(mp, ino, dip, ino_discovery, dirname, parent, - bp, dot, dotdot, mp->m_dirdatablk, (char *)blp); - if (bp->dirty && !no_modify) { + bp, dot, dotdot, mp->m_dirdatablk, (char *)blp, &dirty); + /* If block looks ok but CRC didn't match, make sure to recompute it. */ + if (!rval && bp->b_error == EFSBADCRC) + dirty = 1; + if (dirty && !no_modify) { *repair = 1; - da_bwrite(mp, bp); + libxfs_writebuf(bp, 0); } else - da_brelse(bp); + libxfs_putbuf(bp); return rval; } @@ -1756,26 +1648,30 @@ { int i; int stale; + struct xfs_dir2_leaf_entry *ents; + struct xfs_dir3_icleaf_hdr leafhdr; - for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) { - if ((char *)&leaf->ents[i] >= (char *)leaf + mp->m_dirblksize) { + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + ents = xfs_dir3_leaf_ents_p(leaf); + + for (i = stale = 0; i < leafhdr.count; i++) { + if ((char *)&ents[i] >= (char *)leaf + mp->m_dirblksize) { do_warn( _("bad entry count in block %u of directory inode %" PRIu64 "\n"), da_bno, ino); return 1; } - if (be32_to_cpu(leaf->ents[i].address) == XFS_DIR2_NULL_DATAPTR) + if (be32_to_cpu(ents[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; - else if (be32_to_cpu(leaf->ents[i].hashval) < last_hashval) { + else if (be32_to_cpu(ents[i].hashval) < last_hashval) { do_warn( _("bad hash ordering in block %u of directory inode %" PRIu64 "\n"), da_bno, ino); return 1; } - *next_hashval = last_hashval = - be32_to_cpu(leaf->ents[i].hashval); + *next_hashval = last_hashval = be32_to_cpu(ents[i].hashval); } - if (stale != be16_to_cpu(leaf->hdr.stale)) { + if (stale != leafhdr.stale) { do_warn( _("bad stale count in block %u of directory inode %" PRIu64 "\n"), da_bno, ino); @@ -1794,7 +1690,7 @@ int *repair) { bmap_ext_t *bmp; - xfs_dabuf_t *bp; + struct xfs_buf *bp; int buf_dirty; xfs_dahash_t current_hashval; xfs_dablk_t da_bno; @@ -1804,6 +1700,7 @@ int nex; xfs_dablk_t prev_bno; bmap_ext_t lbmp; + struct xfs_dir3_icleaf_hdr leafhdr; da_bno = da_cursor->level[0].bno; ino = da_cursor->ino; @@ -1829,7 +1726,7 @@ da_bno, ino); goto error_out; } - bp = da_read_buf(mp, nex, bmp); + bp = da_read_buf(mp, nex, bmp, &xfs_dir3_leafn_buf_ops); if (bmp != &lbmp) free(bmp); bmp = NULL; @@ -1839,17 +1736,17 @@ da_bno, ino); goto error_out; } - leaf = bp->data; + leaf = bp->b_addr; + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); /* * Check magic number for leaf directory btree block. */ - if (be16_to_cpu(leaf->hdr.info.magic) != - XFS_DIR2_LEAFN_MAGIC) { + if (!(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || + leafhdr.magic == XFS_DIR3_LEAFN_MAGIC)) { do_warn( _("bad directory leaf magic # %#x for directory inode %" PRIu64 " block %u\n"), - be16_to_cpu(leaf->hdr.info.magic), - ino, da_bno); - da_brelse(bp); + leafhdr.magic, ino, da_bno); + libxfs_putbuf(bp); goto error_out; } buf_dirty = 0; @@ -1859,7 +1756,7 @@ */ if (process_leaf_block_dir2(mp, leaf, da_bno, ino, current_hashval, &greatest_hashval)) { - da_brelse(bp); + libxfs_putbuf(bp); goto error_out; } /* @@ -1870,32 +1767,37 @@ da_cursor->level[0].hashval = greatest_hashval; da_cursor->level[0].bp = bp; da_cursor->level[0].bno = da_bno; - da_cursor->level[0].index = - be16_to_cpu(leaf->hdr.count); + da_cursor->level[0].index = leafhdr.count; da_cursor->level[0].dirty = buf_dirty; - if (be32_to_cpu(leaf->hdr.info.back) != prev_bno) { + if (leafhdr.back != prev_bno) { do_warn( _("bad sibling back pointer for block %u in directory inode %" PRIu64 "\n"), da_bno, ino); - da_brelse(bp); + libxfs_putbuf(bp); goto error_out; } prev_bno = da_bno; - da_bno = be32_to_cpu(leaf->hdr.info.forw); + da_bno = leafhdr.forw; if (da_bno != 0) { if (verify_dir2_path(mp, da_cursor, 0)) { - da_brelse(bp); + libxfs_putbuf(bp); goto error_out; } } current_hashval = greatest_hashval; + /* + * If block looks ok but CRC didn't match, make sure to + * recompute it. + */ + if (!no_modify && bp->b_error == EFSBADCRC) + buf_dirty = 1; ASSERT(buf_dirty == 0 || (buf_dirty && !no_modify)); if (buf_dirty && !no_modify) { *repair = 1; - da_bwrite(mp, bp); + libxfs_writebuf(bp, 0); } else - da_brelse(bp); + libxfs_putbuf(bp); } while (da_bno != 0); if (verify_final_dir2_path(mp, da_cursor, 0)) { /* @@ -1988,8 +1890,8 @@ int isnode) /* node directory not leaf */ { bmap_ext_t *bmp; - xfs_dabuf_t *bp; - xfs_dir2_data_t *data; + struct xfs_buf *bp; + struct xfs_dir2_data_hdr *data; xfs_dfiloff_t dbno; int good; int i; @@ -1997,6 +1899,7 @@ int nex; int t; bmap_ext_t lbmp; + int dirty = 0; *repair = *dot = *dotdot = good = 0; *parent = NULLFSINO; @@ -2014,7 +1917,7 @@ dbno, ino); continue; } - bp = da_read_buf(mp, nex, bmp); + bp = da_read_buf(mp, nex, bmp, &xfs_dir3_data_buf_ops); if (bmp != &lbmp) free(bmp); if (bp == NULL) { @@ -2023,21 +1926,26 @@ dbno, ino); continue; } - data = bp->data; - if (be32_to_cpu(data->hdr.magic) != XFS_DIR2_DATA_MAGIC) + data = bp->b_addr; + if (!(be32_to_cpu(data->magic) == XFS_DIR2_DATA_MAGIC || + be32_to_cpu(data->magic) == XFS_DIR3_DATA_MAGIC)) do_warn( _("bad directory block magic # %#x in block %" PRIu64 " for directory inode %" PRIu64 "\n"), - be32_to_cpu(data->hdr.magic), dbno, ino); + be32_to_cpu(data->magic), dbno, ino); i = process_dir2_data(mp, ino, dip, ino_discovery, dirname, parent, bp, dot, dotdot, (xfs_dablk_t)dbno, - (char *)data + mp->m_dirblksize); - if (i == 0) + (char *)data + mp->m_dirblksize, &dirty); + if (i == 0) { good++; - if (bp->dirty && !no_modify) { + /* Maybe just CRC is wrong. Make sure we correct it. */ + if (bp->b_error == EFSBADCRC) + dirty = 1; + } + if (dirty && !no_modify) { *repair = 1; - da_bwrite(mp, bp); + libxfs_writebuf(bp, 0); } else - da_brelse(bp); + libxfs_putbuf(bp); } if (good == 0) return 1; diff -Nru xfsprogs-3.1.9ubuntu2/repair/dir2.h xfsprogs-3.2.1ubuntu1/repair/dir2.h --- xfsprogs-3.1.9ubuntu2/repair/dir2.h 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/dir2.h 2013-10-10 21:07:17.000000000 +0000 @@ -42,7 +42,7 @@ * Currently, we just trash it. */ typedef struct dir2_level_state { - xfs_dabuf_t *bp; /* block bp */ + xfs_buf_t *bp; /* block bp */ xfs_dablk_t bno; /* file block number */ xfs_dahash_t hashval; /* last verified hashval */ int index; /* current index in block */ @@ -72,11 +72,17 @@ void process_sf_dir2_fixi8( - xfs_dir2_sf_t *sfp, + struct xfs_mount *mp, + struct xfs_dir2_sf_hdr *sfp, xfs_dir2_sf_entry_t **next_sfep); int dir2_is_badino( xfs_ino_t ino); +int +namecheck( + char *name, + int length); + #endif /* _XR_DIR2_H */ diff -Nru xfsprogs-3.1.9ubuntu2/repair/dir.c xfsprogs-3.2.1ubuntu1/repair/dir.c --- xfsprogs-3.1.9ubuntu2/repair/dir.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/dir.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,2642 +0,0 @@ -/* - * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "avl.h" -#include "globals.h" -#include "agheader.h" -#include "incore.h" -#include "protos.h" -#include "err_protos.h" -#include "dinode.h" -#include "dir.h" -#include "bmap.h" - -#if XFS_DIR_LEAF_MAPSIZE >= XFS_ATTR_LEAF_MAPSIZE -#define XR_DA_LEAF_MAPSIZE XFS_DIR_LEAF_MAPSIZE -#else -#define XR_DA_LEAF_MAPSIZE XFS_ATTR_LEAF_MAPSIZE -#endif - - - -typedef struct da_hole_map { - int lost_holes; - int num_holes; - struct { - int base; - int size; - } hentries[XR_DA_LEAF_MAPSIZE]; -} da_hole_map_t; - -/* - * takes a name and length (name need not be null-terminated) - * and returns 1 if the name contains a '/' or a \0, returns 0 - * otherwise - */ -int -namecheck(char *name, int length) -{ - char *c; - int i; - - ASSERT(length < MAXNAMELEN); - - for (c = name, i = 0; i < length; i++, c++) { - if (*c == '/' || *c == '\0') - return(1); - } - - return(0); -} - -/* - * this routine performs inode discovery and tries to fix things - * in place. available redundancy -- inode data size should match - * used directory space in inode. returns number of valid directory - * entries. a non-zero return value means the directory is bogus - * and should be blasted. - */ -static int -process_shortform_dir( - xfs_mount_t *mp, - xfs_ino_t ino, - xfs_dinode_t *dip, - int ino_discovery, - int *dino_dirty, /* out - 1 if dinode buffer dirty? */ - xfs_ino_t *parent, /* out - NULLFSINO if entry doesn't exist */ - char *dirname, /* directory pathname */ - int *repair) /* out - 1 if dir was fixed up */ -{ - xfs_dir_shortform_t *sf; - xfs_dir_sf_entry_t *sf_entry, *next_sfe, *tmp_sfe; - xfs_ino_t lino; - int max_size; - __int64_t ino_dir_size; - int num_entries; - int ino_off; - int namelen; - int i; - int junkit; - int tmp_len; - int tmp_elen; - int bad_sfnamelen; - ino_tree_node_t *irec_p; - char name[MAXNAMELEN + 1]; - -#ifdef XR_DIR_TRACE - fprintf(stderr, "process_shortform_dir - inode %llu\n", ino); -#endif - - sf = (xfs_dir_shortform_t *)XFS_DFORK_DPTR(dip); - max_size = XFS_DFORK_DSIZE(dip, mp); - num_entries = sf->hdr.count; - ino_dir_size = be64_to_cpu(dip->di_size); - *repair = 0; - - ASSERT(ino_dir_size <= max_size); - - /* - * check for bad entry count - */ - if (num_entries * sizeof(xfs_dir_sf_entry_t) + sizeof(xfs_dir_sf_hdr_t) - > max_size || num_entries == 0) - num_entries = 0xFF; - - /* - * run through entries, stop at first bad entry, don't need - * to check for .. since that's encoded in its own field - */ - sf_entry = next_sfe = &sf->list[0]; - for (i = 0; i < num_entries && ino_dir_size > - (__psint_t)next_sfe - (__psint_t)sf; i++) { - tmp_sfe = NULL; - sf_entry = next_sfe; - junkit = 0; - bad_sfnamelen = 0; - xfs_dir_sf_get_dirino(&sf_entry->inumber, &lino); - - /* - * if entry points to self, junk it since only '.' or '..' - * should do that and shortform dirs don't contain either - * entry. if inode number is invalid, trash entry. - * if entry points to special inodes, trash it. - * if inode is unknown but number is valid, - * add it to the list of uncertain inodes. don't - * have to worry about an entry pointing to a - * deleted lost+found inode because the entry was - * deleted at the same time that the inode was cleared. - */ - if (lino == ino) { - junkit = 1; - } else if (verify_inum(mp, lino)) { - /* - * junk the entry, mark lino as NULL since it's bad - */ - do_warn( - _("invalid inode number %" PRIu64 " in directory %" PRIu64 "\n"), lino, ino); - lino = NULLFSINO; - junkit = 1; - } else if (lino == mp->m_sb.sb_rbmino) { - do_warn( - _("entry in shortform dir %" PRIu64 " references rt bitmap inode %" PRIu64 "\n"), - ino, lino); - junkit = 1; - } else if (lino == mp->m_sb.sb_rsumino) { - do_warn( - _("entry in shortform dir %" PRIu64 " references rt summary inode %" PRIu64 "\n"), - ino, lino); - junkit = 1; - } else if (lino == mp->m_sb.sb_uquotino) { - do_warn( - _("entry in shortform dir %" PRIu64 " references user quota inode %" PRIu64 "\n"), - ino, lino); - junkit = 1; - } else if (lino == mp->m_sb.sb_gquotino) { - do_warn( - _("entry in shortform dir %" PRIu64 " references group quota inode %" PRIu64 "\n"), - ino, lino); - junkit = 1; - } else if ((irec_p = find_inode_rec(mp, - XFS_INO_TO_AGNO(mp, lino), - XFS_INO_TO_AGINO(mp, lino))) != NULL) { - /* - * if inode is marked free and we're in inode - * discovery mode, leave the entry alone for now. - * if the inode turns out to be used, we'll figure - * that out when we scan it. If the inode really - * is free, we'll hit this code again in phase 4 - * after we've finished inode discovery and blow - * out the entry then. - */ - ino_off = XFS_INO_TO_AGINO(mp, lino) - - irec_p->ino_startnum; - ASSERT(is_inode_confirmed(irec_p, ino_off)); - - if (!ino_discovery && is_inode_free(irec_p, ino_off)) { - do_warn( - _("entry references free inode %" PRIu64 " in shortform directory %" PRIu64 "\n"), - lino, ino); - junkit = 1; - } - } else if (ino_discovery) { - /* - * put the inode on the uncertain list. we'll - * pull the inode off the list and check it later. - * if the inode turns out be bogus, we'll delete - * this entry in phase 6. - */ - add_inode_uncertain(mp, lino, 0); - } else { - /* - * blow the entry out. we know about all - * undiscovered entries now (past inode discovery - * phase) so this is clearly a bogus entry. - */ - do_warn( - _("entry references non-existent inode %" PRIu64 " in shortform dir %" PRIu64 "\n"), - lino, ino); - junkit = 1; - } - - namelen = sf_entry->namelen; - - if (namelen == 0) { - /* - * if we're really lucky, this is - * the last entry in which case we - * can use the dir size to set the - * namelen value. otherwise, forget - * it because we're not going to be - * able to find the next entry. - */ - bad_sfnamelen = 1; - - if (i == num_entries - 1) { - namelen = ino_dir_size - - ((__psint_t) &sf_entry->name[0] - - (__psint_t) sf); - if (!no_modify) { - do_warn( - _("zero length entry in shortform dir %" PRIu64 ", resetting to %d\n"), - ino, namelen); - sf_entry->namelen = namelen; - } else { - do_warn( - _("zero length entry in shortform dir %" PRIu64 ", would set to %d\n"), - ino, namelen); - } - } else { - do_warn( - _("zero length entry in shortform dir %" PRIu64 ", "), - ino); - if (!no_modify) - do_warn(_("junking %d entries\n"), - num_entries - i); - else - do_warn(_("would junk %d entries\n"), - num_entries - i); - /* - * don't process the rest of the directory, - * break out of processing looop - */ - break; - } - } else if ((__psint_t) sf_entry - (__psint_t) sf + - + xfs_dir_sf_entsize_byentry(sf_entry) - > ino_dir_size) { - bad_sfnamelen = 1; - - if (i == num_entries - 1) { - namelen = ino_dir_size - - ((__psint_t) &sf_entry->name[0] - - (__psint_t) sf); - do_warn( - _("size of last entry overflows space left in in shortform dir %" PRIu64 ", "), - ino); - if (!no_modify) { - do_warn(_("resetting to %d\n"), - namelen); - sf_entry->namelen = namelen; - *dino_dirty = 1; - } else { - do_warn(_("would reset to %d\n"), - namelen); - } - } else { - do_warn( - _("size of entry #%d overflows space left in in shortform dir %" PRIu64 "\n"), - i, ino); - if (!no_modify) { - if (i == num_entries - 1) - do_warn( - _("junking entry #%d\n"), - i); - else - do_warn( - _("junking %d entries\n"), - num_entries - i); - } else { - if (i == num_entries - 1) - do_warn( - _("would junk entry #%d\n"), - i); - else - do_warn( - _("would junk %d entries\n"), - num_entries - i); - } - - break; - } - } - - /* - * check for illegal chars in name. - * no need to check for bad length because - * the length value is stored in a byte - * so it can't be too big, it can only wrap - */ - if (namecheck((char *)&sf_entry->name[0], namelen)) { - /* - * junk entry - */ - do_warn( - _("entry contains illegal character in shortform dir %" PRIu64 "\n"), - ino); - junkit = 1; - } - - /* - * junk the entry by copying up the rest of the - * fork over the current entry and decrementing - * the entry count. if we're in no_modify mode, - * just issue the warning instead. then continue - * the loop with the next_sfe pointer set to the - * correct place in the fork and other counters - * properly set to reflect the deletion if it - * happened. - */ - if (junkit) { - memmove(name, sf_entry->name, namelen); - name[namelen] = '\0'; - - if (!no_modify) { - tmp_elen = xfs_dir_sf_entsize_byentry(sf_entry); - be64_add_cpu(&dip->di_size, -tmp_elen); - ino_dir_size -= tmp_elen; - - tmp_sfe = (xfs_dir_sf_entry_t *) - ((__psint_t) sf_entry + tmp_elen); - tmp_len = max_size - ((__psint_t) tmp_sfe - - (__psint_t) sf); - - memmove(sf_entry, tmp_sfe, tmp_len); - - sf->hdr.count -= 1; - num_entries--; - memset((void *)((__psint_t)sf_entry + tmp_len), - 0, tmp_elen); - - /* - * reset the tmp value to the current - * pointer so we'll process the entry - * we just moved up - */ - tmp_sfe = sf_entry; - - /* - * WARNING: drop the index i by one - * so it matches the decremented count - * for accurate comparisons later - */ - i--; - - *dino_dirty = 1; - *repair = 1; - - do_warn( - _("junking entry \"%s\" in directory inode %" PRIu64 "\n"), - name, ino); - } else { - do_warn( - _("would have junked entry \"%s\" in directory inode %" PRIu64 "\n"), - name, ino); - } - } - - /* - * go onto next entry unless we've just junked an - * entry in which the current entry pointer points - * to an unprocessed entry. have to take into zero-len - * entries into account in no modify mode since we - * calculate size based on next_sfe. - */ - next_sfe = (tmp_sfe == NULL) - ? (xfs_dir_sf_entry_t *) ((__psint_t) sf_entry - + ((!bad_sfnamelen) - ? xfs_dir_sf_entsize_byentry(sf_entry) - : sizeof(xfs_dir_sf_entry_t) - 1 - + namelen)) - : tmp_sfe; - } - - /* sync up sizes and entry counts */ - - if (sf->hdr.count != i) { - if (no_modify) { - do_warn( - _("would have corrected entry count in directory %" PRIu64 " from %d to %d\n"), - ino, sf->hdr.count, i); - } else { - do_warn( - _("corrected entry count in directory %" PRIu64 ", was %d, now %d\n"), - ino, sf->hdr.count, i); - sf->hdr.count = i; - *dino_dirty = 1; - *repair = 1; - } - } - - if ((__psint_t) next_sfe - (__psint_t) sf != ino_dir_size) { - if (no_modify) { - do_warn( - _("would have corrected directory %" PRIu64 " size from %" PRId64 "to %" PRIdPTR "\n"), - ino, ino_dir_size, - (intptr_t)next_sfe - (intptr_t )sf); - } else { - do_warn( - _("corrected directory %" PRIu64 " size, was %" PRId64 ", now %" PRIdPTR "\n"), - ino, ino_dir_size, - (intptr_t)next_sfe - (intptr_t)sf); - - dip->di_size = cpu_to_be64((__psint_t)next_sfe - - (__psint_t)sf); - *dino_dirty = 1; - *repair = 1; - } - } - /* - * check parent (..) entry - */ - xfs_dir_sf_get_dirino(&sf->hdr.parent, parent); - - /* - * if parent entry is bogus, null it out. we'll fix it later . - */ - if (verify_inum(mp, *parent)) { - *parent = NULLFSINO; - - do_warn( - _("bogus .. inode number (%" PRIu64 ") in directory inode %" PRIu64 ", "), - *parent, ino); - if (!no_modify) { - do_warn(_("clearing inode number\n")); - - xfs_dir_sf_put_dirino(parent, &sf->hdr.parent); - *dino_dirty = 1; - *repair = 1; - } else { - do_warn(_("would clear inode number\n")); - } - } else if (ino == mp->m_sb.sb_rootino && ino != *parent) { - /* - * root directories must have .. == . - */ - if (!no_modify) { - do_warn( - _("corrected root directory %" PRIu64 " .. entry, was %" PRIu64 ", now %" PRIu64 "\n"), - ino, *parent, ino); - *parent = ino; - xfs_dir_sf_put_dirino(parent, &sf->hdr.parent); - *dino_dirty = 1; - *repair = 1; - } else { - do_warn( - _("would have corrected root directory %" PRIu64 " .. entry from %" PRIu64 " to %" PRIu64 "\n"), - ino, *parent, ino); - } - } else if (ino == *parent && ino != mp->m_sb.sb_rootino) { - /* - * likewise, non-root directories can't have .. pointing - * to . - */ - *parent = NULLFSINO; - do_warn(_("bad .. entry in dir ino %" PRIu64 ", points to self, "), - ino); - if (!no_modify) { - do_warn(_("clearing inode number\n")); - - xfs_dir_sf_put_dirino(parent, &sf->hdr.parent); - *dino_dirty = 1; - *repair = 1; - } else { - do_warn(_("would clear inode number\n")); - } - } - - return(0); -} - -/* - * Allocate a freespace map for directory or attr leaf blocks (1 bit per byte) - * 1 == used, 0 == free. - */ -da_freemap_t * -alloc_da_freemap(struct xfs_mount *mp) -{ - return calloc(1, mp->m_sb.sb_blocksize / NBBY); -} - -/* - * Set the he range [start, stop) in the directory freemap. - * - * Returns 1 if there is a conflict or 0 if everything's good. - * - * Within a char, the lowest bit of the char represents the byte with - * the smallest address - */ -int -set_da_freemap(xfs_mount_t *mp, da_freemap_t *map, int start, int stop) -{ - const da_freemap_t mask = 0x1; - int i; - - if (start > stop) { - /* - * allow == relation since [x, x) claims 1 byte - */ - do_warn(_("bad range claimed [%d, %d) in da block\n"), - start, stop); - return(1); - } - - if (stop > mp->m_sb.sb_blocksize) { - do_warn( - _("byte range end [%d %d) in da block larger than blocksize %d\n"), - start, stop, mp->m_sb.sb_blocksize); - return(1); - } - - for (i = start; i < stop; i ++) { - if (map[i / NBBY] & (mask << i % NBBY)) { - do_warn(_("multiply claimed byte %d in da block\n"), i); - return(1); - } - map[i / NBBY] |= (mask << i % NBBY); - } - - return(0); -} - -/* - * returns 0 if holemap is consistent with reality (as expressed by - * the da_freemap_t). returns 1 if there's a conflict. - */ -static int -verify_da_freemap(xfs_mount_t *mp, da_freemap_t *map, da_hole_map_t *holes, - xfs_ino_t ino, xfs_dablk_t da_bno) -{ - int i, j, start, len; - const da_freemap_t mask = 0x1; - - for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; i++) { - if (holes->hentries[i].size == 0) - continue; - - start = holes->hentries[i].base; - len = holes->hentries[i].size; - - if (start >= mp->m_sb.sb_blocksize || - start + len > mp->m_sb.sb_blocksize) { - do_warn( - _("hole (start %d, len %d) out of range, block %d, dir ino %" PRIu64 "\n"), - start, len, da_bno, ino); - return(1); - } - - for (j = start; j < start + len; j++) { - if ((map[j / NBBY] & (mask << (j % NBBY))) != 0) { - /* - * bad news -- hole claims a used byte is free - */ - do_warn( - _("hole claims used byte %d, block %d, dir ino %" PRIu64 "\n"), - j, da_bno, ino); - return(1); - } - } - } - - return(0); -} - -static void -process_da_freemap(xfs_mount_t *mp, da_freemap_t *map, da_hole_map_t *holes) -{ - int i, j, in_hole, start, length, smallest, num_holes; - const da_freemap_t mask = 0x1; - - num_holes = in_hole = start = length = 0; - - for (i = 0; i < mp->m_sb.sb_blocksize; i++) { - if ((map[i / NBBY] & (mask << (i % NBBY))) == 0) { - /* - * byte is free (unused) - */ - if (in_hole == 1) - continue; - /* - * start of a new hole - */ - in_hole = 1; - start = i; - } else { - /* - * byte is used - */ - if (in_hole == 0) - continue; - /* - * end of a hole - */ - in_hole = 0; - /* - * if the hole disappears, throw it away - */ - length = i - start; - - if (length <= 0) - continue; - - num_holes++; - - for (smallest = j = 0; j < XR_DA_LEAF_MAPSIZE; j++) { - if (holes->hentries[j].size < - holes->hentries[smallest].size) - smallest = j; - - } - if (length > holes->hentries[smallest].size) { - holes->hentries[smallest].base = start; - holes->hentries[smallest].size = length; - } - } - } - - /* - * see if we have a big hole at the end - */ - if (in_hole == 1) { - /* - * duplicate of hole placement code above - */ - length = i - start; - - if (length > 0) { - num_holes++; - - for (smallest = j = 0; j < XR_DA_LEAF_MAPSIZE; j++) { - if (holes->hentries[j].size < - holes->hentries[smallest].size) - smallest = j; - - } - if (length > holes->hentries[smallest].size) { - holes->hentries[smallest].base = start; - holes->hentries[smallest].size = length; - } - } - } - - holes->lost_holes = MAX(num_holes - XR_DA_LEAF_MAPSIZE, 0); - holes->num_holes = num_holes; - - return; -} - -/* - * returns 1 if the hole info doesn't match, 0 if it does - */ -static int -compare_da_freemaps(xfs_mount_t *mp, da_hole_map_t *holemap, - da_hole_map_t *block_hmap, int entries, - xfs_ino_t ino, xfs_dablk_t da_bno) -{ - int i, k, res, found; - - res = 0; - - /* - * we chop holemap->lost_holes down to being two-valued - * value (1 or 0) for the test because the filesystem - * value is two-valued - */ - if ((holemap->lost_holes > 0 ? 1 : 0) != block_hmap->lost_holes) { - if (verbose) { - do_warn( - _("- derived hole value %d, saw %d, block %d, dir ino %" PRIu64 "\n"), - holemap->lost_holes, block_hmap->lost_holes, - da_bno, ino); - res = 1; - } else - return(1); - } - - for (i = 0; i < entries; i++) { - for (found = k = 0; k < entries; k++) { - if (holemap->hentries[i].base == - block_hmap->hentries[k].base - && holemap->hentries[i].size == - block_hmap->hentries[k].size) - found = 1; - } - if (!found) { - if (verbose) { - do_warn( -_("- derived hole (base %d, size %d) in block %d, dir inode %" PRIu64 " not found\n"), - holemap->hentries[i].base, - holemap->hentries[i].size, - da_bno, ino); - res = 1; - } else - return(1); - } - } - - return(res); -} - -/* - * walk tree from root to the left-most leaf block reading in - * blocks and setting up cursor. passes back file block number of the - * left-most leaf block if successful (bno). returns 1 if successful, - * 0 if unsuccessful. - */ -int -traverse_int_dablock(xfs_mount_t *mp, - da_bt_cursor_t *da_cursor, - xfs_dablk_t *rbno, - int whichfork) -{ - xfs_dablk_t bno; - int i; - xfs_da_intnode_t *node; - xfs_dfsbno_t fsbno; - xfs_buf_t *bp; - - /* - * traverse down left-side of tree until we hit the - * left-most leaf block setting up the btree cursor along - * the way. - */ - bno = 0; - i = -1; - node = NULL; - da_cursor->active = 0; - - do { - /* - * read in each block along the way and set up cursor - */ - fsbno = blkmap_get(da_cursor->blkmap, bno); - - if (fsbno == NULLDFSBNO) - goto error_out; - - bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), - XFS_FSB_TO_BB(mp, 1), 0); - if (!bp) { - if (whichfork == XFS_DATA_FORK) - do_warn( - _("can't read block %u (fsbno %" PRIu64 ") for directory inode %" PRIu64 "\n"), - bno, fsbno, da_cursor->ino); - else - do_warn( - _("can't read block %u (fsbno %" PRIu64 ") for attrbute fork of inode %" PRIu64 "\n"), - bno, fsbno, da_cursor->ino); - goto error_out; - } - - node = (xfs_da_intnode_t *)XFS_BUF_PTR(bp); - - if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC) { - do_warn(_("bad dir/attr magic number in inode %" PRIu64 ", " - "file bno = %u, fsbno = %" PRIu64 "\n"), - da_cursor->ino, bno, fsbno); - libxfs_putbuf(bp); - goto error_out; - } - if (be16_to_cpu(node->hdr.count) > - mp->m_dir_node_ents) { - do_warn(_("bad record count in inode %" PRIu64 ", " - "count = %d, max = %d\n"), - da_cursor->ino, - be16_to_cpu(node->hdr.count), - mp->m_dir_node_ents); - libxfs_putbuf(bp); - goto error_out; - } - - /* - * maintain level counter - */ - if (i == -1) - i = da_cursor->active = be16_to_cpu(node->hdr.level); - else { - if (be16_to_cpu(node->hdr.level) == i - 1) { - i--; - } else { - if (whichfork == XFS_DATA_FORK) - do_warn(_("bad directory btree for " - "directory inode %" PRIu64 "\n"), - da_cursor->ino); - else - do_warn(_("bad attribute fork btree " - "for inode %" PRIu64 "\n"), - da_cursor->ino); - libxfs_putbuf(bp); - goto error_out; - } - } - - da_cursor->level[i].hashval = be32_to_cpu( - node->btree[0].hashval); - da_cursor->level[i].bp = bp; - da_cursor->level[i].bno = bno; - da_cursor->level[i].index = 0; -#ifdef XR_DIR_TRACE - da_cursor->level[i].n = XFS_BUF_TO_DA_INTNODE(bp); -#endif - - /* - * set up new bno for next level down - */ - bno = be32_to_cpu(node->btree[0].before); - } while (node != NULL && i > 1); - - /* - * now return block number and get out - */ - *rbno = da_cursor->level[0].bno = bno; - return(1); - -error_out: - while (i > 1 && i <= da_cursor->active) { - libxfs_putbuf(da_cursor->level[i].bp); - i++; - } - - return(0); -} - -/* - * blow out buffer for this level and all the rest above as well - * if error == 0, we are not expecting to encounter any unreleased - * buffers (e.g. if we do, it's a mistake). if error == 1, we're - * in an error-handling case so unreleased buffers may exist. - */ -static void -release_da_cursor_int(xfs_mount_t *mp, - da_bt_cursor_t *cursor, - int prev_level, - int error) -{ - int level = prev_level + 1; - - if (cursor->level[level].bp != NULL) { - if (!error) { - do_warn(_("release_da_cursor_int got unexpected " - "non-null bp, dabno = %u\n"), - cursor->level[level].bno); - } - ASSERT(error != 0); - - libxfs_putbuf(cursor->level[level].bp); - cursor->level[level].bp = NULL; - } - - if (level < cursor->active) - release_da_cursor_int(mp, cursor, level, error); - - return; -} - -void -release_da_cursor(xfs_mount_t *mp, - da_bt_cursor_t *cursor, - int prev_level) -{ - release_da_cursor_int(mp, cursor, prev_level, 0); -} - -void -err_release_da_cursor(xfs_mount_t *mp, - da_bt_cursor_t *cursor, - int prev_level) -{ - release_da_cursor_int(mp, cursor, prev_level, 1); -} - -/* - * make sure that all entries in all blocks along the right side of - * of the tree are used and hashval's are consistent. level is the - * level of the descendent block. returns 0 if good (even if it had - * to be fixed up), and 1 if bad. The right edge of the tree is - * technically a block boundary. this routine should be used then - * instead of verify_da_path(). - */ -int -verify_final_da_path(xfs_mount_t *mp, - da_bt_cursor_t *cursor, - const int p_level) -{ - xfs_da_intnode_t *node; - xfs_dahash_t hashval; - int bad = 0; - int entry; - int this_level = p_level + 1; - -#ifdef XR_DIR_TRACE - fprintf(stderr, "in verify_final_da_path, this_level = %d\n", - this_level); -#endif - /* - * the index should point to the next "unprocessed" entry - * in the block which should be the final (rightmost) entry - */ - entry = cursor->level[this_level].index; - node = (xfs_da_intnode_t *)XFS_BUF_PTR(cursor->level[this_level].bp); - /* - * check internal block consistency on this level -- ensure - * that all entries are used, encountered and expected hashvals - * match, etc. - */ - if (entry != be16_to_cpu(node->hdr.count) - 1) { - do_warn(_("directory/attribute block used/count " - "inconsistency - %d/%hu\n"), - entry, be16_to_cpu(node->hdr.count)); - bad++; - } - /* - * hash values monotonically increasing ??? - */ - if (cursor->level[this_level].hashval >= - be32_to_cpu(node->btree[entry].hashval)) { - do_warn(_("directory/attribute block hashvalue inconsistency, " - "expected > %u / saw %u\n"), - cursor->level[this_level].hashval, - be32_to_cpu(node->btree[entry].hashval)); - bad++; - } - if (be32_to_cpu(node->hdr.info.forw) != 0) { - do_warn(_("bad directory/attribute forward block pointer, " - "expected 0, saw %u\n"), - be32_to_cpu(node->hdr.info.forw)); - bad++; - } - if (bad) { - do_warn(_("bad directory block in dir ino %" PRIu64 "\n"), - cursor->ino); - return(1); - } - /* - * keep track of greatest block # -- that gets - * us the length of the directory - */ - if (cursor->level[this_level].bno > cursor->greatest_bno) - cursor->greatest_bno = cursor->level[this_level].bno; - - /* - * ok, now check descendant block number against this level - */ - if (cursor->level[p_level].bno != be32_to_cpu( - node->btree[entry].before)) { -#ifdef XR_DIR_TRACE - fprintf(stderr, "bad directory btree pointer, child bno should " - "be %d, block bno is %d, hashval is %u\n", - be16_to_cpu(node->btree[entry].before), - cursor->level[p_level].bno, - cursor->level[p_level].hashval); - fprintf(stderr, "verify_final_da_path returns 1 (bad) #1a\n"); -#endif - return(1); - } - - if (cursor->level[p_level].hashval != be32_to_cpu( - node->btree[entry].hashval)) { - if (!no_modify) { - do_warn(_("correcting bad hashval in non-leaf " - "dir/attr block\n\tin (level %d) in " - "inode %" PRIu64 ".\n"), - this_level, cursor->ino); - node->btree[entry].hashval = cpu_to_be32( - cursor->level[p_level].hashval); - cursor->level[this_level].dirty++; - } else { - do_warn(_("would correct bad hashval in non-leaf " - "dir/attr block\n\tin (level %d) in " - "inode %" PRIu64 ".\n"), - this_level, cursor->ino); - } - } - - /* - * Note: squirrel hashval away _before_ releasing the - * buffer, preventing a use-after-free problem. - */ - hashval = be32_to_cpu(node->btree[entry].hashval); - - /* - * release/write buffer - */ - ASSERT(cursor->level[this_level].dirty == 0 || - (cursor->level[this_level].dirty && !no_modify)); - - if (cursor->level[this_level].dirty && !no_modify) - libxfs_writebuf(cursor->level[this_level].bp, 0); - else - libxfs_putbuf(cursor->level[this_level].bp); - - cursor->level[this_level].bp = NULL; - - /* - * bail out if this is the root block (top of tree) - */ - if (this_level >= cursor->active) { -#ifdef XR_DIR_TRACE - fprintf(stderr, "verify_final_da_path returns 0 (ok)\n"); -#endif - return(0); - } - /* - * set hashvalue to correctly reflect the now-validated - * last entry in this block and continue upwards validation - */ - cursor->level[this_level].hashval = hashval; - return(verify_final_da_path(mp, cursor, this_level)); -} - -/* - * Verifies the path from a descendant block up to the root. - * Should be called when the descendant level traversal hits - * a block boundary before crossing the boundary (reading in a new - * block). - * - * the directory/attr btrees work differently to the other fs btrees. - * each interior block contains records that are - * pairs. The bno is a file bno, not a filesystem bno. The last - * hashvalue in the block will be . BUT unlike - * the freespace btrees, the *last* value in each block gets - * propagated up the tree instead of the first value in each block. - * that is, the interior records point to child blocks and the *greatest* - * hash value contained by the child block is the one the block above - * uses as the key for the child block. - * - * level is the level of the descendent block. returns 0 if good, - * and 1 if bad. The descendant block may be a leaf block. - * - * the invariant here is that the values in the cursor for the - * levels beneath this level (this_level) and the cursor index - * for this level *must* be valid. - * - * that is, the hashval/bno info is accurate for all - * DESCENDANTS and match what the node[index] information - * for the current index in the cursor for this level. - * - * the index values in the cursor for the descendant level - * are allowed to be off by one as they will reflect the - * next entry at those levels to be processed. - * - * the hashvalue for the current level can't be set until - * we hit the last entry in the block so, it's garbage - * until set by this routine. - * - * bno and bp for the current block/level are always valid - * since they have to be set so we can get a buffer for the - * block. - */ -int -verify_da_path(xfs_mount_t *mp, - da_bt_cursor_t *cursor, - const int p_level) -{ - xfs_da_intnode_t *node; - xfs_da_intnode_t *newnode; - xfs_dfsbno_t fsbno; - xfs_dablk_t dabno; - xfs_buf_t *bp; - int bad; - int entry; - int this_level = p_level + 1; - - /* - * index is currently set to point to the entry that - * should be processed now in this level. - */ - entry = cursor->level[this_level].index; - node = (xfs_da_intnode_t *)XFS_BUF_PTR(cursor->level[this_level].bp); - - /* - * if this block is out of entries, validate this - * block and move on to the next block. - * and update cursor value for said level - */ - if (entry >= be16_to_cpu(node->hdr.count)) { - /* - * update the hash value for this level before - * validating it. bno value should be ok since - * it was set when the block was first read in. - */ - cursor->level[this_level].hashval = - be32_to_cpu(node->btree[entry - 1].hashval); - - /* - * keep track of greatest block # -- that gets - * us the length of the directory - */ - if (cursor->level[this_level].bno > cursor->greatest_bno) - cursor->greatest_bno = cursor->level[this_level].bno; - - /* - * validate the path for the current used-up block - * before we trash it - */ - if (verify_da_path(mp, cursor, this_level)) - return(1); - /* - * ok, now get the next buffer and check sibling pointers - */ - dabno = be32_to_cpu(node->hdr.info.forw); - ASSERT(dabno != 0); - fsbno = blkmap_get(cursor->blkmap, dabno); - - if (fsbno == NULLDFSBNO) { - do_warn(_("can't get map info for block %u " - "of directory inode %" PRIu64 "\n"), - dabno, cursor->ino); - return(1); - } - - bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), - XFS_FSB_TO_BB(mp, 1), 0); - if (!bp) { - do_warn( - _("can't read block %u (%" PRIu64 ") for directory inode %" PRIu64 "\n"), - dabno, fsbno, cursor->ino); - return(1); - } - - newnode = (xfs_da_intnode_t *)XFS_BUF_PTR(bp); - /* - * verify magic number and back pointer, sanity-check - * entry count, verify level - */ - bad = 0; - if (XFS_DA_NODE_MAGIC != be16_to_cpu(newnode->hdr.info.magic)) { - do_warn( - _("bad magic number %x in block %u (%" PRIu64 ") for directory inode %" PRIu64 "\n"), - be16_to_cpu(newnode->hdr.info.magic), - dabno, fsbno, cursor->ino); - bad++; - } - if (be32_to_cpu(newnode->hdr.info.back) != - cursor->level[this_level].bno) { - do_warn( - _("bad back pointer in block %u (%"PRIu64 ") for directory inode %" PRIu64 "\n"), - dabno, fsbno, cursor->ino); - bad++; - } - if (be16_to_cpu(newnode->hdr.count) > mp->m_dir_node_ents) { - do_warn( - _("entry count %d too large in block %u (%" PRIu64 ") for directory inode %" PRIu64 "\n"), - be16_to_cpu(newnode->hdr.count), - dabno, fsbno, cursor->ino); - bad++; - } - if (be16_to_cpu(newnode->hdr.level) != this_level) { - do_warn( - _("bad level %d in block %u (%" PRIu64 ") for directory inode %" PRIu64 "\n"), - be16_to_cpu(newnode->hdr.level), - dabno, fsbno, cursor->ino); - bad++; - } - if (bad) { -#ifdef XR_DIR_TRACE - fprintf(stderr, "verify_da_path returns 1 (bad) #4\n"); -#endif - libxfs_putbuf(bp); - return(1); - } - /* - * update cursor, write out the *current* level if - * required. don't write out the descendant level - */ - ASSERT(cursor->level[this_level].dirty == 0 || - (cursor->level[this_level].dirty && !no_modify)); - - if (cursor->level[this_level].dirty && !no_modify) - libxfs_writebuf(cursor->level[this_level].bp, 0); - else - libxfs_putbuf(cursor->level[this_level].bp); - cursor->level[this_level].bp = bp; - cursor->level[this_level].dirty = 0; - cursor->level[this_level].bno = dabno; - cursor->level[this_level].hashval = - be32_to_cpu(newnode->btree[0].hashval); -#ifdef XR_DIR_TRACE - cursor->level[this_level].n = newnode; -#endif - node = newnode; - - entry = cursor->level[this_level].index = 0; - } - /* - * ditto for block numbers - */ - if (cursor->level[p_level].bno != - be32_to_cpu(node->btree[entry].before)) { -#ifdef XR_DIR_TRACE - fprintf(stderr, "bad directory btree pointer, child bno " - "should be %d, block bno is %d, hashval is %u\n", - be32_to_cpu(node->btree[entry].before), - cursor->level[p_level].bno, - cursor->level[p_level].hashval); - fprintf(stderr, "verify_da_path returns 1 (bad) #1a\n"); -#endif - return(1); - } - /* - * ok, now validate last hashvalue in the descendant - * block against the hashval in the current entry - */ - if (cursor->level[p_level].hashval != - be32_to_cpu(node->btree[entry].hashval)) { - if (!no_modify) { - do_warn(_("correcting bad hashval in interior " - "dir/attr block\n\tin (level %d) in " - "inode %" PRIu64 ".\n"), - this_level, cursor->ino); - node->btree[entry].hashval = cpu_to_be32( - cursor->level[p_level].hashval); - cursor->level[this_level].dirty++; - } else { - do_warn(_("would correct bad hashval in interior " - "dir/attr block\n\tin (level %d) in " - "inode %" PRIu64 ".\n"), - this_level, cursor->ino); - } - } - /* - * increment index for this level to point to next entry - * (which should point to the next descendant block) - */ - cursor->level[this_level].index++; -#ifdef XR_DIR_TRACE - fprintf(stderr, "verify_da_path returns 0 (ok)\n"); -#endif - return(0); -} - -/* - * called by both node dir and leaf dir processing routines - * validates all contents *but* the sibling pointers (forw/back) - * and the magic number. - * - * returns 0 if the directory is ok or has been brought to the - * stage that it can be fixed up later (in phase 6), - * 1 if it has to be junked. - * - * Right now we fix a lot of things (TBD == to be deleted). - * - * incorrect . entries - inode # is corrected - * entries with mismatched hashvalue/name strings - hashvalue reset - * entries whose hashvalues are out-of-order - entry marked TBD - * .. entries with invalid inode numbers - entry marked TBD - * entries with invalid inode numbers - entry marked TBD - * multiple . entries - all but the first entry are marked TBD - * zero-length entries - entry is deleted - * entries with an out-of-bounds name index ptr - entry is deleted - * - * entries marked TBD have the first character of the name (which - * lives in the heap) have the first character in the name set - * to '/' -- an illegal value. - * - * entries deleted right here are deleted by blowing away the entry - * (but leaving the heap untouched). any space that was used - * by the deleted entry will be reclaimed by the block freespace - * (da_freemap) processing code. - * - * if two entries claim the same space in the heap (say, due to - * bad entry name index pointers), we lose the directory. We could - * try harder to fix this but it'll do for now. - */ -static int -process_leaf_dir_block( - xfs_mount_t *mp, - xfs_dir_leafblock_t *leaf, - xfs_dablk_t da_bno, - xfs_ino_t ino, - xfs_dahash_t last_hashval, /* last hashval encountered */ - int ino_discovery, - blkmap_t *blkmap, - int *dot, - int *dotdot, - xfs_ino_t *parent, - int *buf_dirty, /* is buffer dirty? */ - xfs_dahash_t *next_hashval) /* greatest hashval in block */ -{ - xfs_ino_t lino; - xfs_dir_leaf_entry_t *entry; - xfs_dir_leaf_entry_t *s_entry; - xfs_dir_leaf_entry_t *d_entry; - xfs_dir_leafblock_t *new_leaf; - char *first_byte; - xfs_dir_leaf_name_t *namest; - ino_tree_node_t *irec_p; - int num_entries; - xfs_dahash_t hashval; - int i; - int nm_illegal; - int bytes; - int start; - int stop; - int res = 0; - int ino_off; - int first_used; - int bytes_used; - int reset_holes; - int zero_len_entries; - char fname[MAXNAMELEN + 1]; - da_hole_map_t holemap; - da_hole_map_t bholemap; - da_freemap_t *dir_freemap; - -#ifdef XR_DIR_TRACE - fprintf(stderr, "\tprocess_leaf_dir_block - ino %" PRIu64 "\n", ino); -#endif - - /* - * clear static dir block freespace bitmap - */ - dir_freemap = alloc_da_freemap(mp); - - *buf_dirty = 0; - first_used = mp->m_sb.sb_blocksize; - zero_len_entries = 0; - bytes_used = 0; - - i = stop = sizeof(xfs_dir_leaf_hdr_t); - if (set_da_freemap(mp, dir_freemap, 0, stop)) { - do_warn( -_("directory block header conflicts with used space in directory inode %" PRIu64 "\n"), - ino); - res = 1; - goto out; - } - - /* - * verify structure: monotonically increasing hash value for - * all leaf entries, indexes for all entries must be within - * this fs block (trivially true for 64K blocks). also track - * used space so we can check the freespace map. check for - * zero-length entries. for now, if anything's wrong, we - * junk the directory and we'll pick up no-longer referenced - * inodes on a later pass. - */ - for (i = 0, entry = &leaf->entries[0]; - i < be16_to_cpu(leaf->hdr.count); - i++, entry++) { - /* - * check that the name index isn't out of bounds - * if it is, delete the entry since we can't - * grab the inode #. - */ - if (be16_to_cpu(entry->nameidx) >= - mp->m_sb.sb_blocksize) { - if (!no_modify) { - *buf_dirty = 1; - - if (be16_to_cpu(leaf->hdr.count) > 1) { - do_warn( -_("nameidx %d for entry #%d, bno %d, ino %" PRIu64 " > fs blocksize, deleting entry\n"), - be16_to_cpu(entry->nameidx), - i, da_bno, ino); - ASSERT(be16_to_cpu(leaf->hdr.count) > i); - - bytes = (be16_to_cpu(leaf->hdr.count) - i) * - sizeof(xfs_dir_leaf_entry_t); - - /* - * compress table unless we're - * only dealing with 1 entry - * (the last one) in which case - * just zero it. - */ - if (bytes > - sizeof(xfs_dir_leaf_entry_t)) { - memmove(entry, entry + 1, - bytes); - memset((void *) - ((__psint_t) entry + bytes), 0, - sizeof(xfs_dir_leaf_entry_t)); - } else { - memset(entry, 0, - sizeof(xfs_dir_leaf_entry_t)); - } - - /* - * sync vars to match smaller table. - * don't have to worry about freespace - * map since we haven't set it for - * this entry yet. - */ - be16_add_cpu(&leaf->hdr.count, -1); - i--; - entry--; - } else { - do_warn( -_("nameidx %d, entry #%d, bno %d, ino %" PRIu64 " > fs blocksize, marking entry bad\n"), - be16_to_cpu(entry->nameidx), - i, da_bno, ino); - entry->nameidx = cpu_to_be16( - mp->m_sb.sb_blocksize - - sizeof(xfs_dir_leaf_name_t)); - namest = xfs_dir_leaf_namestruct(leaf, - be16_to_cpu(entry->nameidx)); - lino = NULLFSINO; - xfs_dir_sf_put_dirino(&lino, - &namest->inumber); - namest->name[0] = '/'; - } - } else { - do_warn( -_("nameidx %d, entry #%d, bno %d, ino %" PRIu64 " > fs blocksize, would delete entry\n"), - be16_to_cpu(entry->nameidx), - i, da_bno, ino); - } - continue; - } - /* - * inode processing -- make sure the inode - * is in our tree or we add it to the uncertain - * list if the inode # is valid. if namelen is 0, - * we can still try for the inode as long as nameidx - * is ok. - */ - namest = xfs_dir_leaf_namestruct(leaf, - be16_to_cpu(entry->nameidx)); - xfs_dir_sf_get_dirino(&namest->inumber, &lino); - - /* - * we may have to blow out an entry because of bad - * inode numbers. do NOT touch the name until after - * we've computed the hashvalue and done a namecheck() - * on the name. - */ - if (!ino_discovery && lino == NULLFSINO) { - /* - * don't do a damned thing. We already - * found this (or did it ourselves) during - * phase 3. - */ - } else if (verify_inum(mp, lino)) { - /* - * bad inode number. clear the inode - * number and the entry will get removed - * later. We don't trash the directory - * since it's still structurally intact. - */ - do_warn( -_("invalid ino number %" PRIu64 " in dir ino %" PRIu64 ", entry #%d, bno %d\n"), - lino, ino, i, da_bno); - if (!no_modify) { - do_warn( - _("\tclearing ino number in entry %d...\n"), - i); - lino = NULLFSINO; - xfs_dir_sf_put_dirino(&lino, &namest->inumber); - *buf_dirty = 1; - } else { - do_warn( - _("\twould clear ino number in entry %d...\n"), - i); - } - } else if (lino == mp->m_sb.sb_rbmino) { - do_warn( -_("entry #%d, bno %d in directory %" PRIu64 " references realtime bitmap inode %" PRIu64 "\n"), - i, da_bno, ino, lino); - if (!no_modify) { - do_warn( - _("\tclearing ino number in entry %d...\n"), - i); - - lino = NULLFSINO; - xfs_dir_sf_put_dirino(&lino, &namest->inumber); - *buf_dirty = 1; - } else { - do_warn( - _("\twould clear ino number in entry %d...\n"), - i); - } - } else if (lino == mp->m_sb.sb_rsumino) { - do_warn( -_("entry #%d, bno %d in directory %" PRIu64 " references realtime summary inode %" PRIu64 "\n"), - i, da_bno, ino, lino); - if (!no_modify) { - do_warn( - _("\tclearing ino number in entry %d...\n"), i); - - lino = NULLFSINO; - xfs_dir_sf_put_dirino(&lino, &namest->inumber); - *buf_dirty = 1; - } else { - do_warn( - _("\twould clear ino number in entry %d...\n"), - i); - } - } else if (lino == mp->m_sb.sb_uquotino) { - do_warn( -_("entry #%d, bno %d in directory %" PRIu64 " references user quota inode %" PRIu64 "\n"), - i, da_bno, ino, lino); - if (!no_modify) { - do_warn( - _("\tclearing ino number in entry %d...\n"), - i); - - lino = NULLFSINO; - xfs_dir_sf_put_dirino(&lino, &namest->inumber); - *buf_dirty = 1; - } else { - do_warn( - _("\twould clear ino number in entry %d...\n"), - i); - } - } else if (lino == mp->m_sb.sb_gquotino) { - do_warn( -_("entry #%d, bno %d in directory %" PRIu64 " references group quota inode %" PRIu64 "\n"), - i, da_bno, ino, lino); - if (!no_modify) { - do_warn( - _("\tclearing ino number in entry %d...\n"), - i); - - lino = NULLFSINO; - xfs_dir_sf_put_dirino(&lino, &namest->inumber); - *buf_dirty = 1; - } else { - do_warn( - _("\twould clear ino number in entry %d...\n"), - i); - } - } else if ((irec_p = find_inode_rec(mp, - XFS_INO_TO_AGNO(mp, lino), - XFS_INO_TO_AGINO(mp, lino))) != NULL) { - /* - * inode recs should have only confirmed - * inodes in them - */ - ino_off = XFS_INO_TO_AGINO(mp, lino) - - irec_p->ino_startnum; - ASSERT(is_inode_confirmed(irec_p, ino_off)); - /* - * if inode is marked free and we're in inode - * discovery mode, leave the entry alone for now. - * if the inode turns out to be used, we'll figure - * that out when we scan it. If the inode really - * is free, we'll hit this code again in phase 4 - * after we've finished inode discovery and blow - * out the entry then. - */ - if (!ino_discovery && is_inode_free(irec_p, ino_off)) { - if (!no_modify) { - do_warn( -_("entry references free inode %" PRIu64 " in directory %" PRIu64 ", will clear entry\n"), - lino, ino); - lino = NULLFSINO; - xfs_dir_sf_put_dirino(&lino, - &namest->inumber); - *buf_dirty = 1; - } else { - do_warn( -_("entry references free inode %" PRIu64 " in directory %" PRIu64 ", would clear entry\n"), - lino, ino); - } - } - } else if (ino_discovery) { - add_inode_uncertain(mp, lino, 0); - } else { - do_warn( - _("bad ino number %" PRIu64 " in dir ino %" PRIu64 ", entry #%d, bno %d\n"), - lino, ino, i, da_bno); - if (!no_modify) { - do_warn(_("clearing inode number...\n")); - lino = NULLFSINO; - xfs_dir_sf_put_dirino(&lino, &namest->inumber); - *buf_dirty = 1; - } else { - do_warn(_("would clear inode number...\n")); - } - } - /* - * if we have a zero-length entry, trash it. - * we may lose the inode (chunk) if we don't - * finish the repair successfully and the inode - * isn't mentioned anywhere else (like in the inode - * tree) but the alternative is to risk losing the - * entire directory by trying to use the next byte - * to turn the entry into a 1-char entry. That's - * probably a safe bet but if it didn't work, we'd - * lose the entire directory the way we currently do - * things. (Maybe we should change that later :-). - */ - if (entry->namelen == 0) { - *buf_dirty = 1; - - if (be16_to_cpu(leaf->hdr.count) > 1) { - do_warn( - _("entry #%d, dir inode %" PRIu64 ", has zero-len name, deleting entry\n"), - i, ino); - ASSERT(be16_to_cpu(leaf->hdr.count) > i); - - bytes = (be16_to_cpu(leaf->hdr.count) - i) * - sizeof(xfs_dir_leaf_entry_t); - - /* - * compress table unless we're - * only dealing with 1 entry - * (the last one) in which case - * just zero it. - */ - if (bytes > sizeof(xfs_dir_leaf_entry_t)) { - memmove(entry, entry + 1, bytes); - memset((void *)((__psint_t) entry + - bytes), 0, - sizeof(xfs_dir_leaf_entry_t)); - } else { - memset(entry, 0, - sizeof(xfs_dir_leaf_entry_t)); - } - - /* - * sync vars to match smaller table. - * don't have to worry about freespace - * map since we haven't set it for - * this entry yet. - */ - be16_add_cpu(&leaf->hdr.count, -1); - i--; - entry--; - } else { - /* - * if it's the only entry, preserve the - * inode number for now - */ - do_warn( - _("entry #%d, dir inode %" PRIu64 ", has zero-len name, marking entry bad\n"), - i, ino); - entry->nameidx = cpu_to_be16( - mp->m_sb.sb_blocksize - - sizeof(xfs_dir_leaf_name_t)); - namest = xfs_dir_leaf_namestruct(leaf, - be16_to_cpu(entry->nameidx)); - xfs_dir_sf_put_dirino(&lino, &namest->inumber); - namest->name[0] = '/'; - } - } else if (be16_to_cpu(entry->nameidx) + entry->namelen > - XFS_LBSIZE(mp)) { - do_warn( -_("bad size, entry #%d in dir inode %" PRIu64 ", block %u -- entry overflows block\n"), - i, ino, da_bno); - res = 1; - goto out; - } - - start = (__psint_t)&leaf->entries[i] - (__psint_t)leaf;; - stop = start + sizeof(xfs_dir_leaf_entry_t); - - if (set_da_freemap(mp, dir_freemap, start, stop)) { - do_warn( -_("dir entry slot %d in block %u conflicts with used space in dir inode %" PRIu64 "\n"), - i, da_bno, ino); - res = 1; - goto out; - } - - /* - * check if the name is legal. if so, then - * check that the name and hashvalues match. - * - * if the name is illegal, we don't check the - * hashvalue computed from it. we just make - * sure that the hashvalue in the entry is - * monotonically increasing wrt to the previous - * entry. - * - * Note that we do NOT have to check the length - * because the length is stored in a one-byte - * unsigned int which max's out at MAXNAMELEN - * making it impossible for the stored length - * value to be out of range. - */ - memmove(fname, namest->name, entry->namelen); - fname[entry->namelen] = '\0'; - hashval = libxfs_da_hashname((uchar_t *) fname, entry->namelen); - - /* - * only complain about illegal names in phase 3 (when - * inode discovery is turned on). Otherwise, we'd complain - * a lot during phase 4. If the name is illegal, leave - * the hash value in that entry alone. - */ - nm_illegal = namecheck(fname, entry->namelen); - - if (ino_discovery && nm_illegal) { - /* - * junk the entry, illegal name - */ - if (!no_modify) { - do_warn( -_("illegal name \"%s\" in directory inode %" PRIu64 ", entry will be cleared\n"), - fname, ino); - namest->name[0] = '/'; - *buf_dirty = 1; - } else { - do_warn( -_("illegal name \"%s\" in directory inode %" PRIu64 ", entry would be cleared\n"), - fname, ino); - } - } else if (!nm_illegal && - be32_to_cpu(entry->hashval) != hashval) { - /* - * try resetting the hashvalue to the correct - * value for the string, if the string has been - * corrupted, too, that will get picked up next - */ - do_warn(_("\tmismatched hash value for entry \"%s\"\n"), - fname); - if (!no_modify) { - do_warn( - _("\t\tin directory inode %" PRIu64 ". resetting hash value.\n"), - ino); - entry->hashval = cpu_to_be32(hashval); - *buf_dirty = 1; - } else { - do_warn( - _("\t\tin directory inode %" PRIu64 ". would reset hash value.\n"), - ino); - } - } - - /* - * now we can mark entries with NULLFSINO's bad - */ - if (!no_modify && lino == NULLFSINO) { - namest->name[0] = '/'; - *buf_dirty = 1; - } - - /* - * regardless of whether the entry has or hasn't been - * marked for deletion, the hash value ordering must - * be maintained. - */ - if (be32_to_cpu(entry->hashval) < last_hashval) { - /* - * blow out the entry -- set hashval to sane value - * and set the first character in the string to - * the illegal value '/'. Reset the hash value - * to the last hashvalue so that verify_da_path - * will fix up the interior pointers correctly. - * the entry will be deleted later (by routines - * that need only the entry #). We keep the - * inode number in the entry so we can attach - * the inode to the orphanage later. - */ - do_warn(_("\tbad hash ordering for entry \"%s\"\n"), - fname); - if (!no_modify) { - do_warn( - _("\t\tin directory inode %" PRIu64 ". will clear entry\n"), - ino); - entry->hashval = cpu_to_be32(last_hashval); - namest->name[0] = '/'; - *buf_dirty = 1; - } else { - do_warn( - _("\t\tin directory inode %" PRIu64 ". would clear entry\n"), - ino); - } - } - - *next_hashval = last_hashval = be32_to_cpu(entry->hashval); - - /* - * if heap data conflicts with something, - * blow it out and skip the rest of the loop - */ - if (set_da_freemap(mp, dir_freemap, be16_to_cpu(entry->nameidx), - be16_to_cpu(entry->nameidx) - + sizeof(xfs_dir_leaf_name_t) - + entry->namelen - 1)) { - do_warn( -_("name \"%s\" (block %u, slot %d) conflicts with used space in dir inode %" PRIu64 "\n"), - fname, da_bno, i, ino); - if (!no_modify) { - entry->namelen = 0; - *buf_dirty = 1; - - do_warn( - _("will clear entry \"%s\" (#%d) in directory inode %" PRIu64 "\n"), - fname, i, ino); - } else { - do_warn( - _("would clear entry \"%s\" (#%d)in directory inode %" PRIu64 "\n"), - fname, i, ino); - } - continue; - } - - /* - * keep track of heap stats (first byte used, total bytes used) - */ - if (be16_to_cpu(entry->nameidx) < first_used) - first_used = be16_to_cpu(entry->nameidx); - bytes_used += entry->namelen; - - /* - * special . or .. entry processing - */ - if (entry->namelen == 2 && namest->name[0] == '.' && - namest->name[1] == '.') { - /* - * the '..' case - */ - if (!*dotdot) { - (*dotdot)++; - *parent = lino; -#ifdef XR_DIR_TRACE - fprintf(stderr, "process_leaf_dir_block found .. entry (parent) = %" PRIu64 "\n", lino); -#endif - /* - * what if .. == .? legal only in - * the root inode. blow out entry - * and set parent to NULLFSINO otherwise. - */ - if (ino == lino && - ino != mp->m_sb.sb_rootino) { - *parent = NULLFSINO; - do_warn( - _("bad .. entry in dir ino %" PRIu64 ", points to self"), - ino); - if (!no_modify) { - do_warn( - _("will clear entry\n")); - namest->name[0] = '/'; - *buf_dirty = 1; - } else { - do_warn( - _("would clear entry\n")); - } - } else if (ino != lino && - ino == mp->m_sb.sb_rootino) { - /* - * we have to make sure that . == .. - * in the root inode - */ - if (!no_modify) { - do_warn( - _("correcting .. entry in root inode %" PRIu64 ", was %" PRIu64 "\n"), - ino, *parent); - xfs_dir_sf_put_dirino( - &ino, &namest->inumber); - *buf_dirty = 1; - } else { - do_warn( - _("bad .. entry (%" PRIu64 ") in root inode %" PRIu64 " should be %" PRIu64 "\n"), - *parent, - ino, ino); - } - } - } else { - /* - * can't fix the directory unless we know - * which .. entry is the right one. Both - * have valid inode numbers, match the hash - * value and the hash values are ordered - * properly or we wouldn't be here. So - * since both seem equally valid, trash - * this one. - */ - if (!no_modify) { - do_warn( -_("multiple .. entries in directory inode %" PRIu64 ", will clear second entry\n"), - ino); - namest->name[0] = '/'; - *buf_dirty = 1; - } else { - do_warn( -_("multiple .. entries in directory inode %" PRIu64 ", would clear second entry\n"), - ino); - } - } - } else if (entry->namelen == 1 && namest->name[0] == '.') { - /* - * the '.' case - */ - if (!*dot) { - (*dot)++; - if (lino != ino) { - if (!no_modify) { - do_warn( -_(". in directory inode %" PRIu64 " has wrong value (%" PRIu64 "), fixing entry...\n"), - ino, lino); - xfs_dir_sf_put_dirino(&ino, - &namest->inumber); - *buf_dirty = 1; - } else { - do_warn( -_(". in directory inode %" PRIu64 " has wrong value (%" PRIu64 ")\n"), - ino, lino); - } - } - } else { - do_warn( -_("multiple . entries in directory inode %" PRIu64 "\n"), - ino); - /* - * mark entry as to be junked. - */ - if (!no_modify) { - do_warn( -_("will clear one . entry in directory inode %" PRIu64 "\n"), - ino); - namest->name[0] = '/'; - *buf_dirty = 1; - } else { - do_warn( -_("would clear one . entry in directory inode %" PRIu64 "\n"), - ino); - } - } - } else { - /* - * all the rest -- make sure only . references self - */ - if (lino == ino) { - do_warn( - _("entry \"%s\" in directory inode %" PRIu64 " points to self, "), - fname, ino); - if (!no_modify) { - do_warn(_("will clear entry\n")); - namest->name[0] = '/'; - *buf_dirty = 1; - } else { - do_warn(_("would clear entry\n")); - } - } - } - } - - /* - * compare top of heap values and reset as required. if the - * holes flag is set, don't reset first_used unless it's - * pointing to used bytes. we're being conservative here - * since the block will get compacted anyhow by the kernel. - */ - if ((leaf->hdr.holes == 0 && - first_used != be16_to_cpu(leaf->hdr.firstused)) || - be16_to_cpu(leaf->hdr.firstused) > first_used) { - if (!no_modify) { - if (verbose) - do_warn( -_("- resetting first used heap value from %d to %d in block %u of dir ino %" PRIu64 "\n"), - be16_to_cpu(leaf->hdr.firstused), - first_used, da_bno, ino); - leaf->hdr.firstused = cpu_to_be16(first_used); - *buf_dirty = 1; - } else { - if (verbose) - do_warn( -_("- would reset first used value from %d to %d in block %u of dir ino %" PRIu64 "\n"), - be16_to_cpu(leaf->hdr.firstused), - first_used, da_bno, ino); - } - } - - if (bytes_used != be16_to_cpu(leaf->hdr.namebytes)) { - if (!no_modify) { - if (verbose) - do_warn( -_("- resetting namebytes cnt from %d to %d in block %u of dir inode %" PRIu64 "\n"), - be16_to_cpu(leaf->hdr.namebytes), - bytes_used, da_bno, ino); - leaf->hdr.namebytes = cpu_to_be16(bytes_used); - *buf_dirty = 1; - } else { - if (verbose) - do_warn( -_("- would reset namebytes cnt from %d to %d in block %u of dir inode %" PRIu64 "\n"), - be16_to_cpu(leaf->hdr.namebytes), - bytes_used, da_bno, ino); - } - } - - /* - * If the hole flag is not set, then we know that there can - * be no lost holes. If the hole flag is set, then it's ok - * if the on-disk holemap doesn't describe everything as long - * as what it does describe doesn't conflict with reality. - */ - - reset_holes = 0; - - bholemap.lost_holes = leaf->hdr.holes; - for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; i++) { - bholemap.hentries[i].base = be16_to_cpu(leaf->hdr.freemap[i].base); - bholemap.hentries[i].size = be16_to_cpu(leaf->hdr.freemap[i].size); - } - - /* - * Ok, now set up our own freespace list - * (XFS_DIR_LEAF_MAPSIZE (3) * biggest regions) - * and see if they match what's in the block - */ - memset(&holemap, 0, sizeof(da_hole_map_t)); - process_da_freemap(mp, dir_freemap, &holemap); - - if (zero_len_entries) { - reset_holes = 1; - } else if (leaf->hdr.holes == 0) { - if (holemap.lost_holes > 0) { - if (verbose) - do_warn( - _("- found unexpected lost holes in block %u, dir inode %" PRIu64 "\n"), - da_bno, ino); - - reset_holes = 1; - } else if (compare_da_freemaps(mp, &holemap, &bholemap, - XFS_DIR_LEAF_MAPSIZE, ino, da_bno)) { - if (verbose) - do_warn( - _("- hole info non-optimal in block %u, dir inode %" PRIu64 "\n"), - da_bno, ino); - reset_holes = 1; - } - } else if (verify_da_freemap(mp, dir_freemap, &holemap, ino, da_bno)) { - if (verbose) - do_warn( - _("- hole info incorrect in block %u, dir inode %" PRIu64 "\n"), - da_bno, ino); - reset_holes = 1; - } - - if (reset_holes) { - /* - * have to reset block hole info - */ - if (verbose) { - do_warn( -_("- existing hole info for block %d, dir inode %" PRIu64 " (base, size) - \n"), - da_bno, ino); - do_warn("- \t"); - for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; i++) { - do_warn( - "- (%d, %d) ", bholemap.hentries[i].base, - bholemap.hentries[i].size); - } - do_warn(_("- holes flag = %d\n"), bholemap.lost_holes); - } - - if (!no_modify) { - if (verbose) - do_warn( - _("- compacting block %u in dir inode %" PRIu64 "\n"), - da_bno, ino); - - new_leaf = malloc(mp->m_sb.sb_blocksize); - - /* - * copy leaf block header - */ - memmove(&new_leaf->hdr, &leaf->hdr, - sizeof(xfs_dir_leaf_hdr_t)); - - /* - * reset count in case we have some zero length entries - * that are being junked - */ - num_entries = 0; - first_used = XFS_LBSIZE(mp); - first_byte = (char *) new_leaf - + (__psint_t) XFS_LBSIZE(mp); - - /* - * copy entry table and pack names starting from the end - * of the block - */ - for (i = 0, s_entry = &leaf->entries[0], - d_entry = &new_leaf->entries[0]; - i < be16_to_cpu(leaf->hdr.count); - i++, s_entry++) { - /* - * skip zero-length entries - */ - if (s_entry->namelen == 0) - continue; - - bytes = sizeof(xfs_dir_leaf_name_t) - + s_entry->namelen - 1; - - if ((__psint_t) first_byte - bytes < - sizeof(xfs_dir_leaf_entry_t) - + (__psint_t) d_entry) { - do_warn( - _("not enough space in block %u of dir inode %" PRIu64 " for all entries\n"), - da_bno, ino); - free(new_leaf); - break; - } - - first_used -= bytes; - first_byte -= bytes; - - d_entry->nameidx = cpu_to_be16(first_used); - d_entry->hashval = s_entry->hashval; - d_entry->namelen = s_entry->namelen; - d_entry->pad2 = 0; - - memmove(first_byte, (char *)leaf + - be16_to_cpu(s_entry->nameidx), bytes); - - num_entries++; - d_entry++; - } - - ASSERT((char *) first_byte >= (char *) d_entry); - ASSERT(first_used <= XFS_LBSIZE(mp)); - - /* - * zero space between end of table and top of heap - */ - memset(d_entry, 0, (__psint_t) first_byte - - (__psint_t) d_entry); - - /* - * reset header info - */ - if (num_entries != be16_to_cpu(new_leaf->hdr.count)) - new_leaf->hdr.count = cpu_to_be16(num_entries); - - new_leaf->hdr.firstused = cpu_to_be16(first_used); - new_leaf->hdr.holes = 0; - new_leaf->hdr.pad1 = 0; - - new_leaf->hdr.freemap[0].base = cpu_to_be16( - (__psint_t) d_entry - (__psint_t) new_leaf); - new_leaf->hdr.freemap[0].size = cpu_to_be16( - (__psint_t) first_byte - (__psint_t) d_entry); - - ASSERT(be16_to_cpu(new_leaf->hdr.freemap[0].base) < first_used); - ASSERT(be16_to_cpu(new_leaf->hdr.freemap[0].base) == - (__psint_t) (&new_leaf->entries[0]) - - (__psint_t) new_leaf - + i * sizeof(xfs_dir_leaf_entry_t)); - ASSERT(be16_to_cpu(new_leaf->hdr.freemap[0].base) < XFS_LBSIZE(mp)); - ASSERT(be16_to_cpu(new_leaf->hdr.freemap[0].size) < XFS_LBSIZE(mp)); - ASSERT(be16_to_cpu(new_leaf->hdr.freemap[0].base) + - be16_to_cpu(new_leaf->hdr.freemap[0].size) == first_used); - - new_leaf->hdr.freemap[1].base = 0; - new_leaf->hdr.freemap[1].size = 0; - new_leaf->hdr.freemap[2].base = 0; - new_leaf->hdr.freemap[2].size = 0; - - /* - * final step, copy block back - */ - memmove(leaf, new_leaf, mp->m_sb.sb_blocksize); - free(new_leaf); - - *buf_dirty = 1; - } else { - if (verbose) - do_warn( - _("- would compact block %u in dir inode %" PRIu64 "\n"), - da_bno, ino); - } - } -#if 0 - if (!no_modify) { - /* - * now take care of deleting or marking the entries with - * zero-length namelen's - */ - junk_zerolen_dir_leaf_entries(mp, leaf, ino, buf_dirty); - } -#endif - -out: - free(dir_freemap); -#ifdef XR_DIR_TRACE - fprintf(stderr, "process_leaf_dir_block returns %d\n", res); -#endif - return res > 0 ? 1 : 0; -} - -/* - * returns 0 if the directory is ok, 1 if it has to be junked. - */ -static int -process_leaf_dir_level(xfs_mount_t *mp, - da_bt_cursor_t *da_cursor, - int ino_discovery, - int *repair, - int *dot, - int *dotdot, - xfs_ino_t *parent) -{ - xfs_dir_leafblock_t *leaf; - xfs_buf_t *bp; - xfs_ino_t ino; - xfs_dfsbno_t dev_bno; - xfs_dablk_t da_bno; - xfs_dablk_t prev_bno; - int res = 0; - int buf_dirty = 0; - xfs_daddr_t bd_addr; - xfs_dahash_t current_hashval = 0; - xfs_dahash_t greatest_hashval; - -#ifdef XR_DIR_TRACE - fprintf(stderr, "process_leaf_dir_level - ino %" PRIu64 "\n", da_cursor->ino); -#endif - *repair = 0; - da_bno = da_cursor->level[0].bno; - ino = da_cursor->ino; - prev_bno = 0; - - do { - dev_bno = blkmap_get(da_cursor->blkmap, da_bno); - /* - * directory code uses 0 as the NULL block pointer - * since 0 is the root block and no directory block - * pointer can point to the root block of the btree - */ - ASSERT(da_bno != 0); - - if (dev_bno == NULLDFSBNO) { - do_warn( - _("can't map block %u for directory inode %" PRIu64 "\n"), - da_bno, ino); - goto error_out; - } - - bd_addr = (xfs_daddr_t)XFS_FSB_TO_DADDR(mp, dev_bno); - - bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, dev_bno), - XFS_FSB_TO_BB(mp, 1), 0); - if (!bp) { - do_warn( - _("can't read file block %u (fsbno %" PRIu64 ", daddr %" PRId64 ") " - "for directory inode %" PRIu64 "\n"), - da_bno, dev_bno, bd_addr, ino); - goto error_out; - } - - leaf = (xfs_dir_leafblock_t *)XFS_BUF_PTR(bp); - - /* - * check magic number for leaf directory btree block - */ - if (XFS_DIR_LEAF_MAGIC != - be16_to_cpu(leaf->hdr.info.magic)) { - do_warn( - _("bad directory leaf magic # %#x for dir ino %" PRIu64"\n"), - be16_to_cpu(leaf->hdr.info.magic), - ino); - libxfs_putbuf(bp); - goto error_out; - } - /* - * keep track of greatest block # -- that gets - * us the length of the directory - */ - if (da_bno > da_cursor->greatest_bno) - da_cursor->greatest_bno = da_bno; - - buf_dirty = 0; - /* - * for each block, process the block, verify its path, - * then get next block. update cursor values along the way - */ - if (process_leaf_dir_block(mp, leaf, da_bno, ino, - current_hashval, ino_discovery, - da_cursor->blkmap, dot, dotdot, parent, - &buf_dirty, &greatest_hashval)) { - libxfs_putbuf(bp); - goto error_out; - } - - /* - * index can be set to hdr.count so match the - * indexes of the interior blocks -- which at the - * end of the block will point to 1 after the final - * real entry in the block - */ - da_cursor->level[0].hashval = greatest_hashval; - da_cursor->level[0].bp = bp; - da_cursor->level[0].bno = da_bno; - da_cursor->level[0].index = be16_to_cpu(leaf->hdr.count); - da_cursor->level[0].dirty = buf_dirty; - - if (be32_to_cpu(leaf->hdr.info.back) != prev_bno) { - do_warn( - _("bad sibling back pointer for directory block %u in directory inode %" PRIu64 "\n"), - da_bno, ino); - libxfs_putbuf(bp); - goto error_out; - } - - prev_bno = da_bno; - da_bno = be32_to_cpu(leaf->hdr.info.forw); - - if (da_bno != 0) - if (verify_da_path(mp, da_cursor, 0)) { - libxfs_putbuf(bp); - goto error_out; - } - - current_hashval = greatest_hashval; - - ASSERT(buf_dirty == 0 || (buf_dirty && !no_modify)); - - if (buf_dirty && !no_modify) { - *repair = 1; - libxfs_writebuf(bp, 0); - } - else - libxfs_putbuf(bp); - } while (da_bno != 0 && res == 0); - - if (verify_final_da_path(mp, da_cursor, 0)) { - /* - * verify the final path up (right-hand-side) if still ok - */ - do_warn(_("bad hash path in directory %" PRIu64 "\n"), da_cursor->ino); - goto error_out; - } - -#ifdef XR_DIR_TRACE - fprintf(stderr, "process_leaf_dir_level returns %d (%s)\n", - res, ((res) ? "bad" : "ok")); -#endif - /* - * redundant but just for testing - */ - release_da_cursor(mp, da_cursor, 0); - - return(res); - -error_out: - /* - * release all buffers holding interior btree blocks - */ - err_release_da_cursor(mp, da_cursor, 0); - - return(1); -} - -/* - * a node directory is a true btree directory -- where the directory - * has gotten big enough that it is represented as a non-trivial (e.g. - * has more than just a root block) btree. - * - * Note that if we run into any problems, we trash the - * directory. Even if it's the root directory, - * we'll be able to traverse all the disconnected - * subtrees later (phase 6). - * - * one day, if we actually fix things, we'll set repair to 1 to - * indicate that we have or that we should. - * - * dirname can be set to NULL if the name is unknown (or to - * the string representation of the inode) - * - * returns 0 if things are ok, 1 if bad (directory needs to be junked) - */ -static int -process_node_dir( - xfs_mount_t *mp, - xfs_ino_t ino, - xfs_dinode_t *dip, - int ino_discovery, - blkmap_t *blkmap, - int *dot, - int *dotdot, - xfs_ino_t *parent, /* out - parent ino # or NULLFSINO */ - char *dirname, - int *repair) -{ - xfs_dablk_t bno; - int error = 0; - da_bt_cursor_t da_cursor; - -#ifdef XR_DIR_TRACE - fprintf(stderr, "process_node_dir - ino %" PRIu64 "\n", ino); -#endif - *repair = *dot = *dotdot = 0; - *parent = NULLFSINO; - - /* - * try again -- traverse down left-side of tree until we hit - * the left-most leaf block setting up the btree cursor along - * the way. Then walk the leaf blocks left-to-right, calling - * a parent-verification routine each time we traverse a block. - */ - memset(&da_cursor, 0, sizeof(da_bt_cursor_t)); - - da_cursor.active = 0; - da_cursor.type = 0; - da_cursor.ino = ino; - da_cursor.dip = dip; - da_cursor.greatest_bno = 0; - da_cursor.blkmap = blkmap; - - /* - * now process interior node - */ - - error = traverse_int_dablock(mp, &da_cursor, &bno, XFS_DATA_FORK); - - if (error == 0) - return(1); - - /* - * now pass cursor and bno into leaf-block processing routine - * the leaf dir level routine checks the interior paths - * up to the root including the final right-most path. - */ - - error = process_leaf_dir_level(mp, &da_cursor, ino_discovery, - repair, dot, dotdot, parent); - - if (error) - return(1); - - /* - * sanity check inode size - */ - if (be64_to_cpu(dip->di_size) < - (da_cursor.greatest_bno + 1) * mp->m_sb.sb_blocksize) { - if ((xfs_fsize_t) da_cursor.greatest_bno - * mp->m_sb.sb_blocksize > UINT_MAX) { - do_warn( -_("out of range internal directory block numbers (inode %" PRIu64 ")\n"), - ino); - return(1); - } - - do_warn( -_("setting directory inode (%" PRIu64 ") size to %" PRIu64 " bytes, was %" PRId64 " bytes\n"), - ino, (xfs_dfiloff_t) (da_cursor.greatest_bno + 1) - * mp->m_sb.sb_blocksize, - (__int64_t)be64_to_cpu(dip->di_size)); - - dip->di_size = cpu_to_be64((da_cursor.greatest_bno + 1) - * mp->m_sb.sb_blocksize); - } - return(0); -} - -/* - * a leaf directory is one where the directory is too big for - * the inode data fork but is small enough to fit into one - * directory btree block (filesystem block) outside the inode - * - * returns NULLFSINO if the directory is cannot be salvaged - * and the .. ino if things are ok (even if the directory had - * to be altered to make it ok). - * - * dirname can be set to NULL if the name is unknown (or to - * the string representation of the inode) - * - * returns 0 if things are ok, 1 if bad (directory needs to be junked) - */ -static int -process_leaf_dir( - xfs_mount_t *mp, - xfs_ino_t ino, - xfs_dinode_t *dip, - int ino_discovery, - int *dino_dirty, - blkmap_t *blkmap, - int *dot, /* out - 1 if there is a dot, else 0 */ - int *dotdot, /* out - 1 if there's a dotdot, else 0 */ - xfs_ino_t *parent, /* out - parent ino # or NULLFSINO */ - char *dirname, /* in - directory pathname */ - int *repair) /* out - 1 if something was fixed */ -{ - xfs_dir_leafblock_t *leaf; - xfs_dahash_t next_hashval; - xfs_dfsbno_t bno; - xfs_buf_t *bp; - int buf_dirty = 0; - -#ifdef XR_DIR_TRACE - fprintf(stderr, "process_leaf_dir - ino %" PRIu64 "\n", ino); -#endif - *repair = *dot = *dotdot = 0; - *parent = NULLFSINO; - - bno = blkmap_get(blkmap, 0); - if (bno == NULLDFSBNO) { - do_warn(_("block 0 for directory inode %" PRIu64 " is missing\n"), - ino); - return(1); - } - bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno), - XFS_FSB_TO_BB(mp, 1), 0); - if (!bp) { - do_warn(_("can't read block 0 for directory inode %" PRIu64 "\n"), - ino); - return(1); - } - /* - * verify leaf block - */ - leaf = (xfs_dir_leafblock_t *)XFS_BUF_PTR(bp); - - /* - * check magic number for leaf directory btree block - */ - if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) { - do_warn(_("bad directory leaf magic # %#x for dir ino %" PRIu64 "\n"), - be16_to_cpu(leaf->hdr.info.magic), ino); - libxfs_putbuf(bp); - return(1); - } - - if (process_leaf_dir_block(mp, leaf, 0, ino, 0, ino_discovery, blkmap, - dot, dotdot, parent, &buf_dirty, &next_hashval)) { - /* - * the block is bad. lose the directory. - * XXX - later, we should try and just lose - * the block without losing the entire directory - */ - ASSERT(*dotdot == 0 || (*dotdot == 1 && *parent != NULLFSINO)); - libxfs_putbuf(bp); - return(1); - } - - /* - * check sibling pointers in leaf block (above doesn't do it) - */ - if (leaf->hdr.info.forw || leaf->hdr.info.back) { - if (!no_modify) { - do_warn(_("clearing forw/back pointers for " - "directory inode %" PRIu64 "\n"), ino); - buf_dirty = 1; - leaf->hdr.info.forw = 0; - leaf->hdr.info.back = 0; - } else { - do_warn(_("would clear forw/back pointers for " - "directory inode %" PRIu64 "\n"), ino); - } - } - - ASSERT(buf_dirty == 0 || (buf_dirty && !no_modify)); - - if (buf_dirty && !no_modify) - libxfs_writebuf(bp, 0); - else - libxfs_putbuf(bp); - - return(0); -} - -/* - * returns 1 if things are bad (directory needs to be junked) - * and 0 if things are ok. If ino_discovery is 1, add unknown - * inodes to uncertain inode list. - */ -int -process_dir( - xfs_mount_t *mp, - xfs_ino_t ino, - xfs_dinode_t *dip, - int ino_discovery, - int *dino_dirty, - char *dirname, - xfs_ino_t *parent, - blkmap_t *blkmap) -{ - int dot; - int dotdot; - int repair = 0; - int res = 0; - - *parent = NULLFSINO; - dot = dotdot = 0; - - /* - * branch off depending on the type of inode. This routine - * is only called ONCE so all the subordinate routines will - * fix '.' and junk '..' if they're bogus. - */ - if (be64_to_cpu(dip->di_size) <= XFS_DFORK_DSIZE(dip, mp)) { - dot = 1; - dotdot = 1; - if (process_shortform_dir(mp, ino, dip, ino_discovery, - dino_dirty, parent, dirname, &repair)) - res = 1; - } else if (be64_to_cpu(dip->di_size) <= XFS_LBSIZE(mp)) { - if (process_leaf_dir(mp, ino, dip, ino_discovery, - dino_dirty, blkmap, &dot, &dotdot, - parent, dirname, &repair)) - res = 1; - } else { - if (process_node_dir(mp, ino, dip, ino_discovery, - blkmap, &dot, &dotdot, - parent, dirname, &repair)) - res = 1; - } - /* - * bad . entries in all directories will be fixed up in phase 6 - */ - if (dot == 0) - do_warn(_("no . entry for directory %" PRIu64 "\n"), ino); - - /* - * shortform dirs always have a .. entry. .. for all longform - * directories will get fixed in phase 6. .. for other shortform - * dirs also get fixed there. .. for a shortform root was - * fixed in place since we know what it should be - */ - if (dotdot == 0 && ino != mp->m_sb.sb_rootino) { - do_warn(_("no .. entry for directory %" PRIu64 "\n"), ino); - } else if (dotdot == 0 && ino == mp->m_sb.sb_rootino) { - do_warn(_("no .. entry for root directory %" PRIu64 "\n"), ino); - need_root_dotdot = 1; - } - -#ifdef XR_DIR_TRACE - fprintf(stderr, "(process_dir), parent of %" PRIu64 " is %" PRIu64 "\n", ino, parent); -#endif - return(res); -} diff -Nru xfsprogs-3.1.9ubuntu2/repair/dir.h xfsprogs-3.2.1ubuntu1/repair/dir.h --- xfsprogs-3.1.9ubuntu2/repair/dir.h 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/dir.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _XR_DIR_H -#define _XR_DIR_H - -struct blkmap; - -typedef unsigned char da_freemap_t; - -/* - * the cursor gets passed up and down the da btree processing - * routines. The interior block processing routines use the - * cursor to determine if the pointers to and from the preceding - * and succeeding sibling blocks are ok and whether the values in - * the current block are consistent with the entries in the parent - * nodes. When a block is traversed, a parent-verification routine - * is called to verify if the next logical entry in the next level up - * is consistent with the greatest hashval in the next block of the - * current level. The verification routine is itself recursive and - * calls itself if it has to traverse an interior block to get - * the next logical entry. The routine recurses upwards through - * the tree until it finds a block where it can simply step to - * the next entry. The hashval in that entry should be equal to - * the hashval being passed to it (the greatest hashval in the block - * that the entry points to). If that isn't true, then the tree - * is blown and we need to trash it, salvage and trash it, or fix it. - * Currently, we just trash it. - */ -typedef struct da_level_state { - xfs_buf_t *bp; /* block bp */ -#ifdef XR_DIR_TRACE - xfs_da_intnode_t *n; /* bp data */ -#endif - xfs_dablk_t bno; /* file block number */ - xfs_dahash_t hashval; /* last verified hashval */ - int index; /* current index in block */ - int dirty; /* is buffer dirty ? (1 == yes) */ -} da_level_state_t; - -typedef struct da_bt_cursor { - int active; /* highest level in tree (# levels-1) */ - int type; /* 0 if dir, 1 if attr */ - xfs_ino_t ino; - xfs_dablk_t greatest_bno; - xfs_dinode_t *dip; - da_level_state_t level[XFS_DA_NODE_MAXDEPTH]; - struct blkmap *blkmap; -} da_bt_cursor_t; - - -/* ROUTINES */ - -void -err_release_da_cursor( - xfs_mount_t *mp, - da_bt_cursor_t *cursor, - int prev_level); - -da_freemap_t * -alloc_da_freemap( - xfs_mount_t *mp); - -int -namecheck( - char *name, - int length); - -int -process_dir( - xfs_mount_t *mp, - xfs_ino_t ino, - xfs_dinode_t *dip, - int ino_discovery, - int *dirty, - char *dirname, - xfs_ino_t *parent, - struct blkmap *blkmap); - -void -release_da_cursor( - xfs_mount_t *mp, - da_bt_cursor_t *cursor, - int prev_level); - -int -set_da_freemap( - xfs_mount_t *mp, da_freemap_t *map, - int start, int stop); - -int -traverse_int_dablock( - xfs_mount_t *mp, - da_bt_cursor_t *da_cursor, - xfs_dablk_t *rbno, - int whichfork); - -int -verify_da_path( - xfs_mount_t *mp, - da_bt_cursor_t *cursor, - const int p_level); - -int -verify_final_da_path( - xfs_mount_t *mp, - da_bt_cursor_t *cursor, - const int p_level); - - -#endif /* _XR_DIR_H */ diff -Nru xfsprogs-3.1.9ubuntu2/repair/globals.h xfsprogs-3.2.1ubuntu1/repair/globals.h --- xfsprogs-3.1.9ubuntu2/repair/globals.h 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/globals.h 2014-07-21 09:15:17.000000000 +0000 @@ -49,7 +49,8 @@ #define XR_BAD_SB_UNIT 17 /* bad stripe unit */ #define XR_BAD_SB_WIDTH 18 /* bad stripe width */ #define XR_BAD_SVN 19 /* bad shared version number */ -#define XR_BAD_ERR_CODE 20 /* Bad error code */ +#define XR_BAD_CRC 20 /* Bad CRC */ +#define XR_BAD_ERR_CODE 21 /* Bad error code */ /* XFS filesystem (il)legal values */ @@ -137,6 +138,7 @@ EXTERN int lost_quotas; EXTERN int have_uquotino; EXTERN int have_gquotino; +EXTERN int have_pquotino; EXTERN int lost_uquotino; EXTERN int lost_gquotino; EXTERN int lost_pquotino; @@ -185,7 +187,10 @@ EXTERN __uint32_t sb_unit; EXTERN __uint32_t sb_width; -EXTERN pthread_mutex_t *ag_locks; +struct aglock { + pthread_mutex_t lock __attribute__((__aligned__(64))); +}; +EXTERN struct aglock *ag_locks; EXTERN int report_interval; EXTERN __uint64_t *prog_rpt_done; diff -Nru xfsprogs-3.1.9ubuntu2/repair/incore.c xfsprogs-3.2.1ubuntu1/repair/incore.c --- xfsprogs-3.1.9ubuntu2/repair/incore.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/incore.c 2014-05-02 00:09:16.000000000 +0000 @@ -294,13 +294,13 @@ if (!ag_bmap) do_error(_("couldn't allocate block map btree roots\n")); - ag_locks = calloc(mp->m_sb.sb_agcount, sizeof(pthread_mutex_t)); + ag_locks = calloc(mp->m_sb.sb_agcount, sizeof(struct aglock)); if (!ag_locks) do_error(_("couldn't allocate block map locks\n")); for (i = 0; i < mp->m_sb.sb_agcount; i++) { btree_init(&ag_bmap[i]); - pthread_mutex_init(&ag_locks[i], NULL); + pthread_mutex_init(&ag_locks[i].lock, NULL); } init_rt_bmap(mp); diff -Nru xfsprogs-3.1.9ubuntu2/repair/incore.h xfsprogs-3.2.1ubuntu1/repair/incore.h --- xfsprogs-3.1.9ubuntu2/repair/incore.h 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/incore.h 2014-06-19 22:42:17.000000000 +0000 @@ -293,6 +293,7 @@ ino_ex_data_t *ex_data; /* phases 6,7 */ parent_list_t *plist; /* phases 2-5 */ } ino_un; + __uint8_t *ftypes; /* phases 3,6 */ } ino_tree_node_t; #define INOS_PER_IREC (sizeof(__uint64_t) * NBBY) @@ -359,7 +360,8 @@ xfs_agino_t ino); void add_inode_uncertain(xfs_mount_t *mp, xfs_ino_t ino, int free); -void add_aginode_uncertain(xfs_agnumber_t agno, +void add_aginode_uncertain(struct xfs_mount *mp, + xfs_agnumber_t agno, xfs_agino_t agino, int free); void get_uncertain_inode_rec(struct xfs_mount *mp, xfs_agnumber_t agno, @@ -379,6 +381,33 @@ ((ino_tree_node_t *) ((ino_node_ptr)->avl_node.avl_forw)) /* + * finobt helpers + */ +static inline ino_tree_node_t * +findfirst_free_inode_rec(xfs_agnumber_t agno) +{ + ino_tree_node_t *ino_rec; + + ino_rec = findfirst_inode_rec(agno); + + while (ino_rec && !ino_rec->ir_free) + ino_rec = next_ino_rec(ino_rec); + + return ino_rec; +} + +static inline ino_tree_node_t * +next_free_ino_rec(ino_tree_node_t *ino_rec) +{ + ino_rec = next_ino_rec(ino_rec); + + while (ino_rec && !ino_rec->ir_free) + ino_rec = next_ino_rec(ino_rec); + + return ino_rec; +} + +/* * Has an inode been processed for phase 6 (reference count checking)? * * add_inode_refchecked() is set on an inode when it gets traversed @@ -476,6 +505,29 @@ } /* + * get/set inode filetype. Only used if the superblock feature bit is set + * which allocates irec->ftypes. + */ +static inline void +set_inode_ftype(struct ino_tree_node *irec, + int ino_offset, + __uint8_t ftype) +{ + if (irec->ftypes) + irec->ftypes[ino_offset] = ftype; +} + +static inline __uint8_t +get_inode_ftype( + struct ino_tree_node *irec, + int ino_offset) +{ + if (!irec->ftypes) + return XFS_DIR3_FT_UNKNOWN; + return irec->ftypes[ino_offset]; +} + +/* * set/get inode number of parent -- works for directory inodes only */ void set_inode_parent(ino_tree_node_t *irec, int ino_offset, @@ -483,6 +535,11 @@ xfs_ino_t get_inode_parent(ino_tree_node_t *irec, int ino_offset); /* + * Allocate extra inode data + */ +void alloc_ex_data(ino_tree_node_t *irec); + +/* * bmap cursor for tracking and fixing bmap btrees. All xfs btrees number * the levels with 0 being the leaf and every level up being 1 greater. */ diff -Nru xfsprogs-3.1.9ubuntu2/repair/incore_ino.c xfsprogs-3.2.1ubuntu1/repair/incore_ino.c --- xfsprogs-3.1.9ubuntu2/repair/incore_ino.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/incore_ino.c 2014-05-02 00:09:16.000000000 +0000 @@ -167,6 +167,7 @@ default: ASSERT(0); } + return 0; } void set_inode_disk_nlinks(struct ino_tree_node *irec, int ino_offset, @@ -207,6 +208,22 @@ default: ASSERT(0); } + return 0; +} + +static __uint8_t * +alloc_ftypes_array( + struct xfs_mount *mp) +{ + __uint8_t *ptr; + + if (!xfs_sb_version_hasftype(&mp->m_sb)) + return NULL; + + ptr = calloc(XFS_INODES_PER_CHUNK, sizeof(*ptr)); + if (!ptr) + do_error(_("could not allocate ftypes array\n")); + return ptr; } /* @@ -224,6 +241,7 @@ */ static struct ino_tree_node * alloc_ino_node( + struct xfs_mount *mp, xfs_agino_t starting_ino) { struct ino_tree_node *irec; @@ -243,6 +261,7 @@ irec->ino_un.ex_data = NULL; irec->nlink_size = sizeof(__uint8_t); irec->disk_nlinks.un8 = alloc_nlink_array(irec->nlink_size); + irec->ftypes = alloc_ftypes_array(mp); return irec; } @@ -283,6 +302,7 @@ } + free(irec->ftypes); free(irec); } @@ -301,7 +321,11 @@ * free is set to 1 if the inode is thought to be free, 0 if used */ void -add_aginode_uncertain(xfs_agnumber_t agno, xfs_agino_t ino, int free) +add_aginode_uncertain( + struct xfs_mount *mp, + xfs_agnumber_t agno, + xfs_agino_t ino, + int free) { ino_tree_node_t *ino_rec; xfs_agino_t s_ino; @@ -332,7 +356,7 @@ ino_rec = (ino_tree_node_t *) avl_findrange(inode_uncertain_tree_ptrs[agno], s_ino); if (!ino_rec) { - ino_rec = alloc_ino_node(s_ino); + ino_rec = alloc_ino_node(mp, s_ino); if (!avl_insert(inode_uncertain_tree_ptrs[agno], &ino_rec->avl_node)) @@ -358,7 +382,7 @@ void add_inode_uncertain(xfs_mount_t *mp, xfs_ino_t ino, int free) { - add_aginode_uncertain(XFS_INO_TO_AGNO(mp, ino), + add_aginode_uncertain(mp, XFS_INO_TO_AGNO(mp, ino), XFS_INO_TO_AGINO(mp, ino), free); } @@ -430,7 +454,7 @@ { struct ino_tree_node *irec; - irec = alloc_ino_node(agino); + irec = alloc_ino_node(mp, agino); if (!avl_insert(inode_tree_ptrs[agno], &irec->avl_node)) do_warn(_("add_inode - duplicate inode range\n")); return irec; @@ -700,7 +724,7 @@ return(0LL); } -static void +void alloc_ex_data(ino_tree_node_t *irec) { parent_list_t *ptbl; diff -Nru xfsprogs-3.1.9ubuntu2/repair/init.c xfsprogs-3.2.1ubuntu1/repair/init.c --- xfsprogs-3.1.9ubuntu2/repair/init.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/init.c 2014-05-02 00:09:16.000000000 +0000 @@ -23,7 +23,6 @@ #include "err_protos.h" #include "pthread.h" #include "avl.h" -#include "dir.h" #include "bmap.h" #include "incore.h" #include "prefetch.h" @@ -98,8 +97,17 @@ else args->isreadonly = LIBXFS_EXCLUSIVELY; - if (!libxfs_init(args)) + if (!libxfs_init(args)) { + /* would -d be an option? */ + if (!no_modify && !dangerously) { + args->isreadonly = (LIBXFS_ISINACTIVE | + LIBXFS_DANGEROUSLY); + if (libxfs_init(args)) + fprintf(stderr, +_("Unmount or use the dangerous (-d) option to repair a read-only mounted filesystem\n")); + } do_error(_("couldn't initialize XFS library\n")); + } ts_create(); increase_rlimit(); diff -Nru xfsprogs-3.1.9ubuntu2/repair/Makefile xfsprogs-3.2.1ubuntu1/repair/Makefile --- xfsprogs-3.1.9ubuntu2/repair/Makefile 2010-01-28 09:49:03.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/Makefile 2013-06-06 22:52:59.000000000 +0000 @@ -10,11 +10,11 @@ LTCOMMAND = xfs_repair HFILES = agheader.h attr_repair.h avl.h avl64.h bmap.h btree.h \ - dinode.h dir.h dir2.h err_protos.h globals.h incore.h protos.h rt.h \ + dinode.h dir2.h err_protos.h globals.h incore.h protos.h rt.h \ progress.h scan.h versions.h prefetch.h threads.h CFILES = agheader.c attr_repair.c avl.c avl64.c bmap.c btree.c \ - dino_chunks.c dinode.c dir.c dir2.c globals.c incore.c \ + dino_chunks.c dinode.c dir2.c globals.c incore.c \ incore_bmc.c init.c incore_ext.c incore_ino.c phase1.c \ phase2.c phase3.c phase4.c phase5.c phase6.c phase7.c \ progress.c prefetch.c rt.c sb.c scan.c threads.c \ diff -Nru xfsprogs-3.1.9ubuntu2/repair/phase1.c xfsprogs-3.2.1ubuntu1/repair/phase1.c --- xfsprogs-3.1.9ubuntu2/repair/phase1.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/phase1.c 2014-05-02 00:09:16.000000000 +0000 @@ -70,13 +70,14 @@ ag_bp = alloc_ag_buf(MAX_SECTSIZE); sb = (xfs_sb_t *) ag_bp; - if (get_sb(sb, 0LL, MAX_SECTSIZE, 0) == XR_EOF) + rval = get_sb(sb, 0LL, MAX_SECTSIZE, 0); + if (rval == XR_EOF) do_error(_("error reading primary superblock\n")); /* * is this really an sb, verify internal consistency */ - if ((rval = verify_sb(sb, 1)) != XR_OK) { + if (rval != XR_OK) { do_warn(_("bad primary superblock - %s !!!\n"), err_string(rval)); if (!find_secondary_sb(sb)) diff -Nru xfsprogs-3.1.9ubuntu2/repair/phase2.c xfsprogs-3.2.1ubuntu1/repair/phase2.c --- xfsprogs-3.1.9ubuntu2/repair/phase2.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/phase2.c 2014-05-02 00:09:16.000000000 +0000 @@ -29,26 +29,30 @@ void set_mp(xfs_mount_t *mpp); /* workaround craziness in the xlog routines */ -int xlog_recover_do_trans(xlog_t *log, xlog_recover_t *t, int p) { return 0; } +int xlog_recover_do_trans(struct xlog *log, xlog_recover_t *t, int p) +{ + return 0; +} static void zero_log(xfs_mount_t *mp) { int error; - xlog_t log; + struct xlog log; xfs_daddr_t head_blk, tail_blk; - dev_t logdev = (mp->m_sb.sb_logstart == 0) ? x.logdev : x.ddev; memset(&log, 0, sizeof(log)); - if (!x.logdev) - x.logdev = x.ddev; x.logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); x.logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart); + x.lbsize = BBSIZE; + if (xfs_sb_version_hassector(&mp->m_sb)) + x.lbsize <<= (mp->m_sb.sb_logsectlog - BBSHIFT); - log.l_dev = logdev; + log.l_dev = mp->m_logdev_targp; log.l_logsize = BBTOB(x.logBBsize); log.l_logBBsize = x.logBBsize; log.l_logBBstart = x.logBBstart; + log.l_sectBBsize = BTOBB(x.lbsize); log.l_mp = mp; if (xfs_sb_version_hassector(&mp->m_sb)) { log.l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT; @@ -89,7 +93,7 @@ } } - libxfs_log_clear(logdev, + libxfs_log_clear(log.l_dev, XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), &mp->m_sb.sb_uuid, diff -Nru xfsprogs-3.1.9ubuntu2/repair/phase3.c xfsprogs-3.2.1ubuntu1/repair/phase3.c --- xfsprogs-3.1.9ubuntu2/repair/phase3.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/phase3.c 2014-05-02 00:09:16.000000000 +0000 @@ -17,6 +17,8 @@ */ #include +#include "threads.h" +#include "prefetch.h" #include "avl.h" #include "globals.h" #include "agheader.h" @@ -24,9 +26,7 @@ #include "protos.h" #include "err_protos.h" #include "dinode.h" -#include "threads.h" #include "progress.h" -#include "prefetch.h" static void process_agi_unlinked( @@ -40,7 +40,7 @@ bp = libxfs_readbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), - mp->m_sb.sb_sectsize/BBSIZE, 0); + mp->m_sb.sb_sectsize/BBSIZE, 0, &xfs_agi_buf_ops); if (!bp) do_error(_("cannot read agi block %" PRId64 " for ag %u\n"), XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), agno); @@ -82,41 +82,7 @@ process_ags( xfs_mount_t *mp) { - int i, j; - xfs_agnumber_t agno; - work_queue_t *queues; - prefetch_args_t *pf_args[2]; - - queues = malloc(thread_count * sizeof(work_queue_t)); - - if (ag_stride) { - /* - * create one worker thread for each segment of the volume - */ - for (i = 0, agno = 0; i < thread_count; i++) { - create_work_queue(&queues[i], mp, 1); - pf_args[0] = NULL; - for (j = 0; j < ag_stride && agno < mp->m_sb.sb_agcount; - j++, agno++) { - pf_args[0] = start_inode_prefetch(agno, 0, pf_args[0]); - queue_work(&queues[i], process_ag_func, agno, pf_args[0]); - } - } - /* - * wait for workers to complete - */ - for (i = 0; i < thread_count; i++) - destroy_work_queue(&queues[i]); - } else { - queues[0].mp = mp; - pf_args[0] = start_inode_prefetch(0, 0, NULL); - for (i = 0; i < mp->m_sb.sb_agcount; i++) { - pf_args[(~i) & 1] = start_inode_prefetch(i + 1, 0, - pf_args[i & 1]); - process_ag_func(&queues[0], i, pf_args[i & 1]); - } - } - free(queues); + do_inode_prefetch(mp, ag_stride, process_ag_func, false, false); } void diff -Nru xfsprogs-3.1.9ubuntu2/repair/phase4.c xfsprogs-3.2.1ubuntu1/repair/phase4.c --- xfsprogs-3.1.9ubuntu2/repair/phase4.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/phase4.c 2014-05-02 00:09:16.000000000 +0000 @@ -17,6 +17,8 @@ */ #include +#include "threads.h" +#include "prefetch.h" #include "avl.h" #include "globals.h" #include "agheader.h" @@ -24,13 +26,10 @@ #include "protos.h" #include "err_protos.h" #include "dinode.h" -#include "dir.h" #include "bmap.h" #include "versions.h" #include "dir2.h" -#include "threads.h" #include "progress.h" -#include "prefetch.h" /* @@ -72,12 +71,25 @@ if (irec == NULL || is_inode_free(irec, mp->m_sb.sb_gquotino - irec->ino_startnum)) { mp->m_sb.sb_gquotino = NULLFSINO; - if (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) - lost_gquotino = 1; - else - lost_pquotino = 1; + lost_gquotino = 1; } else - lost_gquotino = lost_pquotino = 0; + lost_gquotino = 0; + } + + if (mp->m_sb.sb_pquotino != NULLFSINO && mp->m_sb.sb_pquotino != 0) { + if (verify_inum(mp, mp->m_sb.sb_pquotino)) + irec = NULL; + else + irec = find_inode_rec(mp, + XFS_INO_TO_AGNO(mp, mp->m_sb.sb_pquotino), + XFS_INO_TO_AGINO(mp, mp->m_sb.sb_pquotino)); + + if (irec == NULL || is_inode_free(irec, + mp->m_sb.sb_pquotino - irec->ino_startnum)) { + mp->m_sb.sb_pquotino = NULLFSINO; + lost_pquotino = 1; + } else + lost_pquotino = 0; } } @@ -105,11 +117,13 @@ if (fs_quotas && (mp->m_sb.sb_uquotino == NULLFSINO || mp->m_sb.sb_uquotino == 0) && - (mp->m_sb.sb_gquotino == NULLFSINO || mp->m_sb.sb_gquotino == 0)) { + (mp->m_sb.sb_gquotino == NULLFSINO || mp->m_sb.sb_gquotino == 0) && + (mp->m_sb.sb_pquotino == NULLFSINO || mp->m_sb.sb_pquotino == 0)) { lost_quotas = 1; fs_quotas = 0; } else if (!verify_inum(mp, mp->m_sb.sb_uquotino) && - !verify_inum(mp, mp->m_sb.sb_gquotino)) { + !verify_inum(mp, mp->m_sb.sb_gquotino) && + !verify_inum(mp, mp->m_sb.sb_pquotino)) { fs_quotas = 1; } } @@ -136,49 +150,7 @@ process_ags( xfs_mount_t *mp) { - int i, j; - xfs_agnumber_t agno; - work_queue_t *queues; - prefetch_args_t *pf_args[2]; - - queues = malloc(thread_count * sizeof(work_queue_t)); - - if (!libxfs_bcache_overflowed()) { - queues[0].mp = mp; - create_work_queue(&queues[0], mp, libxfs_nproc()); - for (i = 0; i < mp->m_sb.sb_agcount; i++) - queue_work(&queues[0], process_ag_func, i, NULL); - destroy_work_queue(&queues[0]); - } else { - if (ag_stride) { - /* - * create one worker thread for each segment of the volume - */ - for (i = 0, agno = 0; i < thread_count; i++) { - create_work_queue(&queues[i], mp, 1); - pf_args[0] = NULL; - for (j = 0; j < ag_stride && agno < mp->m_sb.sb_agcount; - j++, agno++) { - pf_args[0] = start_inode_prefetch(agno, 0, pf_args[0]); - queue_work(&queues[i], process_ag_func, agno, pf_args[0]); - } - } - /* - * wait for workers to complete - */ - for (i = 0; i < thread_count; i++) - destroy_work_queue(&queues[i]); - } else { - queues[0].mp = mp; - pf_args[0] = start_inode_prefetch(0, 0, NULL); - for (i = 0; i < mp->m_sb.sb_agcount; i++) { - pf_args[(~i) & 1] = start_inode_prefetch(i + 1, - 0, pf_args[i & 1]); - process_ag_func(&queues[0], i, pf_args[i & 1]); - } - } - } - free(queues); + do_inode_prefetch(mp, ag_stride, process_ag_func, true, false); } diff -Nru xfsprogs-3.1.9ubuntu2/repair/phase5.c xfsprogs-3.2.1ubuntu1/repair/phase5.c --- xfsprogs-3.1.9ubuntu2/repair/phase5.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/phase5.c 2014-06-19 22:42:17.000000000 +0000 @@ -74,6 +74,15 @@ bt_stat_level_t level[XFS_BTREE_MAXLEVELS]; } bt_status_t; +/* + * extra metadata for the agi + */ +struct agi_stat { + xfs_agino_t first_agino; + xfs_agino_t count; + xfs_agino_t freecount; +}; + static __uint64_t *sb_icount_ag; /* allocated inodes per ag */ static __uint64_t *sb_ifree_ag; /* free inodes per ag */ static __uint64_t *sb_fdblocks_ag; /* free data blocks per ag */ @@ -153,7 +162,6 @@ /* * free extent ends here */ - in_extent = 0; #if defined(XR_BLD_FREE_TRACE) && defined(XR_BLD_ADD_EXTENT) fprintf(stderr, "adding extent %u [%u %u]\n", agno, extent_start, extent_len); @@ -206,7 +214,7 @@ ASSERT(big_extent_len > 0); - if ((curs->btree_blocks = malloc(sizeof(xfs_agblock_t *) + if ((curs->btree_blocks = malloc(sizeof(xfs_agblock_t) * big_extent_len)) == NULL) do_error(_("could not set up btree block array\n")); @@ -223,7 +231,6 @@ do_error(_("error - not enough free space in filesystem\n")); agb_ptr = curs->btree_blocks; - j = curs->level[0].num_blocks; /* * set up the free block array @@ -438,7 +445,6 @@ do_error(_("can't rebuild fs trees -- not enough free space " "on ag %u\n"), agno); - i = 0; while (ext_ptr != NULL && blocks_needed > 0) { if (ext_ptr->ex_blockcount <= blocks_needed) { blocks_needed -= ext_ptr->ex_blockcount; @@ -602,6 +608,12 @@ xfs_alloc_ptr_t *bt_ptr; xfs_agblock_t agbno; bt_stat_level_t *lptr; + __uint32_t crc_magic; + + if (magic == XFS_ABTB_MAGIC) + crc_magic = XFS_ABTB_CRC_MAGIC; + else + crc_magic = XFS_ABTC_CRC_MAGIC; level++; @@ -650,14 +662,17 @@ /* * initialize block header */ + lptr->buf_p->b_ops = &xfs_allocbt_buf_ops; bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); + if (xfs_sb_version_hascrc(&mp->m_sb)) + xfs_btree_init_block(mp, lptr->buf_p, crc_magic, level, + 0, agno, XFS_BTREE_CRC_BLOCKS); + else + xfs_btree_init_block(mp, lptr->buf_p, magic, level, + 0, agno, 0); - bt_hdr->bb_magic = cpu_to_be32(magic); - bt_hdr->bb_level = cpu_to_be16(level); bt_hdr->bb_u.s.bb_leftsib = cpu_to_be32(lptr->prev_agbno); - bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); - bt_hdr->bb_numrecs = 0; /* * propagate extent record for first extent in new block up @@ -699,6 +714,7 @@ extent_tree_node_t *ext_ptr; bt_stat_level_t *lptr; xfs_extlen_t freeblks; + __uint32_t crc_magic; #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "in build_freespace_tree, agno = %d\n", agno); @@ -707,6 +723,10 @@ freeblks = 0; ASSERT(level > 0); + if (magic == XFS_ABTB_MAGIC) + crc_magic = XFS_ABTB_CRC_MAGIC; + else + crc_magic = XFS_ABTC_CRC_MAGIC; /* * initialize the first block on each btree level @@ -728,14 +748,15 @@ /* * initialize block header */ + lptr->buf_p->b_ops = &xfs_allocbt_buf_ops; bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); - - bt_hdr->bb_magic = cpu_to_be32(magic); - bt_hdr->bb_level = cpu_to_be16(i); - bt_hdr->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); - bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); - bt_hdr->bb_numrecs = 0; + if (xfs_sb_version_hascrc(&mp->m_sb)) + xfs_btree_init_block(mp, lptr->buf_p, crc_magic, i, + 0, agno, XFS_BTREE_CRC_BLOCKS); + else + xfs_btree_init_block(mp, lptr->buf_p, magic, i, + 0, agno, 0); } /* * run along leaf, setting up records. as we have to switch @@ -759,13 +780,17 @@ /* * block initialization, lay in block header */ + lptr->buf_p->b_ops = &xfs_allocbt_buf_ops; bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); + if (xfs_sb_version_hascrc(&mp->m_sb)) + xfs_btree_init_block(mp, lptr->buf_p, crc_magic, 0, + 0, agno, XFS_BTREE_CRC_BLOCKS); + else + xfs_btree_init_block(mp, lptr->buf_p, magic, 0, + 0, agno, 0); - bt_hdr->bb_magic = cpu_to_be32(magic); - bt_hdr->bb_level = 0; bt_hdr->bb_u.s.bb_leftsib = cpu_to_be32(lptr->prev_agbno); - bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); bt_hdr->bb_numrecs = cpu_to_be16(lptr->num_recs_pb + (lptr->modulo > 0)); #ifdef XR_BLD_FREE_TRACE @@ -853,10 +878,11 @@ */ static void init_ino_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, - __uint64_t *num_inos, __uint64_t *num_free_inos) + __uint64_t *num_inos, __uint64_t *num_free_inos, int finobt) { __uint64_t ninos; __uint64_t nfinos; + __uint64_t rec_nfinos; ino_tree_node_t *ino_rec; int num_recs; int level; @@ -892,13 +918,22 @@ * build up statistics */ for (num_recs = 0; ino_rec != NULL; ino_rec = next_ino_rec(ino_rec)) { - ninos += XFS_INODES_PER_CHUNK; - num_recs++; + rec_nfinos = 0; for (i = 0; i < XFS_INODES_PER_CHUNK; i++) { ASSERT(is_inode_confirmed(ino_rec, i)); if (is_inode_free(ino_rec, i)) - nfinos++; + rec_nfinos++; } + + /* + * finobt only considers records with free inodes + */ + if (finobt && !rec_nfinos) + continue; + + nfinos += rec_nfinos; + ninos += XFS_INODES_PER_CHUNK; + num_recs++; } blocks_allocated = lptr->num_blocks = howmany(num_recs, @@ -996,14 +1031,19 @@ /* * initialize block header */ + lptr->buf_p->b_ops = &xfs_inobt_buf_ops; bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); + if (xfs_sb_version_hascrc(&mp->m_sb)) + xfs_btree_init_block(mp, lptr->buf_p, XFS_IBT_CRC_MAGIC, + level, 0, agno, + XFS_BTREE_CRC_BLOCKS); + else + xfs_btree_init_block(mp, lptr->buf_p, XFS_IBT_MAGIC, + level, 0, agno, 0); - bt_hdr->bb_magic = cpu_to_be32(XFS_IBT_MAGIC); - bt_hdr->bb_level = cpu_to_be16(level); bt_hdr->bb_u.s.bb_leftsib = cpu_to_be32(lptr->prev_agbno); - bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); - bt_hdr->bb_numrecs = 0; + /* * propagate extent record for first extent in new block up */ @@ -1024,10 +1064,12 @@ *bt_ptr = cpu_to_be32(btree_curs->level[level-1].agbno); } +/* + * XXX: yet more code that can be shared with mkfs, growfs. + */ static void -build_agi(xfs_mount_t *mp, xfs_agnumber_t agno, - bt_status_t *btree_curs, xfs_agino_t first_agino, - xfs_agino_t count, xfs_agino_t freecount) +build_agi(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, + bt_status_t *finobt_curs, struct agi_stat *agi_stat) { xfs_buf_t *agi_buf; xfs_agi_t *agi; @@ -1036,6 +1078,7 @@ agi_buf = libxfs_getbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), mp->m_sb.sb_sectsize/BBSIZE); + agi_buf->b_ops = &xfs_agi_buf_ops; agi = XFS_BUF_TO_AGI(agi_buf); memset(agi, 0, mp->m_sb.sb_sectsize); @@ -1047,16 +1090,24 @@ else agi->agi_length = cpu_to_be32(mp->m_sb.sb_dblocks - (xfs_drfsbno_t) mp->m_sb.sb_agblocks * agno); - agi->agi_count = cpu_to_be32(count); + agi->agi_count = cpu_to_be32(agi_stat->count); agi->agi_root = cpu_to_be32(btree_curs->root); agi->agi_level = cpu_to_be32(btree_curs->num_levels); - agi->agi_freecount = cpu_to_be32(freecount); - agi->agi_newino = cpu_to_be32(first_agino); + agi->agi_freecount = cpu_to_be32(agi_stat->freecount); + agi->agi_newino = cpu_to_be32(agi_stat->first_agino); agi->agi_dirino = cpu_to_be32(NULLAGINO); for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) agi->agi_unlinked[i] = cpu_to_be32(NULLAGINO); + if (xfs_sb_version_hascrc(&mp->m_sb)) + platform_uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_uuid); + + if (xfs_sb_version_hasfinobt(&mp->m_sb)) { + agi->agi_free_root = cpu_to_be32(finobt_curs->root); + agi->agi_free_level = cpu_to_be32(finobt_curs->num_levels); + } + libxfs_writebuf(agi_buf, 0); } @@ -1066,7 +1117,8 @@ */ static void build_ino_tree(xfs_mount_t *mp, xfs_agnumber_t agno, - bt_status_t *btree_curs) + bt_status_t *btree_curs, __uint32_t magic, + struct agi_stat *agi_stat, int finobt) { xfs_agnumber_t i; xfs_agblock_t j; @@ -1099,22 +1151,29 @@ /* * initialize block header */ + + lptr->buf_p->b_ops = &xfs_inobt_buf_ops; bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); - - bt_hdr->bb_magic = cpu_to_be32(XFS_IBT_MAGIC); - bt_hdr->bb_level = cpu_to_be16(i); - bt_hdr->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); - bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); - bt_hdr->bb_numrecs = 0; + if (xfs_sb_version_hascrc(&mp->m_sb)) + xfs_btree_init_block(mp, lptr->buf_p, magic, + i, 0, agno, + XFS_BTREE_CRC_BLOCKS); + else + xfs_btree_init_block(mp, lptr->buf_p, magic, + i, 0, agno, 0); } + /* * run along leaf, setting up records. as we have to switch * blocks, call the prop_ino_cursor routine to set up the new * pointers for the parent. that can recurse up to the root * if required. set the sibling pointers for leaf level here. */ - ino_rec = findfirst_inode_rec(agno); + if (finobt) + ino_rec = findfirst_free_inode_rec(agno); + else + ino_rec = findfirst_inode_rec(agno); if (ino_rec != NULL) first_agino = ino_rec->ino_startnum; @@ -1127,13 +1186,18 @@ /* * block initialization, lay in block header */ + lptr->buf_p->b_ops = &xfs_inobt_buf_ops; bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); + if (xfs_sb_version_hascrc(&mp->m_sb)) + xfs_btree_init_block(mp, lptr->buf_p, magic, + 0, 0, agno, + XFS_BTREE_CRC_BLOCKS); + else + xfs_btree_init_block(mp, lptr->buf_p, magic, + 0, 0, agno, 0); - bt_hdr->bb_magic = cpu_to_be32(XFS_IBT_MAGIC); - bt_hdr->bb_level = 0; bt_hdr->bb_u.s.bb_leftsib = cpu_to_be32(lptr->prev_agbno); - bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); bt_hdr->bb_numrecs = cpu_to_be16(lptr->num_recs_pb + (lptr->modulo > 0)); @@ -1161,7 +1225,11 @@ bt_rec[j].ir_freecount = cpu_to_be32(inocnt); freecount += inocnt; count += XFS_INODES_PER_CHUNK; - ino_rec = next_ino_rec(ino_rec); + + if (finobt) + ino_rec = next_free_ino_rec(ino_rec); + else + ino_rec = next_ino_rec(ino_rec); } if (ino_rec != NULL) { @@ -1187,12 +1255,18 @@ } } - build_agi(mp, agno, btree_curs, first_agino, count, freecount); + if (agi_stat) { + agi_stat->first_agino = first_agino; + agi_stat->count = count; + agi_stat->freecount = freecount; + } } /* * build both the agf and the agfl for an agno given both - * btree cursors + * btree cursors. + * + * XXX: yet more common code that can be shared with mkfs/growfs. */ static void build_agf_agfl(xfs_mount_t *mp, @@ -1208,10 +1282,12 @@ int j; xfs_agfl_t *agfl; xfs_agf_t *agf; + __be32 *freelist; agf_buf = libxfs_getbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), mp->m_sb.sb_sectsize/BBSIZE); + agf_buf->b_ops = &xfs_agf_buf_ops; agf = XFS_BUF_TO_AGF(agf_buf); memset(agf, 0, mp->m_sb.sb_sectsize); @@ -1265,31 +1341,44 @@ XFS_BTNUM_CNT); #endif + if (xfs_sb_version_hascrc(&mp->m_sb)) + platform_uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_uuid); + + /* initialise the AGFL, then fill it if there are blocks left over. */ + agfl_buf = libxfs_getbuf(mp->m_dev, + XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), + mp->m_sb.sb_sectsize/BBSIZE); + agfl_buf->b_ops = &xfs_agfl_buf_ops; + agfl = XFS_BUF_TO_AGFL(agfl_buf); + + /* setting to 0xff results in initialisation to NULLAGBLOCK */ + memset(agfl, 0xff, mp->m_sb.sb_sectsize); + if (xfs_sb_version_hascrc(&mp->m_sb)) { + agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC); + agfl->agfl_seqno = cpu_to_be32(agno); + platform_uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_uuid); + for (i = 0; i < XFS_AGFL_SIZE(mp); i++) + agfl->agfl_bno[i] = cpu_to_be32(NULLAGBLOCK); + } + freelist = XFS_BUF_TO_AGFL_BNO(mp, agfl_buf); + /* * do we have left-over blocks in the btree cursors that should * be used to fill the AGFL? */ if (bno_bt->num_free_blocks > 0 || bcnt_bt->num_free_blocks > 0) { /* - * yes - grab the AGFL buffer - */ - agfl_buf = libxfs_getbuf(mp->m_dev, - XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), - mp->m_sb.sb_sectsize/BBSIZE); - agfl = XFS_BUF_TO_AGFL(agfl_buf); - memset(agfl, 0, mp->m_sb.sb_sectsize); - /* - * ok, now grab as many blocks as we can + * yes, now grab as many blocks as we can */ i = j = 0; while (bno_bt->num_free_blocks > 0 && i < XFS_AGFL_SIZE(mp)) { - agfl->agfl_bno[i] = cpu_to_be32( + freelist[i] = cpu_to_be32( get_next_blockaddr(agno, 0, bno_bt)); i++; } while (bcnt_bt->num_free_blocks > 0 && i < XFS_AGFL_SIZE(mp)) { - agfl->agfl_bno[i] = cpu_to_be32( + freelist[i] = cpu_to_be32( get_next_blockaddr(agno, 0, bcnt_bt)); i++; } @@ -1324,13 +1413,14 @@ fprintf(stderr, "writing agfl for ag %u\n", agno); #endif - libxfs_writebuf(agfl_buf, 0); } else { agf->agf_flfirst = 0; agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1); agf->agf_flcount = 0; } + libxfs_writebuf(agfl_buf, 0); + ext_ptr = findbiggest_bcnt_extent(agno); agf->agf_longest = cpu_to_be32((ext_ptr != NULL) ? ext_ptr->ex_blockcount : 0); @@ -1340,6 +1430,27 @@ libxfs_writebuf(agf_buf, 0); + /* + * now fix up the free list appropriately + * XXX: code lifted from mkfs, should be shared. + */ + { + xfs_alloc_arg_t args; + xfs_trans_t *tp; + struct xfs_trans_res tres = {0}; + + memset(&args, 0, sizeof(args)); + args.tp = tp = libxfs_trans_alloc(mp, 0); + args.mp = mp; + args.agno = agno; + args.alignment = 1; + args.pag = xfs_perag_get(mp,agno); + libxfs_trans_reserve(tp, &tres, XFS_MIN_FREELIST(agf, mp), 0); + libxfs_alloc_fix_freelist(&args, 0); + xfs_perag_put(args.pag); + libxfs_trans_commit(tp, 0); + } + #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "wrote agf for ag %u, error = %d\n", agno, error); #endif @@ -1394,9 +1505,12 @@ { __uint64_t num_inos; __uint64_t num_free_inos; + __uint64_t finobt_num_inos; + __uint64_t finobt_num_free_inos; bt_status_t bno_btree_curs; bt_status_t bcnt_btree_curs; bt_status_t ino_btree_curs; + bt_status_t fino_btree_curs; int extra_blocks = 0; uint num_freeblocks; xfs_extlen_t freeblks1; @@ -1404,6 +1518,8 @@ xfs_extlen_t freeblks2; #endif xfs_agblock_t num_extents; + __uint32_t magic; + struct agi_stat agi_stat = {0,}; if (verbose) do_log(_(" - agno = %d\n"), agno); @@ -1439,8 +1555,13 @@ * on-disk btrees (includs pre-allocating all * required blocks for the trees themselves) */ - init_ino_cursor(mp, agno, &ino_btree_curs, - &num_inos, &num_free_inos); + init_ino_cursor(mp, agno, &ino_btree_curs, &num_inos, + &num_free_inos, 0); + + if (xfs_sb_version_hasfinobt(&mp->m_sb)) + init_ino_cursor(mp, agno, &fino_btree_curs, + &finobt_num_inos, &finobt_num_free_inos, + 1); sb_icount_ag[agno] += num_inos; sb_ifree_ag[agno] += num_free_inos; @@ -1535,15 +1656,35 @@ build_agf_agfl(mp, agno, &bno_btree_curs, &bcnt_btree_curs, freeblks1, extra_blocks); /* - * build inode allocation tree. this also build the agi + * build inode allocation tree. */ - build_ino_tree(mp, agno, &ino_btree_curs); + magic = xfs_sb_version_hascrc(&mp->m_sb) ? + XFS_IBT_CRC_MAGIC : XFS_IBT_MAGIC; + build_ino_tree(mp, agno, &ino_btree_curs, magic, &agi_stat, 0); write_cursor(&ino_btree_curs); + + /* + * build free inode tree + */ + if (xfs_sb_version_hasfinobt(&mp->m_sb)) { + magic = xfs_sb_version_hascrc(&mp->m_sb) ? + XFS_FIBT_CRC_MAGIC : XFS_FIBT_MAGIC; + build_ino_tree(mp, agno, &fino_btree_curs, magic, + NULL, 1); + write_cursor(&fino_btree_curs); + } + + /* build the agi */ + build_agi(mp, agno, &ino_btree_curs, &fino_btree_curs, + &agi_stat); + /* * tear down cursors */ finish_cursor(&bno_btree_curs); finish_cursor(&ino_btree_curs); + if (xfs_sb_version_hasfinobt(&mp->m_sb)) + finish_cursor(&fino_btree_curs); finish_cursor(&bcnt_btree_curs); /* * release the incore per-AG bno/bcnt trees so diff -Nru xfsprogs-3.1.9ubuntu2/repair/phase6.c xfsprogs-3.2.1ubuntu1/repair/phase6.c --- xfsprogs-3.1.9ubuntu2/repair/phase6.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/phase6.c 2014-07-21 09:13:53.000000000 +0000 @@ -17,38 +17,39 @@ */ #include +#include "threads.h" +#include "prefetch.h" #include "avl.h" #include "globals.h" #include "agheader.h" #include "incore.h" -#include "dir.h" #include "dir2.h" #include "protos.h" #include "err_protos.h" #include "dinode.h" -#include "prefetch.h" #include "progress.h" -#include "threads.h" #include "versions.h" static struct cred zerocr; static struct fsxattr zerofsx; static xfs_ino_t orphanage_ino; -static struct xfs_name xfs_name_dot = {(unsigned char *)".", 1}; +static struct xfs_name xfs_name_dot = {(unsigned char *)".", + 1, + XFS_DIR3_FT_DIR}; /* * Data structures used to keep track of directories where the ".." * entries are updated. These must be rebuilt after the initial pass */ typedef struct dotdot_update { - struct dotdot_update *next; + struct list_head list; ino_tree_node_t *irec; xfs_agnumber_t agno; int ino_offset; } dotdot_update_t; -static dotdot_update_t *dotdot_update_list; +static LIST_HEAD(dotdot_update_list); static int dotdot_update; static void @@ -63,12 +64,12 @@ do_error(_("malloc failed add_dotdot_update (%zu bytes)\n"), sizeof(dotdot_update_t)); - dir->next = dotdot_update_list; + INIT_LIST_HEAD(&dir->list); dir->irec = irec; dir->agno = agno; dir->ino_offset = ino_offset; - dotdot_update_list = dir; + list_add(&dir->list, &dotdot_update_list); } /* @@ -124,6 +125,45 @@ #define DIR_HASH_CK_TOTAL 6 /* + * Need to handle CRC and validation errors specially here. If there is a + * validator error, re-read without the verifier so that we get a buffer we can + * check and repair. Re-attach the ops to the buffer after the read so that when + * it is rewritten the CRC is recalculated. + * + * If the buffer was not read, we return an error. If the buffer was read but + * had a CRC or corruption error, we reread it without the verifier and if it is + * read successfully we increment *crc_error and return 0. Otherwise we + * return the read error. + */ +static int +dir_read_buf( + struct xfs_inode *ip, + xfs_dablk_t bno, + xfs_daddr_t mappedbno, + struct xfs_buf **bpp, + const struct xfs_buf_ops *ops, + int *crc_error) +{ + int error; + int error2; + + error = libxfs_da_read_buf(NULL, ip, bno, mappedbno, bpp, + XFS_DATA_FORK, ops); + + if (error != EFSBADCRC && error != EFSCORRUPTED) + return error; + + error2 = libxfs_da_read_buf(NULL, ip, bno, mappedbno, bpp, + XFS_DATA_FORK, NULL); + if (error2) + return error2; + + (*crc_error)++; + (*bpp)->b_ops = ops; + return 0; +} + +/* * Returns 0 if the name already exists (ie. a duplicate) */ static int @@ -133,7 +173,8 @@ __uint32_t addr, xfs_ino_t inum, int namelen, - unsigned char *name) + unsigned char *name, + __uint8_t ftype) { xfs_dahash_t hash = 0; int byaddr; @@ -147,6 +188,7 @@ xname.name = name; xname.len = namelen; + xname.type = ftype; junk = name[0] == '/'; byaddr = DIR_HASH_FUNC(hashtab, addr); @@ -311,6 +353,23 @@ return DIR_HASH_CK_NODATA; } +static void +dir_hash_update_ftype( + dir_hash_tab_t *hashtab, + xfs_dir2_dataptr_t addr, + __uint8_t ftype) +{ + int i; + dir_hash_ent_t *p; + + i = DIR_HASH_FUNC(hashtab, addr); + for (p = hashtab->byaddr[i]; p; p = p->nextbyaddr) { + if (p->address != addr) + continue; + p->name.type = ftype; + } +} + /* * checks to make sure leafs match a data entry, and that the stale * count is valid. @@ -428,13 +487,17 @@ xfs_bmap_free_t flist; xfs_dfiloff_t bno; xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP]; + int vers; + int times; + struct xfs_trans_res tres = {0}; /* * first set up inode */ tp = libxfs_trans_alloc(mp, 0); - if ((i = libxfs_trans_reserve(tp, 10, 0, 0, 0, 0))) + i = libxfs_trans_reserve(tp, &tres, 10, 0); + if (i) res_failed(i); error = libxfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, 0, &ip); @@ -444,16 +507,30 @@ error); } - memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); + vers = xfs_sb_version_hascrc(&mp->m_sb) ? 3 : 1; + memset(&ip->i_d, 0, xfs_icdinode_size(vers)); ip->i_d.di_magic = XFS_DINODE_MAGIC; ip->i_d.di_mode = S_IFREG; - ip->i_d.di_version = 1; + ip->i_d.di_version = vers; ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; ip->i_d.di_nlink = 1; /* account for sb ptr */ + times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD; + if (ip->i_d.di_version == 3) { + ip->i_d.di_crc = 0; + ip->i_d.di_changecount = 1; + ip->i_d.di_lsn = 0; + ip->i_d.di_flags2 = 0; + ip->i_d.di_ino = mp->m_sb.sb_rbmino; + memset(&(ip->i_d.di_pad2[0]), 0, sizeof(ip->i_d.di_pad2)); + platform_uuid_copy(&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); + times |= XFS_ICHGTIME_CREATE; + } + libxfs_trans_ichgtime(tp, ip, times); + /* * now the ifork */ @@ -467,7 +544,6 @@ * commit changes */ libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - libxfs_trans_ihold(tp, ip); libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); /* @@ -475,8 +551,9 @@ * from mkfs) */ tp = libxfs_trans_alloc(mp, 0); - if ((error = libxfs_trans_reserve(tp, mp->m_sb.sb_rbmblocks + - (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0, 0, 0, 0))) + error = libxfs_trans_reserve(tp, &tres, mp->m_sb.sb_rbmblocks + + (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0); + if (error) res_failed(error); libxfs_trans_ijoin(tp, ip, 0); @@ -484,9 +561,9 @@ xfs_bmap_init(&flist, &first); while (bno < mp->m_sb.sb_rbmblocks) { nmap = XFS_BMAP_MAX_NMAP; - error = libxfs_bmapi(tp, ip, bno, + error = libxfs_bmapi_write(tp, ip, bno, (xfs_extlen_t)(mp->m_sb.sb_rbmblocks - bno), - XFS_BMAPI_WRITE, &first, mp->m_sb.sb_rbmblocks, + 0, &first, mp->m_sb.sb_rbmblocks, map, &nmap, &flist); if (error) { do_error( @@ -494,7 +571,7 @@ error); } for (i = 0, ep = map; i < nmap; i++, ep++) { - libxfs_device_zero(mp->m_dev, + libxfs_device_zero(mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, ep->br_startblock), XFS_FSB_TO_BB(mp, ep->br_blockcount)); bno += ep->br_blockcount; @@ -521,13 +598,15 @@ int error; xfs_dfiloff_t bno; xfs_bmbt_irec_t map; + struct xfs_trans_res tres = {0}; bmp = btmcompute; bno = 0; tp = libxfs_trans_alloc(mp, 0); - if ((error = libxfs_trans_reserve(tp, 10, 0, 0, 0, 0))) + error = libxfs_trans_reserve(tp, &tres, 10, 0); + if (error) res_failed(error); error = libxfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, 0, &ip); @@ -537,12 +616,13 @@ error); } + first = NULLFSBLOCK; while (bno < mp->m_sb.sb_rbmblocks) { /* * fill the file one block at a time */ nmap = 1; - error = libxfs_bmapi(tp, ip, bno, 1, XFS_BMAPI_WRITE, + error = libxfs_bmapi_write(tp, ip, bno, 1, 0, &first, 1, &map, &nmap, NULL); if (error || nmap != 1) { do_error( @@ -555,7 +635,7 @@ error = libxfs_trans_read_buf( mp, tp, mp->m_dev, XFS_FSB_TO_DADDR(mp, map.br_startblock), - XFS_FSB_TO_BB(mp, 1), 1, &bp); + XFS_FSB_TO_BB(mp, 1), 1, &bp, NULL); if (error) { do_warn( @@ -589,6 +669,7 @@ xfs_dfiloff_t bno; xfs_dfiloff_t end_bno; xfs_bmbt_irec_t map; + struct xfs_trans_res tres = {0}; smp = sumcompute; bno = 0; @@ -596,7 +677,8 @@ tp = libxfs_trans_alloc(mp, 0); - if ((error = libxfs_trans_reserve(tp, 10, 0, 0, 0, 0))) + error = libxfs_trans_reserve(tp, &tres, 10, 0); + if (error) res_failed(error); error = libxfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0, 0, &ip); @@ -606,12 +688,13 @@ error); } + first = NULLFSBLOCK; while (bno < end_bno) { /* * fill the file one block at a time */ nmap = 1; - error = libxfs_bmapi(tp, ip, bno, 1, XFS_BMAPI_WRITE, + error = libxfs_bmapi_write(tp, ip, bno, 1, 0, &first, 1, &map, &nmap, NULL); if (error || nmap != 1) { do_error( @@ -624,7 +707,7 @@ error = libxfs_trans_read_buf( mp, tp, mp->m_dev, XFS_FSB_TO_DADDR(mp, map.br_startblock), - XFS_FSB_TO_BB(mp, 1), 1, &bp); + XFS_FSB_TO_BB(mp, 1), 1, &bp, NULL); if (error) { do_warn( @@ -660,14 +743,17 @@ xfs_bmap_free_t flist; xfs_dfiloff_t bno; xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP]; + int vers; + int times; + struct xfs_trans_res tres = {0}; /* * first set up inode */ tp = libxfs_trans_alloc(mp, 0); - if ((i = libxfs_trans_reserve(tp, 10, XFS_ICHANGE_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT))) + i = libxfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 10, 0); + if (i) res_failed(i); error = libxfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0, 0, &ip); @@ -677,16 +763,30 @@ error); } - memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); + vers = xfs_sb_version_hascrc(&mp->m_sb) ? 3 : 1; + memset(&ip->i_d, 0, xfs_icdinode_size(vers)); ip->i_d.di_magic = XFS_DINODE_MAGIC; ip->i_d.di_mode = S_IFREG; - ip->i_d.di_version = 1; + ip->i_d.di_version = vers; ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; ip->i_d.di_nlink = 1; /* account for sb ptr */ + times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD; + if (ip->i_d.di_version == 3) { + ip->i_d.di_crc = 0; + ip->i_d.di_changecount = 1; + ip->i_d.di_lsn = 0; + ip->i_d.di_flags2 = 0; + ip->i_d.di_ino = mp->m_sb.sb_rsumino; + memset(&(ip->i_d.di_pad2[0]), 0, sizeof(ip->i_d.di_pad2)); + platform_uuid_copy(&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); + times |= XFS_ICHGTIME_CREATE; + } + libxfs_trans_ichgtime(tp, ip, times); + /* * now the ifork */ @@ -700,7 +800,6 @@ * commit changes */ libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - libxfs_trans_ihold(tp, ip); libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); /* @@ -711,11 +810,12 @@ xfs_bmap_init(&flist, &first); nsumblocks = mp->m_rsumsize >> mp->m_sb.sb_blocklog; - if ((error = libxfs_trans_reserve(tp, - mp->m_sb.sb_rbmblocks + - (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), - BBTOB(128), 0, XFS_TRANS_PERM_LOG_RES, - XFS_DEFAULT_PERM_LOG_COUNT))) + tres.tr_logres = BBTOB(128); + tres.tr_logcount = XFS_DEFAULT_PERM_LOG_COUNT; + tres.tr_logflags = XFS_TRANS_PERM_LOG_RES; + error = libxfs_trans_reserve(tp, &tres, mp->m_sb.sb_rbmblocks + + (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0); + if (error) res_failed(error); libxfs_trans_ijoin(tp, ip, 0); @@ -723,17 +823,16 @@ xfs_bmap_init(&flist, &first); while (bno < nsumblocks) { nmap = XFS_BMAP_MAX_NMAP; - error = libxfs_bmapi(tp, ip, bno, + error = libxfs_bmapi_write(tp, ip, bno, (xfs_extlen_t)(nsumblocks - bno), - XFS_BMAPI_WRITE, &first, nsumblocks, - map, &nmap, &flist); + 0, &first, nsumblocks, map, &nmap, &flist); if (error) { do_error( _("couldn't allocate realtime summary inode, error = %d\n"), error); } for (i = 0, ep = map; i < nmap; i++, ep++) { - libxfs_device_zero(mp->m_dev, + libxfs_device_zero(mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, ep->br_startblock), XFS_FSB_TO_BB(mp, ep->br_blockcount)); bno += ep->br_blockcount; @@ -760,14 +859,16 @@ int error; const mode_t mode = 0755; ino_tree_node_t *irec; + int vers; + int times; ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb)); tp = libxfs_trans_alloc(mp, 0); ip = NULL; - if ((i = libxfs_trans_reserve(tp, 10, XFS_ICHANGE_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT))) + i = libxfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 10, 0); + if (i) res_failed(i); error = libxfs_trans_iget(mp, tp, mp->m_sb.sb_rootino, 0, 0, &ip); @@ -778,16 +879,30 @@ /* * take care of the core -- initialization from xfs_ialloc() */ - memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); + vers = xfs_sb_version_hascrc(&mp->m_sb) ? 3 : 1; + memset(&ip->i_d, 0, xfs_icdinode_size(vers)); ip->i_d.di_magic = XFS_DINODE_MAGIC; ip->i_d.di_mode = (__uint16_t) mode|S_IFDIR; - ip->i_d.di_version = 1; + ip->i_d.di_version = vers; ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; ip->i_d.di_nlink = 1; /* account for . */ + times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD; + if (ip->i_d.di_version == 3) { + ip->i_d.di_crc = 0; + ip->i_d.di_changecount = 1; + ip->i_d.di_lsn = 0; + ip->i_d.di_flags2 = 0; + ip->i_d.di_ino = mp->m_sb.sb_rootino; + memset(&(ip->i_d.di_pad2[0]), 0, sizeof(ip->i_d.di_pad2)); + platform_uuid_copy(&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); + times |= XFS_ICHGTIME_CREATE; + } + libxfs_trans_ichgtime(tp, ip, times); + libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); /* @@ -797,8 +912,6 @@ ip->i_df.if_bytes = ip->i_df.if_real_bytes = 0; ip->i_df.if_u1.if_extents = NULL; - mp->m_rootip = ip; - /* * initialize the directory */ @@ -847,6 +960,8 @@ xname.name = (unsigned char *)ORPHANAGE; xname.len = strlen(ORPHANAGE); + xname.type = XFS_DIR3_FT_DIR; + if (libxfs_dir_lookup(NULL, pip, &xname, &ino, NULL) == 0) return ino; @@ -858,8 +973,8 @@ xfs_bmap_init(&flist, &first); nres = XFS_MKDIR_SPACE_RES(mp, xname.len); - if ((i = libxfs_trans_reserve(tp, nres, XFS_MKDIR_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT))) + i = libxfs_trans_reserve(tp, &M_RES(mp)->tr_mkdir, nres, 0); + if (i) res_failed(i); /* @@ -882,6 +997,22 @@ irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, ino), XFS_INO_TO_AGINO(mp, ino)); + + if (irec == NULL) { + /* + * This inode is allocated from a newly created inode + * chunk and therefore did not exist when inode chunks + * were processed in phase3. Add this group of inodes to + * the entry avl tree as if they were discovered in phase3. + */ + irec = set_inode_free_alloc(mp, XFS_INO_TO_AGNO(mp, ino), + XFS_INO_TO_AGINO(mp, ino)); + alloc_ex_data(irec); + + for (i = 0; i < XFS_INODES_PER_CHUNK; i++) + set_inode_free(irec, i); + } + ino_offset = get_inode_offset(mp, ino, irec); /* @@ -930,6 +1061,8 @@ libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); + IRELE(ip); + IRELE(pip); add_inode_reached(irec,ino_offset); return(ino); @@ -964,6 +1097,8 @@ xname.name = fname; xname.len = snprintf((char *)fname, sizeof(fname), "%llu", (unsigned long long)ino); + /* XXX use xfs_mode_to_ftype[] when userspace gains it */ + xname.type = XFS_DIR3_FT_UNKNOWN; err = libxfs_iget(mp, NULL, orphanage_ino, 0, &orphanage_ip, 0); if (err) @@ -995,10 +1130,9 @@ if (err) { ASSERT(err == ENOENT); - if ((err = libxfs_trans_reserve(tp, nres, - XFS_RENAME_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, - XFS_RENAME_LOG_COUNT))) + err = libxfs_trans_reserve(tp, &M_RES(mp)->tr_rename, + nres, 0); + if (err) do_error( _("space reservation failed (%d), filesystem may be out of space\n"), err); @@ -1039,10 +1173,9 @@ libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); } else { - if ((err = libxfs_trans_reserve(tp, nres, - XFS_RENAME_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, - XFS_RENAME_LOG_COUNT))) + err = libxfs_trans_reserve(tp, &M_RES(mp)->tr_rename, + nres, 0); + if (err) do_error( _("space reservation failed (%d), filesystem may be out of space\n"), err); @@ -1097,8 +1230,8 @@ * also accounted for in the create */ nres = XFS_DIRENTER_SPACE_RES(mp, xname.len); - err = libxfs_trans_reserve(tp, nres, XFS_REMOVE_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT); + err = libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove, + nres, 0); if (err) do_error( _("space reservation failed (%d), filesystem may be out of space\n"), @@ -1127,147 +1260,8 @@ libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); } -} - -/* - * Returns the fsbno of the first (leftmost) block in the directory leaf. - * sets *bno to the directory block # corresponding to the returned fsbno. - */ -static xfs_dfsbno_t -map_first_dblock_fsbno(xfs_mount_t *mp, - xfs_ino_t ino, - xfs_inode_t *ip, - xfs_dablk_t *bno) -{ - xfs_fsblock_t fblock; - xfs_da_intnode_t *node; - xfs_buf_t *bp; - xfs_dablk_t da_bno; - xfs_dfsbno_t fsbno; - xfs_bmbt_irec_t map; - int nmap; - int i; - int error; - char *ftype; - - /* - * traverse down left-side of tree until we hit the - * left-most leaf block setting up the btree cursor along - * the way. - */ - da_bno = 0; - *bno = 0; - i = -1; - node = NULL; - fblock = NULLFSBLOCK; - ftype = _("dir"); - - nmap = 1; - error = libxfs_bmapi(NULL, ip, (xfs_fileoff_t) da_bno, 1, - XFS_BMAPI_METADATA, &fblock, 0, - &map, &nmap, NULL); - if (error || nmap != 1) { - if (!no_modify) - do_error( -_("can't map block %d in %s inode %" PRIu64 ", xfs_bmapi returns %d, nmap = %d\n"), - da_bno, ftype, ino, error, nmap); - else { - do_warn( -_("can't map block %d in %s inode %" PRIu64 ", xfs_bmapi returns %d, nmap = %d\n"), - da_bno, ftype, ino, error, nmap); - return(NULLDFSBNO); - } - } - - if ((fsbno = map.br_startblock) == HOLESTARTBLOCK) { - if (!no_modify) - do_error( - _("block %d in %s ino %" PRIu64 " doesn't exist\n"), - da_bno, ftype, ino); - else { - do_warn( - _("block %d in %s ino %" PRIu64 " doesn't exist\n"), - da_bno, ftype, ino); - return(NULLDFSBNO); - } - } - - if (ip->i_d.di_size <= XFS_LBSIZE(mp)) - return(fsbno); - - if (xfs_sb_version_hasdirv2(&mp->m_sb)) - return(fsbno); - - do { - /* - * walk down left side of btree, release buffers as you - * go. if the root block is a leaf (single-level btree), - * just return it. - * - */ - - bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), - XFS_FSB_TO_BB(mp, 1), 0); - - if (!bp) { - do_warn( - _("can't read block %u (fsbno %" PRIu64 ") for directory inode %" PRIu64 "\n"), - da_bno, fsbno, ino); - return(NULLDFSBNO); - } - - node = (xfs_da_intnode_t *)XFS_BUF_PTR(bp); - - if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC) { - libxfs_putbuf(bp); - do_warn( -_("bad dir/attr magic number in inode %" PRIu64 ", file bno = %u, fsbno = %" PRIu64 "\n"), - ino, da_bno, fsbno); - return(NULLDFSBNO); - } - - if (i == -1) - i = be16_to_cpu(node->hdr.level); - - da_bno = be32_to_cpu(node->btree[0].before); - - libxfs_putbuf(bp); - bp = NULL; - - nmap = 1; - error = libxfs_bmapi(NULL, ip, (xfs_fileoff_t) da_bno, 1, - XFS_BMAPI_METADATA, &fblock, 0, - &map, &nmap, NULL); - if (error || nmap != 1) { - if (!no_modify) - do_error( -_("can't map block %d in %s ino %" PRIu64 ", xfs_bmapi returns %d, nmap = %d\n"), - da_bno, ftype, ino, error, nmap); - else { - do_warn( -_("can't map block %d in %s ino %" PRIu64 ", xfs_bmapi returns %d, nmap = %d\n"), - da_bno, ftype, ino, error, nmap); - return(NULLDFSBNO); - } - } - if ((fsbno = map.br_startblock) == HOLESTARTBLOCK) { - if (!no_modify) - do_error( - _("block %d in %s inode %" PRIu64 " doesn't exist\n"), - da_bno, ftype, ino); - else { - do_warn( - _("block %d in %s inode %" PRIu64 " doesn't exist\n"), - da_bno, ftype, ino); - return(NULLDFSBNO); - } - } - - i--; - } while(i > 0); - - *bno = da_bno; - return(fsbno); + IRELE(ino_p); + IRELE(orphanage_ip); } static int @@ -1289,479 +1283,103 @@ } /* - * process a leaf block, also checks for .. entry - * and corrects it to match what we think .. should be + * Unexpected failure during the rebuild will leave the entries in + * lost+found on the next run */ + static void -lf_block_dir_entry_check(xfs_mount_t *mp, - xfs_ino_t ino, - xfs_dir_leafblock_t *leaf, - int *dirty, - int *num_illegal, - int *need_dot, - ino_tree_node_t *current_irec, - int current_ino_offset, - dir_hash_tab_t *hashtab, - xfs_dablk_t da_bno) +longform_dir2_rebuild( + xfs_mount_t *mp, + xfs_ino_t ino, + xfs_inode_t *ip, + ino_tree_node_t *irec, + int ino_offset, + dir_hash_tab_t *hashtab) { - xfs_dir_leaf_entry_t *entry; - ino_tree_node_t *irec; - xfs_ino_t lino; - xfs_ino_t parent; - xfs_dir_leaf_name_t *namest; - int i; - int junkit; - int ino_offset; - int nbad; - char fname[MAXNAMELEN + 1]; + int error; + int nres; + xfs_trans_t *tp; + xfs_fileoff_t lastblock; + xfs_fsblock_t firstblock; + xfs_bmap_free_t flist; + xfs_inode_t pip; + dir_hash_ent_t *p; + int committed; + int done; - entry = &leaf->entries[0]; - *dirty = 0; - nbad = 0; + /* + * trash directory completely and rebuild from scratch using the + * name/inode pairs in the hash table + */ + + do_warn(_("rebuilding directory inode %" PRIu64 "\n"), ino); /* - * look at each entry. reference inode pointed to by each - * entry in the incore inode tree. - * if not a directory, set reached flag, increment link count - * if a directory and reached, mark entry as to be deleted. - * if a directory, check to see if recorded parent - * matches current inode #, - * if so, then set reached flag, increment link count - * of current and child dir inodes, push the child - * directory inode onto the directory stack. - * if current inode != parent, then mark entry to be deleted. - * - * return + * first attempt to locate the parent inode, if it can't be + * found, set it to the root inode and it'll be moved to the + * orphanage later (the inode number here needs to be valid + * for the libxfs_dir_init() call). */ - for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { - /* - * snag inode #, update link counts, and make sure - * this isn't a loop if the child is a directory - */ - namest = xfs_dir_leaf_namestruct(leaf, - be16_to_cpu(entry->nameidx)); + pip.i_ino = get_inode_parent(irec, ino_offset); + if (pip.i_ino == NULLFSINO) + pip.i_ino = mp->m_sb.sb_rootino; - /* - * skip bogus entries (leading '/'). they'll be deleted - * later - */ - if (namest->name[0] == '/') { - nbad++; - continue; - } + xfs_bmap_init(&flist, &firstblock); - junkit = 0; + tp = libxfs_trans_alloc(mp, 0); + nres = XFS_REMOVE_SPACE_RES(mp); + error = libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove, nres, 0); + if (error) + res_failed(error); + libxfs_trans_ijoin(tp, ip, 0); - xfs_dir_sf_get_dirino(&namest->inumber, &lino); - memmove(fname, namest->name, entry->namelen); - fname[entry->namelen] = '\0'; + if ((error = libxfs_bmap_last_offset(tp, ip, &lastblock, + XFS_DATA_FORK))) + do_error(_("xfs_bmap_last_offset failed -- error - %d\n"), + error); - ASSERT(lino != NULLFSINO); + /* free all data, leaf, node and freespace blocks */ + error = libxfs_bunmapi(tp, ip, 0, lastblock, XFS_BMAPI_METADATA, 0, + &firstblock, &flist, &done); + if (error) { + do_warn(_("xfs_bunmapi failed -- error - %d\n"), error); + goto out_bmap_cancel; + } - /* - * skip the '..' entry since it's checked when the - * directory is reached by something else. if it never - * gets reached, it'll be moved to the orphanage and we'll - * take care of it then. - */ - if (entry->namelen == 2 && namest->name[0] == '.' && - namest->name[1] == '.') - continue; + ASSERT(done); - ASSERT(no_modify || !verify_inum(mp, lino)); + libxfs_dir_init(tp, ip, &pip); - /* - * special case the . entry. we know there's only one - * '.' and only '.' points to itself because bogus entries - * got trashed in phase 3 if there were > 1. - * bump up link count for '.' but don't set reached - * until we're actually reached by another directory - * '..' is already accounted for or will be taken care - * of when directory is moved to orphanage. - */ - if (ino == lino) { - ASSERT(namest->name[0] == '.' && entry->namelen == 1); - add_inode_ref(current_irec, current_ino_offset); - *need_dot = 0; - continue; - } + error = libxfs_bmap_finish(&tp, &flist, &committed); - /* - * skip entries with bogus inumbers if we're in no modify mode - */ - if (no_modify && verify_inum(mp, lino)) - continue; + libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); - /* - * ok, now handle the rest of the cases besides '.' and '..' - */ - irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, lino), - XFS_INO_TO_AGINO(mp, lino)); + /* go through the hash list and re-add the inodes */ - if (irec == NULL) { - nbad++; - if (entry_junked( - _("entry \"%s\" in dir inode %" PRIu64 " points to non-existent inode %" PRIu64), - fname, ino, lino)) { - namest->name[0] = '/'; - *dirty = 1; - } + for (p = hashtab->first; p; p = p->nextbyorder) { + + if (p->name.name[0] == '/' || (p->name.name[0] == '.' && + (p->name.len == 1 || (p->name.len == 2 && + p->name.name[1] == '.')))) continue; - } - ino_offset = XFS_INO_TO_AGINO(mp, lino) - irec->ino_startnum; + tp = libxfs_trans_alloc(mp, 0); + nres = XFS_CREATE_SPACE_RES(mp, p->name.len); + error = libxfs_trans_reserve(tp, &M_RES(mp)->tr_create, + nres, 0); + if (error) + res_failed(error); - /* - * if it's a free inode, blow out the entry. - * by now, any inode that we think is free - * really is free. - */ - if (is_inode_free(irec, ino_offset)) { - nbad++; - if (entry_junked( - _("entry \"%s\" in dir inode %" PRIu64 " points to free inode %" PRIu64), - fname, ino, lino)) { - namest->name[0] = '/'; - *dirty = 1; - } - continue; - } - /* - * check if this inode is lost+found dir in the root - */ - if (ino == mp->m_sb.sb_rootino && strcmp(fname, ORPHANAGE) == 0) { - /* root inode, "lost+found", if it's not a directory, - * trash it, otherwise, assign it */ - if (!inode_isadir(irec, ino_offset)) { - nbad++; - if (entry_junked( - _("%s (ino %" PRIu64 ") in root (%" PRIu64 ") is not a directory"), - ORPHANAGE, lino, ino)) { - namest->name[0] = '/'; - *dirty = 1; - } - continue; - } - /* - * if this is a dup, it will be picked up below, - * otherwise, mark it as the orphanage for later. - */ - if (!orphanage_ino) - orphanage_ino = lino; - } - /* - * check for duplicate names in directory. - */ - if (!dir_hash_add(mp, hashtab, (da_bno << mp->m_sb.sb_blocklog) - + be16_to_cpu(entry->nameidx), lino, - entry->namelen, namest->name)) { - nbad++; - if (entry_junked( - _("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is a duplicate name"), - fname, lino, ino)) { - namest->name[0] = '/'; - *dirty = 1; - } - if (lino == orphanage_ino) - orphanage_ino = 0; - continue; - } - /* - * check easy case first, regular inode, just bump - * the link count and continue - */ - if (!inode_isadir(irec, ino_offset)) { - add_inode_reached(irec, ino_offset); - continue; - } - - parent = get_inode_parent(irec, ino_offset); - ASSERT(parent != 0); - - /* - * bump up the link counts in parent and child - * directory but if the link doesn't agree with - * the .. in the child, blow out the entry. - * if the directory has already been reached, - * blow away the entry also. - */ - if (is_inode_reached(irec, ino_offset)) { - junkit = 1; - do_warn( - _("entry \"%s\" in dir ino %" PRIu64 " points to an already connected dir inode %" PRIu64 ",\n"), - fname, ino, lino); - } else if (parent == ino) { - add_inode_reached(irec, ino_offset); - add_inode_ref(current_irec, current_ino_offset); - } else if (parent == NULLFSINO) { - /* ".." was missing, but this entry refers to it, - so, set it as the parent and mark for rebuild */ - do_warn( - _("entry \"%s\" in dir ino %" PRIu64 " doesn't have a .. entry, will set it in ino %" PRIu64 ".\n"), - fname, ino, lino); - set_inode_parent(irec, ino_offset, ino); - add_inode_reached(irec, ino_offset); - add_inode_ref(current_irec, current_ino_offset); - } else { - junkit = 1; - do_warn( - _("entry \"%s\" in dir ino %" PRIu64 " not consistent with .. value (%" PRIu64 ") in ino %" PRIu64 ",\n"), - fname, ino, parent, lino); - } - - if (junkit) { - if (lino == orphanage_ino) - orphanage_ino = 0; - junkit = 0; - nbad++; - if (!no_modify) { - namest->name[0] = '/'; - *dirty = 1; - if (verbose) - do_warn( - _("\twill clear entry \"%s\"\n"), - fname); - } else { - do_warn(_("\twould clear entry \"%s\"\n"), - fname); - } - } - } - - *num_illegal += nbad; -} - -/* - * succeeds or dies, inode never gets dirtied since all changes - * happen in file blocks. the inode size and other core info - * is already correct, it's just the leaf entries that get altered. - */ -static void -longform_dir_entry_check(xfs_mount_t *mp, - xfs_ino_t ino, - xfs_inode_t *ip, - int *num_illegal, - int *need_dot, - ino_tree_node_t *irec, - int ino_offset, - dir_hash_tab_t *hashtab) -{ - xfs_dir_leafblock_t *leaf; - xfs_buf_t *bp; - xfs_dfsbno_t fsbno; - xfs_fsblock_t fblock; - xfs_dablk_t da_bno; - int dirty; - int nmap; - int error; - int skipit; - xfs_bmbt_irec_t map; - char *ftype; - - da_bno = 0; - fblock = NULLFSBLOCK; - *need_dot = 1; - ftype = _("dir"); - - fsbno = map_first_dblock_fsbno(mp, ino, ip, &da_bno); - - if (fsbno == NULLDFSBNO && no_modify) { - do_warn( - _("cannot map block 0 of directory inode %" PRIu64 "\n"), ino); - return; - } - - do { - ASSERT(fsbno != NULLDFSBNO); - skipit = 0; - - bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), - XFS_FSB_TO_BB(mp, 1), 0); - - if (!bp) { - do_error( - _("can't read block %u (fsbno %" PRIu64 ") for directory inode %" PRIu64 "\n"), - da_bno, fsbno, ino); - /* NOTREACHED */ - } - - leaf = (xfs_dir_leafblock_t *)XFS_BUF_PTR(bp); - - if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) { - if (!no_modify) { - do_error( -_("bad magic # (0x%x) for dir ino %" PRIu64 " leaf block (bno %u fsbno %" PRIu64 ")\n"), - be16_to_cpu(leaf->hdr.info.magic), - ino, da_bno, fsbno); - /* NOTREACHED */ - } else { - /* - * this block's bad but maybe the - * forward pointer is good... - */ - skipit = 1; - dirty = 0; - } - } - - if (!skipit) - lf_block_dir_entry_check(mp, ino, leaf, &dirty, - num_illegal, need_dot, irec, - ino_offset, hashtab, da_bno); - - da_bno = be32_to_cpu(leaf->hdr.info.forw); - - ASSERT(dirty == 0 || (dirty && !no_modify)); - - if (dirty && !no_modify) - libxfs_writebuf(bp, 0); - else - libxfs_putbuf(bp); - bp = NULL; - - if (da_bno != 0) { - nmap = 1; - error = libxfs_bmapi(NULL, ip, (xfs_fileoff_t)da_bno, 1, - XFS_BMAPI_METADATA, &fblock, 0, - &map, &nmap, NULL); - if (error || nmap != 1) { - if (!no_modify) - do_error( -_("can't map leaf block %d in dir %" PRIu64 ", xfs_bmapi returns %d, nmap = %d\n"), - da_bno, ino, error, nmap); - else { - do_warn( -_("can't map leaf block %d in dir %" PRIu64 ", xfs_bmapi returns %d, nmap = %d\n"), - da_bno, ino, error, nmap); - return; - } - } - fsbno = map.br_startblock; - if (fsbno == HOLESTARTBLOCK) { - if (!no_modify) - do_error( - _("block %d in %s ino %" PRIu64 " doesn't exist\n"), - da_bno, ftype, ino); - else { - do_warn( - _("block %d in %s ino %" PRIu64 " doesn't exist\n"), - da_bno, ftype, ino); - return; - } - } - } - } while (da_bno != 0); -} - -/* - * Unexpected failure during the rebuild will leave the entries in - * lost+found on the next run - */ - -static void -longform_dir2_rebuild( - xfs_mount_t *mp, - xfs_ino_t ino, - xfs_inode_t *ip, - ino_tree_node_t *irec, - int ino_offset, - dir_hash_tab_t *hashtab) -{ - int error; - int nres; - xfs_trans_t *tp; - xfs_fileoff_t lastblock; - xfs_fsblock_t firstblock; - xfs_bmap_free_t flist; - xfs_inode_t pip; - dir_hash_ent_t *p; - int committed; - int done; - - /* - * trash directory completely and rebuild from scratch using the - * name/inode pairs in the hash table - */ - - do_warn(_("rebuilding directory inode %" PRIu64 "\n"), ino); - - /* - * first attempt to locate the parent inode, if it can't be - * found, set it to the root inode and it'll be moved to the - * orphanage later (the inode number here needs to be valid - * for the libxfs_dir_init() call). - */ - pip.i_ino = get_inode_parent(irec, ino_offset); - if (pip.i_ino == NULLFSINO) - pip.i_ino = mp->m_sb.sb_rootino; - - xfs_bmap_init(&flist, &firstblock); - - tp = libxfs_trans_alloc(mp, 0); - nres = XFS_REMOVE_SPACE_RES(mp); - error = libxfs_trans_reserve(tp, nres, XFS_REMOVE_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT); - if (error) - res_failed(error); - libxfs_trans_ijoin(tp, ip, 0); - libxfs_trans_ihold(tp, ip); - - if ((error = libxfs_bmap_last_offset(tp, ip, &lastblock, - XFS_DATA_FORK))) - do_error(_("xfs_bmap_last_offset failed -- error - %d\n"), - error); - - /* free all data, leaf, node and freespace blocks */ - error = libxfs_bunmapi(tp, ip, 0, lastblock, XFS_BMAPI_METADATA, 0, - &firstblock, &flist, &done); - if (error) { - do_warn(_("xfs_bunmapi failed -- error - %d\n"), error); - libxfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | - XFS_TRANS_ABORT); - return; - } - - ASSERT(done); - - libxfs_dir_init(tp, ip, &pip); - - error = libxfs_bmap_finish(&tp, &flist, &committed); - - libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); - - /* go through the hash list and re-add the inodes */ - - for (p = hashtab->first; p; p = p->nextbyorder) { - - if (p->name.name[0] == '/' || (p->name.name[0] == '.' && - (p->name.len == 1 || (p->name.len == 2 && - p->name.name[1] == '.')))) - continue; - - tp = libxfs_trans_alloc(mp, 0); - nres = XFS_CREATE_SPACE_RES(mp, p->name.len); - error = libxfs_trans_reserve(tp, nres, XFS_CREATE_LOG_RES(mp), - 0, XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT); - if (error) { - do_warn( - _("space reservation failed (%d), filesystem may be out of space\n"), - error); - break; - } - - libxfs_trans_ijoin(tp, ip, 0); - libxfs_trans_ihold(tp, ip); - - xfs_bmap_init(&flist, &firstblock); - error = libxfs_dir_createname(tp, ip, &p->name, p->inum, - &firstblock, &flist, nres); - if (error) { - do_warn( -_("name create failed in ino %" PRIu64 " (%d), filesystem may be out of space\n"), - ino, error); - libxfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | - XFS_TRANS_ABORT); - break; + libxfs_trans_ijoin(tp, ip, 0); + + xfs_bmap_init(&flist, &firstblock); + error = libxfs_dir_createname(tp, ip, &p->name, p->inum, + &firstblock, &flist, nres); + if (error) { + do_warn( +_("name create failed in ino %" PRIu64 " (%d), filesystem may be out of space\n"), + ino, error); + goto out_bmap_cancel; } error = libxfs_bmap_finish(&tp, &flist, &committed); @@ -1769,15 +1387,19 @@ do_warn( _("bmap finish failed (%d), filesystem may be out of space\n"), error); - libxfs_bmap_cancel(&flist); - libxfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | - XFS_TRANS_ABORT); - break; + goto out_bmap_cancel; } libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); } + + return; + +out_bmap_cancel: + libxfs_bmap_cancel(&flist); + libxfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); + return; } @@ -1790,7 +1412,7 @@ xfs_mount_t *mp, xfs_inode_t *ip, xfs_dablk_t da_bno, - xfs_dabuf_t *bp) + struct xfs_buf *bp) { xfs_da_args_t args; int committed; @@ -1802,13 +1424,11 @@ tp = libxfs_trans_alloc(mp, 0); nres = XFS_REMOVE_SPACE_RES(mp); - error = libxfs_trans_reserve(tp, nres, XFS_REMOVE_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT); + error = libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove, nres, 0); if (error) res_failed(error); libxfs_trans_ijoin(tp, ip, 0); - libxfs_trans_ihold(tp, ip); - libxfs_da_bjoin(tp, bp); + libxfs_trans_bjoin(tp, bp); memset(&args, 0, sizeof(args)); xfs_bmap_init(&flist, &firstblock); args.dp = ip; @@ -1840,7 +1460,7 @@ int *need_dot, ino_tree_node_t *current_irec, int current_ino_offset, - xfs_dabuf_t **bpp, + struct xfs_buf **bpp, dir_hash_tab_t *hashtab, freetab_t **freetabp, xfs_dablk_t da_bno, @@ -1848,13 +1468,14 @@ { xfs_dir2_dataptr_t addr; xfs_dir2_leaf_entry_t *blp; - xfs_dabuf_t *bp; + struct xfs_buf *bp; xfs_dir2_block_tail_t *btp; int committed; - xfs_dir2_data_t *d; + struct xfs_dir2_data_hdr *d; xfs_dir2_db_t db; xfs_dir2_data_entry_t *dep; xfs_dir2_data_unused_t *dup; + struct xfs_dir2_data_free *bf; char *endptr; int error; xfs_fsblock_t firstblock; @@ -1877,22 +1498,28 @@ int wantmagic; bp = *bpp; - d = bp->data; - ptr = (char *)d->u; + d = bp->b_addr; + ptr = (char *)xfs_dir3_data_entry_p(d); nbad = 0; needscan = needlog = 0; junkit = 0; freetab = *freetabp; if (isblock) { - btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); + btp = xfs_dir2_block_tail_p(mp, (struct xfs_dir2_data_hdr *)d); blp = xfs_dir2_block_leaf_p(btp); endptr = (char *)blp; if (endptr > (char *)btp) endptr = (char *)btp; - wantmagic = XFS_DIR2_BLOCK_MAGIC; + if (xfs_sb_version_hascrc(&mp->m_sb)) + wantmagic = XFS_DIR3_BLOCK_MAGIC; + else + wantmagic = XFS_DIR2_BLOCK_MAGIC; } else { endptr = (char *)d + mp->m_dirblksize; - wantmagic = XFS_DIR2_DATA_MAGIC; + if (xfs_sb_version_hascrc(&mp->m_sb)) + wantmagic = XFS_DIR3_DATA_MAGIC; + else + wantmagic = XFS_DIR2_DATA_MAGIC; } db = xfs_dir2_da_to_db(mp, da_bno); @@ -1902,9 +1529,8 @@ *freetabp = freetab = realloc(freetab, FREETAB_SIZE(db + 1)); if (!freetab) { - do_error( - _("realloc failed in longform_dir2_entry_check_data (%zu bytes)\n"), - FREETAB_SIZE(db + 1)); + do_error(_("realloc failed in %s (%zu bytes)\n"), + __func__, FREETAB_SIZE(db + 1)); } e.v = NULLDATAOFF; e.s = 0; @@ -1933,8 +1559,8 @@ break; /* check for block with no data entries */ - if ((ptr == (char *)d->u) && (ptr + - be16_to_cpu(dup->length) >= endptr)) { + if ((ptr == (char *)xfs_dir3_data_entry_p(d)) && + (ptr + be16_to_cpu(dup->length) >= endptr)) { junkit = 1; *num_illegal += 1; break; @@ -1948,12 +1574,12 @@ /* validate data entry size */ dep = (xfs_dir2_data_entry_t *)ptr; - if (ptr + xfs_dir2_data_entsize(dep->namelen) > endptr) + if (ptr + xfs_dir3_data_entsize(mp, dep->namelen) > endptr) break; - if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) != + if (be16_to_cpu(*xfs_dir3_data_entry_tag_p(mp, dep)) != (char *)dep - (char *)d) break; - ptr += xfs_dir2_data_entsize(dep->namelen); + ptr += xfs_dir3_data_entsize(mp, dep->namelen); } /* did we find an empty or corrupt block? */ @@ -1972,7 +1598,7 @@ dir2_kill_block(mp, ip, da_bno, bp); } else { do_warn(_("would junk block\n")); - libxfs_da_brelse(NULL, bp); + libxfs_putbuf(bp); } freetab->ents[db].v = NULLDATAOFF; *bpp = NULL; @@ -1984,28 +1610,26 @@ freetab->nents = db + 1; tp = libxfs_trans_alloc(mp, 0); - error = libxfs_trans_reserve(tp, 0, XFS_REMOVE_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT); + error = libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove, 0, 0); if (error) res_failed(error); libxfs_trans_ijoin(tp, ip, 0); - libxfs_trans_ihold(tp, ip); - libxfs_da_bjoin(tp, bp); - libxfs_da_bhold(tp, bp); + libxfs_trans_bjoin(tp, bp); + libxfs_trans_bhold(tp, bp); xfs_bmap_init(&flist, &firstblock); - if (be32_to_cpu(d->hdr.magic) != wantmagic) { + if (be32_to_cpu(d->magic) != wantmagic) { do_warn( _("bad directory block magic # %#x for directory inode %" PRIu64 " block %d: "), - be32_to_cpu(d->hdr.magic), ip->i_ino, da_bno); + be32_to_cpu(d->magic), ip->i_ino, da_bno); if (!no_modify) { do_warn(_("fixing magic # to %#x\n"), wantmagic); - d->hdr.magic = cpu_to_be32(wantmagic); + d->magic = cpu_to_be32(wantmagic); needlog = 1; } else do_warn(_("would fix magic # to %#x\n"), wantmagic); } lastfree = 0; - ptr = (char *)d->u; + ptr = (char *)xfs_dir3_data_entry_p(d); /* * look at each entry. reference inode pointed to by each * entry in the incore inode tree. @@ -2043,7 +1667,7 @@ } addr = xfs_dir2_db_off_to_dataptr(mp, db, ptr - (char *)d); dep = (xfs_dir2_data_entry_t *)ptr; - ptr += xfs_dir2_data_entsize(dep->namelen); + ptr += xfs_dir3_data_entsize(mp, dep->namelen); inum = be64_to_cpu(dep->inumber); lastfree = 0; /* @@ -2116,11 +1740,12 @@ if (!orphanage_ino) orphanage_ino = inum; } + /* * check for duplicate names in directory. */ if (!dir_hash_add(mp, hashtab, addr, inum, dep->namelen, - dep->name)) { + dep->name, xfs_dir3_dirent_get_ftype(mp, dep))) { nbad++; if (entry_junked( _("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is a duplicate name"), @@ -2175,7 +1800,8 @@ if (ip->i_ino == inum) { ASSERT(dep->name[0] == '.' && dep->namelen == 1); add_inode_ref(current_irec, current_ino_offset); - if (da_bno != 0 || dep != (xfs_dir2_data_entry_t *)d->u) { + if (da_bno != 0 || + dep != xfs_dir3_data_entry_p(d)) { /* "." should be the first entry */ nbad++; if (entry_junked( @@ -2193,6 +1819,35 @@ */ if (no_modify && verify_inum(mp, inum)) continue; + + /* validate ftype field if supported */ + if (xfs_sb_version_hasftype(&mp->m_sb)) { + __uint8_t dir_ftype; + __uint8_t ino_ftype; + + dir_ftype = xfs_dir3_dirent_get_ftype(mp, dep); + ino_ftype = get_inode_ftype(irec, ino_offset); + + if (dir_ftype != ino_ftype) { + if (no_modify) { + do_warn( + _("would fix ftype mismatch (%d/%d) in directory/child inode %" PRIu64 "/%" PRIu64 "\n"), + dir_ftype, ino_ftype, + ip->i_ino, inum); + } else { + do_warn( + _("fixing ftype mismatch (%d/%d) in directory/child inode %" PRIu64 "/%" PRIu64 "\n"), + dir_ftype, ino_ftype, + ip->i_ino, inum); + xfs_dir3_dirent_put_ftype(mp, dep, + ino_ftype); + libxfs_dir2_data_log_entry(tp, bp, dep); + dir_hash_update_ftype(hashtab, addr, + ino_ftype); + } + } + } + /* * check easy case first, regular inode, just bump * the link count and continue @@ -2239,7 +1894,6 @@ if (junkit) { if (inum == orphanage_ino) orphanage_ino = 0; - junkit = 0; nbad++; if (!no_modify) { dep->name[0] = '/'; @@ -2261,7 +1915,10 @@ libxfs_dir2_data_log_header(tp, bp); libxfs_bmap_finish(&tp, &flist, &committed); libxfs_trans_commit(tp, 0); - freetab->ents[db].v = be16_to_cpu(d->hdr.bestfree[0].length); + + /* record the largest free space in the freetab for later checking */ + bf = xfs_dir3_data_bestfree_p(d); + freetab->ents[db].v = be16_to_cpu(bf[0].length); freetab->ents[db].s = 0; } @@ -2277,43 +1934,48 @@ { int badtail; __be16 *bestsp; - xfs_dabuf_t *bp; + struct xfs_buf *bp; xfs_dablk_t da_bno; int i; xfs_dir2_leaf_t *leaf; xfs_dir2_leaf_tail_t *ltp; int seeval; + struct xfs_dir2_leaf_entry *ents; + struct xfs_dir3_icleaf_hdr leafhdr; + int error; + int fixit = 0; da_bno = mp->m_dirleafblk; - if (libxfs_da_read_bufr(NULL, ip, da_bno, -1, &bp, XFS_DATA_FORK)) { + error = dir_read_buf(ip, da_bno, -1, &bp, &xfs_dir3_leaf1_buf_ops, + &fixit); + if (error) { do_error( - _("can't read block %u for directory inode %" PRIu64 "\n"), - da_bno, ip->i_ino); + _("can't read block %u for directory inode %" PRIu64 ", error %d\n"), + da_bno, ip->i_ino, error); /* NOTREACHED */ } - leaf = bp->data; + + leaf = bp->b_addr; + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + ents = xfs_dir3_leaf_ents_p(leaf); ltp = xfs_dir2_leaf_tail_p(mp, leaf); bestsp = xfs_dir2_leaf_bests_p(ltp); - if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAF1_MAGIC || - be32_to_cpu(leaf->hdr.info.forw) || - be32_to_cpu(leaf->hdr.info.back) || - be16_to_cpu(leaf->hdr.count) < - be16_to_cpu(leaf->hdr.stale) || - be16_to_cpu(leaf->hdr.count) > - xfs_dir2_max_leaf_ents(mp) || - (char *)&leaf->ents[be16_to_cpu( - leaf->hdr.count)] > (char *)bestsp) { + if (!(leafhdr.magic == XFS_DIR2_LEAF1_MAGIC || + leafhdr.magic == XFS_DIR3_LEAF1_MAGIC) || + leafhdr.forw || leafhdr.back || + leafhdr.count < leafhdr.stale || + leafhdr.count > + xfs_dir3_max_leaf_ents(mp, leaf) || + (char *)&ents[leafhdr.count] > (char *)bestsp) { do_warn( _("leaf block %u for directory inode %" PRIu64 " bad header\n"), da_bno, ip->i_ino); - libxfs_da_brelse(NULL, bp); + libxfs_putbuf(bp); return 1; } - seeval = dir_hash_see_all(hashtab, leaf->ents, - be16_to_cpu(leaf->hdr.count), - be16_to_cpu(leaf->hdr.stale)); + seeval = dir_hash_see_all(hashtab, ents, leafhdr.count, leafhdr.stale); if (dir_hash_check(hashtab, ip, seeval)) { - libxfs_da_brelse(NULL, bp); + libxfs_putbuf(bp); return 1; } badtail = freetab->nents != be32_to_cpu(ltp->bestcount); @@ -2325,11 +1987,11 @@ do_warn( _("leaf block %u for directory inode %" PRIu64 " bad tail\n"), da_bno, ip->i_ino); - libxfs_da_brelse(NULL, bp); + libxfs_putbuf(bp); return 1; } - libxfs_da_brelse(NULL, bp); - return 0; + libxfs_putbuf(bp); + return fixit; } /* @@ -2343,7 +2005,7 @@ dir_hash_tab_t *hashtab, freetab_t *freetab) { - xfs_dabuf_t *bp; + struct xfs_buf *bp; xfs_dablk_t da_bno; xfs_dir2_db_t fdb; xfs_dir2_free_t *free; @@ -2352,6 +2014,12 @@ xfs_fileoff_t next_da_bno; int seeval = 0; int used; + struct xfs_dir2_leaf_entry *ents; + struct xfs_dir3_icleaf_hdr leafhdr; + struct xfs_dir3_icfree_hdr freehdr; + __be16 *bests; + int error; + int fixit = 0; for (da_bno = mp->m_dirleafblk, next_da_bno = 0; next_da_bno != NULLFILEOFF && da_bno < mp->m_dirfreeblk; @@ -2359,40 +2027,55 @@ next_da_bno = da_bno + mp->m_dirblkfsbs - 1; if (bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK)) break; - if (libxfs_da_read_bufr(NULL, ip, da_bno, -1, &bp, - XFS_DATA_FORK)) { + + /* + * we need to use the da3 node verifier here as it handles the + * fact that reading the leaf hash tree blocks can return either + * leaf or node blocks and calls the correct verifier. If we get + * a node block, then we'll skip it below based on a magic + * number check. + */ + error = dir_read_buf(ip, da_bno, -1, &bp, + &xfs_da3_node_buf_ops, &fixit); + if (error) { do_warn( - _("can't read leaf block %u for directory inode %" PRIu64 "\n"), - da_bno, ip->i_ino); + _("can't read leaf block %u for directory inode %" PRIu64 ", error %d\n"), + da_bno, ip->i_ino, error); return 1; } - leaf = bp->data; - if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAFN_MAGIC) { - if (be16_to_cpu(leaf->hdr.info.magic) == - XFS_DA_NODE_MAGIC) { - libxfs_da_brelse(NULL, bp); + leaf = bp->b_addr; + xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); + ents = xfs_dir3_leaf_ents_p(leaf); + if (!(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || + leafhdr.magic == XFS_DIR3_LEAFN_MAGIC)) { + if (leafhdr.magic == XFS_DA_NODE_MAGIC || + leafhdr.magic == XFS_DA3_NODE_MAGIC) { + libxfs_putbuf(bp); continue; } do_warn( _("unknown magic number %#x for block %u in directory inode %" PRIu64 "\n"), - be16_to_cpu(leaf->hdr.info.magic), - da_bno, ip->i_ino); - libxfs_da_brelse(NULL, bp); + leafhdr.magic, da_bno, ip->i_ino); + libxfs_putbuf(bp); return 1; } - if (be16_to_cpu(leaf->hdr.count) > xfs_dir2_max_leaf_ents(mp) || - be16_to_cpu(leaf->hdr.count) < - be16_to_cpu(leaf->hdr.stale)) { + + /* + * If there's a validator error, we need to ensure that we got + * the right ops on the buffer for when we write it back out. + */ + bp->b_ops = &xfs_dir3_leafn_buf_ops; + if (leafhdr.count > xfs_dir3_max_leaf_ents(mp, leaf) || + leafhdr.count < leafhdr.stale) { do_warn( _("leaf block %u for directory inode %" PRIu64 " bad header\n"), da_bno, ip->i_ino); - libxfs_da_brelse(NULL, bp); + libxfs_putbuf(bp); return 1; } - seeval = dir_hash_see_all(hashtab, leaf->ents, - be16_to_cpu(leaf->hdr.count), - be16_to_cpu(leaf->hdr.stale)); - libxfs_da_brelse(NULL, bp); + seeval = dir_hash_see_all(hashtab, ents, + leafhdr.count, leafhdr.stale); + libxfs_putbuf(bp); if (seeval != DIR_HASH_CK_OK) return 1; } @@ -2405,50 +2088,52 @@ next_da_bno = da_bno + mp->m_dirblkfsbs - 1; if (bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK)) break; - if (libxfs_da_read_bufr(NULL, ip, da_bno, -1, &bp, - XFS_DATA_FORK)) { + + error = dir_read_buf(ip, da_bno, -1, &bp, + &xfs_dir3_free_buf_ops, &fixit); + if (error) { do_warn( - _("can't read freespace block %u for directory inode %" PRIu64 "\n"), - da_bno, ip->i_ino); + _("can't read freespace block %u for directory inode %" PRIu64 ", error %d\n"), + da_bno, ip->i_ino, error); return 1; } - free = bp->data; + free = bp->b_addr; + xfs_dir3_free_hdr_from_disk(&freehdr, free); + bests = xfs_dir3_free_bests_p(mp, free); fdb = xfs_dir2_da_to_db(mp, da_bno); - if (be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC || - be32_to_cpu(free->hdr.firstdb) != + if (!(freehdr.magic == XFS_DIR2_FREE_MAGIC || + freehdr.magic == XFS_DIR3_FREE_MAGIC) || + freehdr.firstdb != (fdb - XFS_DIR2_FREE_FIRSTDB(mp)) * - XFS_DIR2_MAX_FREE_BESTS(mp) || - be32_to_cpu(free->hdr.nvalid) < - be32_to_cpu(free->hdr.nused)) { + xfs_dir3_free_max_bests(mp) || + freehdr.nvalid < freehdr.nused) { do_warn( _("free block %u for directory inode %" PRIu64 " bad header\n"), da_bno, ip->i_ino); - libxfs_da_brelse(NULL, bp); + libxfs_putbuf(bp); return 1; } - for (i = used = 0; i < be32_to_cpu(free->hdr.nvalid); i++) { - if (i + be32_to_cpu(free->hdr.firstdb) >= - freetab->nents || - freetab->ents[i + be32_to_cpu( - free->hdr.firstdb)].v != - be16_to_cpu(free->bests[i])) { + for (i = used = 0; i < freehdr.nvalid; i++) { + if (i + freehdr.firstdb >= freetab->nents || + freetab->ents[i + freehdr.firstdb].v != + be16_to_cpu(bests[i])) { do_warn( _("free block %u entry %i for directory ino %" PRIu64 " bad\n"), da_bno, i, ip->i_ino); - libxfs_da_brelse(NULL, bp); + libxfs_putbuf(bp); return 1; } - used += be16_to_cpu(free->bests[i]) != NULLDATAOFF; - freetab->ents[i + be32_to_cpu(free->hdr.firstdb)].s = 1; + used += be16_to_cpu(bests[i]) != NULLDATAOFF; + freetab->ents[i + freehdr.firstdb].s = 1; } - if (used != be32_to_cpu(free->hdr.nused)) { + if (used != freehdr.nused) { do_warn( _("free block %u for directory inode %" PRIu64 " bad nused\n"), da_bno, ip->i_ino); - libxfs_da_brelse(NULL, bp); + libxfs_putbuf(bp); return 1; } - libxfs_da_brelse(NULL, bp); + libxfs_putbuf(bp); } for (i = 0; i < freetab->nents; i++) { if ((freetab->ents[i].s == 0) && @@ -2459,7 +2144,7 @@ return 1; } } - return 0; + return fixit; } /* @@ -2477,8 +2162,7 @@ int ino_offset, dir_hash_tab_t *hashtab) { - xfs_dir2_block_t *block; - xfs_dabuf_t **bplist; + struct xfs_buf **bplist; xfs_dablk_t da_bno; freetab_t *freetab; int num_bps; @@ -2487,14 +2171,14 @@ int isleaf; xfs_fileoff_t next_da_bno; int seeval; - int fixit; + int fixit = 0; xfs_dir2_db_t db; *need_dot = 1; freetab = malloc(FREETAB_SIZE(ip->i_d.di_size / mp->m_dirblksize)); if (!freetab) { - do_error( - _("malloc failed in longform_dir2_entry_check (%" PRId64 " bytes)\n"), + do_error(_("malloc failed in %s (%" PRId64 " bytes)\n"), + __func__, FREETAB_SIZE(ip->i_d.di_size / mp->m_dirblksize)); exit(1); } @@ -2505,7 +2189,11 @@ freetab->ents[i].s = 0; } num_bps = freetab->naents; - bplist = calloc(num_bps, sizeof(xfs_dabuf_t*)); + bplist = calloc(num_bps, sizeof(struct xfs_buf*)); + if (!bplist) + do_error(_("calloc failed in %s (%zu bytes)\n"), + __func__, num_bps * sizeof(struct xfs_buf*)); + /* is this a block, leaf, or node directory? */ libxfs_dir2_isblock(NULL, ip, &isblock); libxfs_dir2_isleaf(NULL, ip, &isleaf); @@ -2514,40 +2202,70 @@ for (da_bno = 0, next_da_bno = 0; next_da_bno != NULLFILEOFF && da_bno < mp->m_dirleafblk; da_bno = (xfs_dablk_t)next_da_bno) { + const struct xfs_buf_ops *ops; + int error; + next_da_bno = da_bno + mp->m_dirblkfsbs - 1; - if (bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK)) + if (bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK)) { + /* + * if this is the first block, there isn't anything we + * can recover so we just trash it. + */ + if (da_bno == 0) { + fixit++; + goto out_fix; + } break; + } + db = xfs_dir2_da_to_db(mp, da_bno); if (db >= num_bps) { /* more data blocks than expected */ num_bps = db + 1; - bplist = realloc(bplist, num_bps * sizeof(xfs_dabuf_t*)); + bplist = realloc(bplist, num_bps * sizeof(struct xfs_buf*)); if (!bplist) - do_error( - _("realloc failed in longform_dir2_entry_check (%zu bytes)\n"), - num_bps * sizeof(xfs_dabuf_t*)); + do_error(_("realloc failed in %s (%zu bytes)\n"), + __func__, + num_bps * sizeof(struct xfs_buf*)); } - if (libxfs_da_read_bufr(NULL, ip, da_bno, -1, &bplist[db], - XFS_DATA_FORK)) { + + if (isblock) + ops = &xfs_dir3_block_buf_ops; + else + ops = &xfs_dir3_data_buf_ops; + + error = dir_read_buf(ip, da_bno, -1, &bplist[db], ops, &fixit); + if (error) { do_warn( - _("can't read data block %u for directory inode %" PRIu64 "\n"), - da_bno, ino); + _("can't read data block %u for directory inode %" PRIu64 " error %d\n"), + da_bno, ino, error); *num_illegal += 1; - continue; /* try and read all "data" blocks */ + + /* + * we try to read all "data" blocks, but if we are in + * block form and we fail, there isn't anything else to + * read, and nothing we can do but trash it. + */ + if (isblock) { + fixit++; + goto out_fix; + } + continue; } longform_dir2_entry_check_data(mp, ip, num_illegal, need_dot, irec, ino_offset, &bplist[db], hashtab, &freetab, da_bno, isblock); } - fixit = (*num_illegal != 0) || dir2_is_badino(ino) || *need_dot; + fixit |= (*num_illegal != 0) || dir2_is_badino(ino) || *need_dot; if (!dotdot_update) { /* check btree and freespace */ if (isblock) { + struct xfs_dir2_data_hdr *block; xfs_dir2_block_tail_t *btp; xfs_dir2_leaf_entry_t *blp; - block = bplist[0]->data; + block = bplist[0]->b_addr; btp = xfs_dir2_block_tail_p(mp, block); blp = xfs_dir2_block_leaf_p(btp); seeval = dir_hash_see_all(hashtab, blp, @@ -2563,18 +2281,19 @@ freetab); } } +out_fix: if (!no_modify && (fixit || dotdot_update)) { dir_hash_dup_names(hashtab); for (i = 0; i < freetab->naents; i++) if (bplist[i]) - libxfs_da_brelse(NULL, bplist[i]); + libxfs_putbuf(bplist[i]); longform_dir2_rebuild(mp, ino, ip, irec, ino_offset, hashtab); *num_illegal = 0; *need_dot = 0; } else { for (i = 0; i < freetab->naents; i++) if (bplist[i]) - libxfs_da_brelse(NULL, bplist[i]); + libxfs_putbuf(bplist[i]); } free(bplist); @@ -2582,307 +2301,65 @@ } /* - * shortform directory processing routines -- entry verification and + * shortform directory v2 processing routines -- entry verification and * bad entry deletion (pruning). */ -static void -shortform_dir_entry_check(xfs_mount_t *mp, - xfs_ino_t ino, - xfs_inode_t *ip, - int *ino_dirty, - ino_tree_node_t *current_irec, - int current_ino_offset, - dir_hash_tab_t *hashtab) +static struct xfs_dir2_sf_entry * +shortform_dir2_junk( + struct xfs_mount *mp, + struct xfs_dir2_sf_hdr *sfp, + struct xfs_dir2_sf_entry *sfep, + xfs_ino_t lino, + int *max_size, + int *index, + int *bytes_deleted, + int *ino_dirty) { - xfs_ino_t lino; - xfs_ino_t parent; - xfs_dir_shortform_t *sf; - xfs_dir_sf_entry_t *sf_entry, *next_sfe, *tmp_sfe; - xfs_ifork_t *ifp; - ino_tree_node_t *irec; - int max_size; - int ino_offset; - int i; - int junkit; - int tmp_len; - int tmp_elen; - int bad_sfnamelen; - int namelen; - int bytes_deleted; - char fname[MAXNAMELEN + 1]; + struct xfs_dir2_sf_entry *next_sfep; + int next_len; + int next_elen; - ifp = &ip->i_df; - sf = (xfs_dir_shortform_t *) ifp->if_u1.if_data; - *ino_dirty = 0; - bytes_deleted = 0; + if (lino == orphanage_ino) + orphanage_ino = 0; - max_size = ifp->if_bytes; - ASSERT(ip->i_d.di_size <= ifp->if_bytes); + next_elen = xfs_dir3_sf_entsize(mp, sfp, sfep->namelen); + next_sfep = (xfs_dir2_sf_entry_t *)((__psint_t)sfep + next_elen); /* - * no '.' entry in shortform dirs, just bump up ref count by 1 - * '..' was already (or will be) accounted for and checked when - * the directory is reached or will be taken care of when the - * directory is moved to orphanage. + * if we are just checking, simply return the pointer to the next entry + * here so that the checking loop can continue. */ - add_inode_ref(current_irec, current_ino_offset); + if (no_modify) { + do_warn(_("would junk entry\n")); + return next_sfep; + } /* - * now run through entries, stop at first bad entry, don't need - * to skip over '..' since that's encoded in its own field and - * no need to worry about '.' since it doesn't exist. + * now move all the remaining entries down over the junked entry and + * clear the newly unused bytes at the tail of the directory region. */ - sf_entry = next_sfe = &sf->list[0]; - if (sf == NULL) { - junkit = 1; - do_warn( - _("shortform dir inode %" PRIu64 " has null data entries \n"), - ino); - - } - else { - for (i = 0; i < sf->hdr.count && max_size > - (__psint_t)next_sfe - (__psint_t)sf; - sf_entry = next_sfe, i++) { - junkit = 0; - bad_sfnamelen = 0; - tmp_sfe = NULL; - - xfs_dir_sf_get_dirino(&sf_entry->inumber, &lino); - - namelen = sf_entry->namelen; - - ASSERT(no_modify || namelen > 0); - - if (no_modify && namelen == 0) { - /* - * if we're really lucky, this is - * the last entry in which case we - * can use the dir size to set the - * namelen value. otherwise, forget - * it because we're not going to be - * able to find the next entry. - */ - bad_sfnamelen = 1; - - if (i == sf->hdr.count - 1) { - namelen = ip->i_d.di_size - - ((__psint_t) &sf_entry->name[0] - - (__psint_t) sf); - } else { - /* - * don't process the rest of the directory, - * break out of processing looop - */ - break; - } - } else if (no_modify && (__psint_t) sf_entry - (__psint_t) sf + - + xfs_dir_sf_entsize_byentry(sf_entry) - > ip->i_d.di_size) { - bad_sfnamelen = 1; - - if (i == sf->hdr.count - 1) { - namelen = ip->i_d.di_size - - ((__psint_t) &sf_entry->name[0] - - (__psint_t) sf); - } else { - /* - * don't process the rest of the directory, - * break out of processing looop - */ - break; - } - } - - memmove(fname, sf_entry->name, sf_entry->namelen); - fname[sf_entry->namelen] = '\0'; - - ASSERT(no_modify || lino != NULLFSINO); - ASSERT(no_modify || !verify_inum(mp, lino)); - - irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, lino), - XFS_INO_TO_AGINO(mp, lino)); - if (irec == NULL) { - do_warn( - _("entry \"%s\" in shortform dir %" PRIu64 " references non-existent ino %" PRIu64 "\n"), - fname, ino, lino); - goto do_junkit; - } - ino_offset = XFS_INO_TO_AGINO(mp, lino) - irec->ino_startnum; - - /* - * if it's a free inode, blow out the entry. - * by now, any inode that we think is free - * really is free. - */ - if (!is_inode_free(irec, ino_offset)) { - do_warn( - _("entry \"%s\" in shortform dir inode %" PRIu64 " points to free inode %" PRIu64"\n"), - fname, ino, lino); - goto do_junkit; - } - /* - * check if this inode is lost+found dir in the root - */ - if (ino == mp->m_sb.sb_rootino && strcmp(fname, ORPHANAGE) == 0) { - /* - * if it's not a directory, trash it - */ - if (!inode_isadir(irec, ino_offset)) { - do_warn( - _("%s (ino %" PRIu64 ") in root (%" PRIu64 ") is not a directory"), - ORPHANAGE, lino, ino); - goto do_junkit; - } - /* - * if this is a dup, it will be picked up below, - * otherwise, mark it as the orphanage for later. - */ - if (!orphanage_ino) - orphanage_ino = lino; - } - /* - * check for duplicate names in directory. - */ - if (!dir_hash_add(mp, hashtab, (xfs_dir2_dataptr_t) - (sf_entry - &sf->list[0]), lino, - sf_entry->namelen, sf_entry->name)) { - do_warn( -_("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is a duplicate name"), - fname, lino, ino); - goto do_junkit; - } - if (!inode_isadir(irec, ino_offset)) { - /* - * check easy case first, regular inode, just bump - * the link count and continue - */ - add_inode_reached(irec, ino_offset); - - next_sfe = (xfs_dir_sf_entry_t *)((__psint_t)sf_entry + - xfs_dir_sf_entsize_byentry(sf_entry)); - continue; - } else { - parent = get_inode_parent(irec, ino_offset); - - /* - * bump up the link counts in parent and child. - * directory but if the link doesn't agree with - * the .. in the child, blow out the entry - */ - if (is_inode_reached(irec, ino_offset)) { - junkit = 1; - do_warn( - _("entry \"%s\" in dir %" PRIu64 " references already connected dir ino %" PRIu64 ".\n"), - fname, ino, lino); - } else if (parent == ino) { - add_inode_reached(irec, ino_offset); - add_inode_ref(current_irec, current_ino_offset); - } else if (parent == NULLFSINO) { - /* ".." was missing, but this entry refers to it, - so, set it as the parent and mark for rebuild */ - do_warn( - _("entry \"%s\" in dir ino %" PRIu64 " doesn't have a .. entry, will set it in ino %" PRIu64 ".\n"), - fname, ino, lino); - set_inode_parent(irec, ino_offset, ino); - add_inode_reached(irec, ino_offset); - add_inode_ref(current_irec, current_ino_offset); - } else { - junkit = 1; - do_warn( - _("entry \"%s\" in dir %" PRIu64 " not consistent with .. value (%" PRIu64 ") in dir ino %" PRIu64".\n"), - fname, ino, parent, lino); - } - } - if (junkit) { -do_junkit: - if (lino == orphanage_ino) - orphanage_ino = 0; - if (!no_modify) { - tmp_elen = xfs_dir_sf_entsize_byentry(sf_entry); - tmp_sfe = (xfs_dir_sf_entry_t *) - ((__psint_t) sf_entry + tmp_elen); - tmp_len = max_size - ((__psint_t) tmp_sfe - - (__psint_t) sf); - max_size -= tmp_elen; - bytes_deleted += tmp_elen; - - memmove(sf_entry, tmp_sfe, tmp_len); - - sf->hdr.count -= 1; - memset((void *)((__psint_t)sf_entry + tmp_len), - 0, tmp_elen); - - /* - * set the tmp value to the current - * pointer so we'll process the entry - * we just moved up - */ - tmp_sfe = sf_entry; - - /* - * WARNING: drop the index i by one - * so it matches the decremented count for - * accurate comparisons in the loop test - */ - i--; - - *ino_dirty = 1; - - if (verbose) - do_warn(_("junking entry\n")); - else - do_warn("\n"); - } else { - do_warn(_("would junk entry\n")); - } - } - - /* - * go onto next entry unless we've just junked an - * entry in which the current entry pointer points - * to an unprocessed entry. have to take into entries - * with bad namelen into account in no modify mode since we - * calculate size based on next_sfe. - */ - ASSERT(no_modify || bad_sfnamelen == 0); + next_len = *max_size - ((__psint_t)next_sfep - (__psint_t)sfp); + *max_size -= next_elen; + *bytes_deleted += next_elen; - next_sfe = (tmp_sfe == NULL) - ? (xfs_dir_sf_entry_t *) ((__psint_t) sf_entry - + ((!bad_sfnamelen) - ? xfs_dir_sf_entsize_byentry(sf_entry) - : sizeof(xfs_dir_sf_entry_t) - 1 - + namelen)) - : tmp_sfe; - } - } + memmove(sfep, next_sfep, next_len); + memset((void *)((__psint_t)sfep + next_len), 0, next_elen); + sfp->count -= 1; + *ino_dirty = 1; /* - * sync up sizes if required + * WARNING: drop the index i by one so it matches the decremented count + * for accurate comparisons in the loop test */ - if (*ino_dirty) { - ASSERT(bytes_deleted > 0); - ASSERT(!no_modify); - libxfs_idata_realloc(ip, -bytes_deleted, XFS_DATA_FORK); - ip->i_d.di_size -= bytes_deleted; - } + (*index)--; - if (ip->i_d.di_size != ip->i_df.if_bytes) { - ASSERT(ip->i_df.if_bytes == (xfs_fsize_t) - ((__psint_t) next_sfe - (__psint_t) sf)); - ip->i_d.di_size = (xfs_fsize_t) - ((__psint_t) next_sfe - (__psint_t) sf); - do_warn( - _("setting size to %" PRId64 " bytes to reflect junked entries\n"), - ip->i_d.di_size); - *ino_dirty = 1; - } + if (verbose) + do_warn(_("junking entry\n")); + else + do_warn("\n"); + return sfep; } -/* - * shortform directory v2 processing routines -- entry verification and - * bad entry deletion (pruning). - */ static void shortform_dir2_entry_check(xfs_mount_t *mp, xfs_ino_t ino, @@ -2894,16 +2371,14 @@ { xfs_ino_t lino; xfs_ino_t parent; - xfs_dir2_sf_t *sfp; - xfs_dir2_sf_entry_t *sfep, *next_sfep, *tmp_sfep; - xfs_ifork_t *ifp; - ino_tree_node_t *irec; + struct xfs_dir2_sf_hdr *sfp; + struct xfs_dir2_sf_entry *sfep; + struct xfs_dir2_sf_entry *next_sfep; + struct xfs_ifork *ifp; + struct ino_tree_node *irec; int max_size; int ino_offset; int i; - int junkit; - int tmp_len; - int tmp_elen; int bad_sfnamelen; int namelen; int bytes_deleted; @@ -2911,7 +2386,7 @@ int i8; ifp = &ip->i_df; - sfp = (xfs_dir2_sf_t *) ifp->if_u1.if_data; + sfp = (struct xfs_dir2_sf_hdr *) ifp->if_u1.if_data; *ino_dirty = 0; bytes_deleted = 0; @@ -2931,7 +2406,7 @@ do_warn( _("setting .. in sf dir inode %" PRIu64 " to %" PRIu64 "\n"), ino, parent); - xfs_dir2_sf_put_inumber(sfp, &parent, &sfp->hdr.parent); + xfs_dir2_sf_put_parent_ino(sfp, parent); *ino_dirty = 1; } return; @@ -2948,8 +2423,7 @@ /* * Initialise i8 counter -- the parent inode number counts as well. */ - i8 = (xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent) > - XFS_DIR2_MAX_SHORT_INUM); + i8 = xfs_dir2_sf_get_parent_ino(sfp) > XFS_DIR2_MAX_SHORT_INUM; /* * now run through entries, stop at first bad entry, don't need @@ -2958,14 +2432,12 @@ */ sfep = next_sfep = xfs_dir2_sf_firstentry(sfp); - for (i = 0; i < sfp->hdr.count && max_size > + for (i = 0; i < sfp->count && max_size > (__psint_t)next_sfep - (__psint_t)sfp; sfep = next_sfep, i++) { - junkit = 0; bad_sfnamelen = 0; - tmp_sfep = NULL; - lino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); + lino = xfs_dir3_sfe_get_ino(mp, sfp, sfep); namelen = sfep->namelen; @@ -2982,7 +2454,7 @@ */ bad_sfnamelen = 1; - if (i == sfp->hdr.count - 1) { + if (i == sfp->count - 1) { namelen = ip->i_d.di_size - ((__psint_t) &sfep->name[0] - (__psint_t) sfp); @@ -2994,11 +2466,11 @@ break; } } else if (no_modify && (__psint_t) sfep - (__psint_t) sfp + - + xfs_dir2_sf_entsize_byentry(sfp, sfep) + + xfs_dir3_sf_entsize(mp, sfp, sfep->namelen) > ip->i_d.di_size) { bad_sfnamelen = 1; - if (i == sfp->hdr.count - 1) { + if (i == sfp->count - 1) { namelen = ip->i_d.di_size - ((__psint_t) &sfep->name[0] - (__psint_t) sfp); @@ -3024,7 +2496,7 @@ if (no_modify && verify_inum(mp, lino)) { next_sfep = (xfs_dir2_sf_entry_t *)((__psint_t)sfep + - xfs_dir2_sf_entsize_byentry(sfp, sfep)); + xfs_dir3_sf_entsize(mp, sfp, sfep->namelen)); continue; } @@ -3035,7 +2507,10 @@ do_warn( _("entry \"%s\" in shortform directory %" PRIu64 " references non-existent inode %" PRIu64 "\n"), fname, ino, lino); - goto do_junkit; + next_sfep = shortform_dir2_junk(mp, sfp, sfep, lino, + &max_size, &i, &bytes_deleted, + ino_dirty); + continue; } ino_offset = XFS_INO_TO_AGINO(mp, lino) - irec->ino_startnum; @@ -3049,7 +2524,10 @@ do_warn( _("entry \"%s\" in shortform directory inode %" PRIu64 " points to free inode %" PRIu64 "\n"), fname, ino, lino); - goto do_junkit; + next_sfep = shortform_dir2_junk(mp, sfp, sfep, lino, + &max_size, &i, &bytes_deleted, + ino_dirty); + continue; } /* * check if this inode is lost+found dir in the root @@ -3062,7 +2540,10 @@ do_warn( _("%s (ino %" PRIu64 ") in root (%" PRIu64 ") is not a directory"), ORPHANAGE, lino, ino); - goto do_junkit; + next_sfep = shortform_dir2_junk(mp, sfp, sfep, + lino, &max_size, &i, + &bytes_deleted, ino_dirty); + continue; } /* * if this is a dup, it will be picked up below, @@ -3075,12 +2556,16 @@ * check for duplicate names in directory. */ if (!dir_hash_add(mp, hashtab, (xfs_dir2_dataptr_t) - (sfep - xfs_dir2_sf_firstentry(sfp)), - lino, sfep->namelen, sfep->name)) { + (sfep - xfs_dir2_sf_firstentry(sfp)), + lino, sfep->namelen, sfep->name, + xfs_dir3_sfe_get_ftype(mp, sfp, sfep))) { do_warn( _("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is a duplicate name"), fname, lino, ino); - goto do_junkit; + next_sfep = shortform_dir2_junk(mp, sfp, sfep, lino, + &max_size, &i, &bytes_deleted, + ino_dirty); + continue; } if (!inode_isadir(irec, ino_offset)) { @@ -3098,11 +2583,14 @@ * the .. in the child, blow out the entry */ if (is_inode_reached(irec, ino_offset)) { - junkit = 1; do_warn( _("entry \"%s\" in directory inode %" PRIu64 " references already connected inode %" PRIu64 ".\n"), fname, ino, lino); + next_sfep = shortform_dir2_junk(mp, sfp, sfep, + lino, &max_size, &i, + &bytes_deleted, ino_dirty); + continue; } else if (parent == ino) { add_inode_reached(irec, ino_offset); add_inode_ref(current_irec, current_ino_offset); @@ -3118,91 +2606,78 @@ add_dotdot_update(XFS_INO_TO_AGNO(mp, lino), irec, ino_offset); } else { - junkit = 1; do_warn( _("entry \"%s\" in directory inode %" PRIu64 " not consistent with .. value (%" PRIu64 ") in inode %" PRIu64 ",\n"), fname, ino, parent, lino); + next_sfep = shortform_dir2_junk(mp, sfp, sfep, + lino, &max_size, &i, + &bytes_deleted, ino_dirty); + continue; } } - if (junkit) { -do_junkit: - if (lino == orphanage_ino) - orphanage_ino = 0; - if (!no_modify) { - tmp_elen = xfs_dir2_sf_entsize_byentry(sfp, sfep); - tmp_sfep = (xfs_dir2_sf_entry_t *) - ((__psint_t) sfep + tmp_elen); - tmp_len = max_size - ((__psint_t) tmp_sfep - - (__psint_t) sfp); - max_size -= tmp_elen; - bytes_deleted += tmp_elen; - - memmove(sfep, tmp_sfep, tmp_len); - - sfp->hdr.count -= 1; - memset((void *)((__psint_t)sfep + tmp_len), 0, - tmp_elen); - - /* - * set the tmp value to the current - * pointer so we'll process the entry - * we just moved up - */ - tmp_sfep = sfep; - - /* - * WARNING: drop the index i by one - * so it matches the decremented count for - * accurate comparisons in the loop test - */ - i--; + /* validate ftype field if supported */ + if (xfs_sb_version_hasftype(&mp->m_sb)) { + __uint8_t dir_ftype; + __uint8_t ino_ftype; - *ino_dirty = 1; + dir_ftype = xfs_dir3_sfe_get_ftype(mp, sfp, sfep); + ino_ftype = get_inode_ftype(irec, ino_offset); - if (verbose) - do_warn(_("junking entry\n")); - else - do_warn("\n"); - } else { - do_warn(_("would junk entry\n")); + if (dir_ftype != ino_ftype) { + if (no_modify) { + do_warn( + _("would fix ftype mismatch (%d/%d) in directory/child inode %" PRIu64 "/%" PRIu64 "\n"), + dir_ftype, ino_ftype, + ino, lino); + } else { + do_warn( + _("fixing ftype mismatch (%d/%d) in directory/child inode %" PRIu64 "/%" PRIu64 "\n"), + dir_ftype, ino_ftype, + ino, lino); + xfs_dir3_sfe_put_ftype(mp, sfp, sfep, + ino_ftype); + dir_hash_update_ftype(hashtab, + (xfs_dir2_dataptr_t)(sfep - xfs_dir2_sf_firstentry(sfp)), + ino_ftype); + *ino_dirty = 1; + } } - } else if (lino > XFS_DIR2_MAX_SHORT_INUM) + } + + if (lino > XFS_DIR2_MAX_SHORT_INUM) i8++; /* - * go onto next entry unless we've just junked an - * entry in which the current entry pointer points - * to an unprocessed entry. have to take into entries - * with bad namelen into account in no modify mode since we - * calculate size based on next_sfep. + * go onto next entry - we have to take entries with bad namelen + * into account in no modify mode since we calculate size based + * on next_sfep. */ ASSERT(no_modify || bad_sfnamelen == 0); - - next_sfep = (tmp_sfep == NULL) - ? (xfs_dir2_sf_entry_t *) ((__psint_t) sfep - + ((!bad_sfnamelen) - ? xfs_dir2_sf_entsize_byentry(sfp, sfep) - : xfs_dir2_sf_entsize_byname(sfp, namelen))) - : tmp_sfep; + next_sfep = (struct xfs_dir2_sf_entry *)((__psint_t)sfep + + (bad_sfnamelen + ? xfs_dir3_sf_entsize(mp, sfp, namelen) + : xfs_dir3_sf_entsize(mp, sfp, sfep->namelen))); } - if (sfp->hdr.i8count != i8) { + if (sfp->i8count != i8) { if (no_modify) { do_warn(_("would fix i8count in inode %" PRIu64 "\n"), ino); } else { if (i8 == 0) { + struct xfs_dir2_sf_entry *tmp_sfep; + tmp_sfep = next_sfep; - process_sf_dir2_fixi8(sfp, &tmp_sfep); + process_sf_dir2_fixi8(mp, sfp, &tmp_sfep); bytes_deleted += (__psint_t)next_sfep - (__psint_t)tmp_sfep; next_sfep = tmp_sfep; } else - sfp->hdr.i8count = i8; + sfp->i8count = i8; *ino_dirty = 1; do_warn(_("fixing i8count in inode %" PRIu64 "\n"), ino); @@ -3212,8 +2687,7 @@ /* * sync up sizes if required */ - if (*ino_dirty) { - ASSERT(bytes_deleted > 0); + if (*ino_dirty && bytes_deleted > 0) { ASSERT(!no_modify); libxfs_idata_realloc(ip, -bytes_deleted, XFS_DATA_FORK); ip->i_d.di_size -= bytes_deleted; @@ -3316,16 +2790,10 @@ * the directory is connected to lost+found. but * we need to create '.' entries here. */ - if (xfs_sb_version_hasdirv2(&mp->m_sb)) - longform_dir2_entry_check(mp, ino, ip, - &num_illegal, &need_dot, - irec, ino_offset, - hashtab); - else - longform_dir_entry_check(mp, ino, ip, - &num_illegal, &need_dot, - irec, ino_offset, - hashtab); + longform_dir2_entry_check(mp, ino, ip, + &num_illegal, &need_dot, + irec, ino_offset, + hashtab); break; case XFS_DINODE_FMT_LOCAL: @@ -3337,24 +2805,16 @@ * new define in ourselves. */ nres = no_modify ? 0 : XFS_REMOVE_SPACE_RES(mp); - error = libxfs_trans_reserve(tp, nres, - XFS_REMOVE_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, - XFS_REMOVE_LOG_COUNT); + error = libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove, + nres, 0); if (error) res_failed(error); libxfs_trans_ijoin(tp, ip, 0); - libxfs_trans_ihold(tp, ip); - if (xfs_sb_version_hasdirv2(&mp->m_sb)) - shortform_dir2_entry_check(mp, ino, ip, &dirty, - irec, ino_offset, - hashtab); - else - shortform_dir_entry_check(mp, ino, ip, &dirty, - irec, ino_offset, - hashtab); + shortform_dir2_entry_check(mp, ino, ip, &dirty, + irec, ino_offset, + hashtab); ASSERT(dirty == 0 || (dirty && !no_modify)); if (dirty) { @@ -3375,30 +2835,6 @@ dir_hash_done(hashtab); /* - * We don't support repairing of v1 dir anymore, report errors and exit - */ - if (!xfs_sb_version_hasdirv2(&mp->m_sb)) { - if (need_root_dotdot && ino == mp->m_sb.sb_rootino) - do_warn(_("missing root directory .. entry, cannot " - "fix in V1 dir filesystem\n")); - - if (num_illegal > 0) { - ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_LOCAL); - - do_warn( - _("%d bad entries found in dir inode %" PRIu64 ", cannot fix in V1 dir filesystem\n"), - num_illegal, ino); - } - if (need_dot) { - add_inode_ref(irec, ino_offset); - - do_warn( - _("missing \".\" entry in dir ino %" PRIu64 ", cannot in fix V1 dir filesystem\n"), ino); - } - goto out; - } - - /* * if we have to create a .. for /, do it now *before* * we delete the bogus entries, otherwise the directory * could transform into a shortform dir which would @@ -3417,13 +2853,11 @@ ASSERT(tp != NULL); nres = XFS_MKDIR_SPACE_RES(mp, 2); - error = libxfs_trans_reserve(tp, nres, XFS_MKDIR_LOG_RES(mp), - 0, XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT); + error = libxfs_trans_reserve(tp, &M_RES(mp)->tr_mkdir, nres, 0); if (error) res_failed(error); libxfs_trans_ijoin(tp, ip, 0); - libxfs_trans_ihold(tp, ip); xfs_bmap_init(&flist, &first); @@ -3479,17 +2913,12 @@ ASSERT(tp != NULL); nres = XFS_MKDIR_SPACE_RES(mp, 1); - error = libxfs_trans_reserve(tp, nres, - XFS_MKDIR_LOG_RES(mp), - 0, - XFS_TRANS_PERM_LOG_RES, - XFS_MKDIR_LOG_COUNT); - + error = libxfs_trans_reserve(tp, &M_RES(mp)->tr_mkdir, + nres, 0); if (error) res_failed(error); libxfs_trans_ijoin(tp, ip, 0); - libxfs_trans_ihold(tp, ip); xfs_bmap_init(&flist, &first); @@ -3508,8 +2937,7 @@ |XFS_TRANS_SYNC); } } -out: - libxfs_iput(ip, 0); + IRELE(ip); } /* @@ -3561,6 +2989,15 @@ - irec->ino_startnum; add_inode_reached(irec, offset); } + if (mp->m_sb.sb_pquotino + && mp->m_sb.sb_pquotino != NULLFSINO) { + irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, + mp->m_sb.sb_pquotino), + XFS_INO_TO_AGINO(mp, mp->m_sb.sb_pquotino)); + offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_pquotino) + - irec->ino_startnum; + add_inode_reached(irec, offset); + } } } @@ -3589,10 +3026,8 @@ do_warn(_("disconnected dir inode %" PRIu64 ", "), ino); else do_warn(_("disconnected inode %" PRIu64 ", "), ino); - if (!xfs_sb_version_hasdirv2(&mp->m_sb)) - do_warn(_("cannot fix in V1 dir filesystem\n")); - else if (!no_modify) { - if (!orphanage_ino) + if (!no_modify) { + if (!orphanage_ino) orphanage_ino = mk_orphanage(mp); do_warn(_("moving to %s\n"), ORPHANAGE); mv_orphanage(mp, ino, inode_isadir(irec, i)); @@ -3627,8 +3062,15 @@ if (irec->ino_isa_dir == 0) continue; - if (pf_args) + if (pf_args) { sem_post(&pf_args->ra_count); +#ifdef XR_PF_TRACE + sem_getvalue(&pf_args->ra_count, &i); + pftrace( + "processing inode chunk %p in AG %d (sem count = %d)", + irec, agno, i); +#endif + } for (i = 0; i < XFS_INODES_PER_CHUNK; i++) { if (inode_isadir(irec, i)) @@ -3649,9 +3091,10 @@ * set dotdot_update flag so processing routines do not count links */ dotdot_update = 1; - while (dotdot_update_list) { - dir = dotdot_update_list; - dotdot_update_list = dir->next; + while (!list_empty(&dotdot_update_list)) { + dir = list_entry(dotdot_update_list.prev, struct dotdot_update, + list); + list_del(&dir->list); process_dir_inode(mp, dir->agno, dir->irec, dir->ino_offset); free(dir); } @@ -3659,23 +3102,9 @@ static void traverse_ags( - xfs_mount_t *mp) + struct xfs_mount *mp) { - int i; - work_queue_t queue; - prefetch_args_t *pf_args[2]; - - /* - * we always do prefetch for phase 6 as it will fill in the gaps - * not read during phase 3 prefetch. - */ - queue.mp = mp; - pf_args[0] = start_inode_prefetch(0, 1, NULL); - for (i = 0; i < glob_agcount; i++) { - pf_args[(~i) & 1] = start_inode_prefetch(i + 1, 1, - pf_args[i & 1]); - traverse_function(&queue, i, pf_args[i & 1]); - } + do_inode_prefetch(mp, 0, traverse_function, false, true); } void @@ -3701,10 +3130,7 @@ * inodes in its chunk if a new chunk was created) are ok */ if (need_root_inode) { - if (!xfs_sb_version_hasdirv2(&mp->m_sb)) - do_warn(_("need to reinitialize root directory, " - "but not supported on V1 dir filesystem\n")); - else if (!no_modify) { + if (!no_modify) { do_warn(_("reinitializing root directory\n")); mk_root_dir(mp); need_root_inode = 0; diff -Nru xfsprogs-3.1.9ubuntu2/repair/phase7.c xfsprogs-3.2.1ubuntu1/repair/phase7.c --- xfsprogs-3.1.9ubuntu2/repair/phase7.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/phase7.c 2014-06-19 22:42:17.000000000 +0000 @@ -68,13 +68,12 @@ xfs_inode_t *ip; int error; int dirty; + int nres; tp = libxfs_trans_alloc(mp, XFS_TRANS_REMOVE); - error = libxfs_trans_reserve(tp, (no_modify ? 0 : 10), - XFS_REMOVE_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, - XFS_REMOVE_LOG_COUNT); - + nres = no_modify ? 0 : 10; + error = libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove, nres, 0); ASSERT(error == 0); error = libxfs_trans_iget(mp, tp, ino, 0, 0, &ip); @@ -100,7 +99,6 @@ set_nlinks(&ip->i_d, ino, nlinks, &dirty); if (!dirty) { - libxfs_trans_iput(tp, ip, 0); libxfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES); } else { libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); @@ -114,6 +112,7 @@ ASSERT(error == 0); } + IRELE(ip); } void diff -Nru xfsprogs-3.1.9ubuntu2/repair/prefetch.c xfsprogs-3.2.1ubuntu1/repair/prefetch.c --- xfsprogs-3.1.9ubuntu2/repair/prefetch.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/prefetch.c 2014-06-19 22:42:17.000000000 +0000 @@ -5,7 +5,6 @@ #include "globals.h" #include "agheader.h" #include "incore.h" -#include "dir.h" #include "dir2.h" #include "protos.h" #include "err_protos.h" @@ -106,11 +105,12 @@ static void pf_queue_io( prefetch_args_t *args, - xfs_fsblock_t fsbno, - int blen, + struct xfs_buf_map *map, + int nmaps, int flag) { - xfs_buf_t *bp; + struct xfs_buf *bp; + xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, map[0].bm_bn); /* * Never block on a buffer lock here, given that the actual repair @@ -118,8 +118,7 @@ * the lock holder is either reading it from disk himself or * completely overwriting it this behaviour is perfectly fine. */ - bp = libxfs_getbuf_flags(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), - XFS_FSB_TO_BB(mp, blen), LIBXFS_GETBUF_TRYLOCK); + bp = libxfs_getbuf_map(mp->m_dev, map, nmaps, LIBXFS_GETBUF_TRYLOCK); if (!bp) return; @@ -168,6 +167,14 @@ xfs_bmbt_irec_t irec; xfs_dfilblks_t cp = 0; /* prev count */ xfs_dfiloff_t op = 0; /* prev offset */ +#define MAP_ARRAY_SZ 4 + struct xfs_buf_map map_array[MAP_ARRAY_SZ]; + struct xfs_buf_map *map = map_array; + int max_extents = MAP_ARRAY_SZ; + int nmaps = 0;; + unsigned int len = 0; + int ret = 0; + for (i = 0; i < numrecs; i++) { libxfs_bmbt_disk_get_all(rp + i, &irec); @@ -175,11 +182,11 @@ if (((i > 0) && (op + cp > irec.br_startoff)) || (irec.br_blockcount == 0) || (irec.br_startoff >= fs_max_file_offset)) - return 0; + goto out_free; if (!verify_dfsbno(mp, irec.br_startblock) || !verify_dfsbno(mp, irec.br_startblock + irec.br_blockcount - 1)) - return 0; + goto out_free; if (!args->dirs_only && ((irec.br_startoff + irec.br_blockcount) >= mp->m_dirfreeblk)) @@ -189,18 +196,59 @@ cp = irec.br_blockcount; while (irec.br_blockcount) { - unsigned int len; + unsigned int bm_len; pftrace("queuing dir extent in AG %d", args->agno); - len = (irec.br_blockcount > mp->m_dirblkfsbs) ? - mp->m_dirblkfsbs : irec.br_blockcount; - pf_queue_io(args, irec.br_startblock, len, B_DIR_META); - irec.br_blockcount -= len; - irec.br_startblock += len; + if (len + irec.br_blockcount >= mp->m_dirblkfsbs) + bm_len = mp->m_dirblkfsbs - len; + else + bm_len = irec.br_blockcount; + len += bm_len; + + map[nmaps].bm_bn = XFS_FSB_TO_DADDR(mp, + irec.br_startblock); + map[nmaps].bm_len = XFS_FSB_TO_BB(mp, bm_len); + nmaps++; + + if (len == mp->m_dirblkfsbs) { + pf_queue_io(args, map, nmaps, B_DIR_META); + len = 0; + nmaps = 0; + } + + irec.br_blockcount -= bm_len; + irec.br_startblock += bm_len; + + /* + * Handle very fragmented dir2 blocks with dynamically + * allocated buffer maps. + */ + if (nmaps >= max_extents) { + struct xfs_buf_map *old_map = NULL; + + if (map == map_array) { + old_map = map; + map = NULL; + } + max_extents *= 2; + map = realloc(map, max_extents * sizeof(*map)); + if (map == NULL) { + do_error( + _("couldn't malloc dir2 buffer list\n")); + exit(1); + } + if (old_map) + memcpy(map, old_map, sizeof(map_array)); + } + } } - return 1; + ret = 1; +out_free: + if (map != map_array) + free(map); + return ret; } /* @@ -222,7 +270,7 @@ int rc; bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, dbno), - XFS_FSB_TO_BB(mp, 1), 0); + XFS_FSB_TO_BB(mp, 1), 0, &xfs_bmbt_buf_ops); if (!bp) return 0; @@ -250,7 +298,8 @@ /* * do some validation on the block contents */ - if ((be32_to_cpu(block->bb_magic) != XFS_BMAP_MAGIC) || + if ((block->bb_magic != cpu_to_be32(XFS_BMAP_MAGIC) && + block->bb_magic != cpu_to_be32(XFS_BMAP_CRC_MAGIC)) || (be16_to_cpu(block->bb_level) != level)) return 0; @@ -338,6 +387,10 @@ int hasdir = 0; int isadir; + libxfs_readbuf_verify(bp, &xfs_inode_buf_ops); + if (bp->b_error) + return; + for (icnt = 0; icnt < (XFS_BUF_COUNT(bp) >> mp->m_sb.sb_inodelog); icnt++) { dino = xfs_make_iptr(mp, bp, icnt); @@ -374,7 +427,7 @@ continue; if ((dino->di_forkoff != 0) && - (dino->di_forkoff >= (XFS_LITINO(mp) >> 3))) + (dino->di_forkoff >= XFS_LITINO(mp, dino->di_version) >> 3)) continue; switch (dino->di_format) { @@ -393,7 +446,6 @@ /* * pf_batch_read must be called with the lock locked. */ - static void pf_batch_read( prefetch_args_t *args, @@ -422,9 +474,24 @@ max_fsbno = fsbno + pf_max_fsbs; } while (bplist[num] && num < MAX_BUFS && fsbno < max_fsbno) { + /* + * Discontiguous buffers need special handling, so stop + * gathering new buffers and process the list and this + * discontigous buffer immediately. This avoids the + * complexity of keeping a separate discontigous buffer + * list and seeking back over ranges we've already done + * optimised reads for. + */ + if ((bplist[num]->b_flags & LIBXFS_B_DISCONTIG)) { + num++; + break; + } + if (which != PF_META_ONLY || - !B_IS_INODE(XFS_BUF_PRIORITY(bplist[num]))) + !B_IS_INODE(XFS_BUF_PRIORITY(bplist[num]))) num++; + if (num == MAX_BUFS) + break; bplist[num] = btree_lookup_next(args->io_queue, &fsbno); } if (!num) @@ -438,7 +505,7 @@ first_off = LIBXFS_BBTOOFF64(XFS_BUF_ADDR(bplist[0])); last_off = LIBXFS_BBTOOFF64(XFS_BUF_ADDR(bplist[num-1])) + XFS_BUF_SIZE(bplist[num-1]); - while (last_off - first_off > pf_max_bytes) { + while (num > 1 && last_off - first_off > pf_max_bytes) { num--; last_off = LIBXFS_BBTOOFF64(XFS_BUF_ADDR(bplist[num-1])) + XFS_BUF_SIZE(bplist[num-1]); @@ -488,12 +555,25 @@ * now read the data and put into the xfs_but_t's */ len = pread64(mp_fd, buf, (int)(last_off - first_off), first_off); + + /* + * Check the last buffer on the list to see if we need to + * process a discontiguous buffer. The gather above loop + * guarantees that only the last buffer in the list will be a + * discontiguous buffer. + */ + if ((bplist[num - 1]->b_flags & LIBXFS_B_DISCONTIG)) { + libxfs_readbufr_map(mp->m_ddev_targp, bplist[num - 1], 0); + bplist[num - 1]->b_flags |= LIBXFS_B_UNCHECKED; + libxfs_putbuf(bplist[num - 1]); + num--; + } + if (len > 0) { /* * go through the xfs_buf_t list copying from the * read buffer into the xfs_buf_t's and release them. */ - last_off = first_off; for (i = 0; i < num; i++) { pbuf = ((char *)buf) + (LIBXFS_BBTOOFF64(XFS_BUF_ADDR(bplist[i])) - first_off); @@ -501,7 +581,8 @@ if (len < size) break; memcpy(XFS_BUF_PTR(bplist[i]), pbuf, size); - bplist[i]->b_flags |= LIBXFS_B_UPTODATE; + bplist[i]->b_flags |= (LIBXFS_B_UPTODATE | + LIBXFS_B_UNCHECKED); len -= size; if (B_IS_INODE(XFS_BUF_PRIORITY(bplist[i]))) pf_read_inode_dirs(args, bplist[i]); @@ -642,7 +723,7 @@ irec, args->agno, i); #endif err = sem_trywait(&args->ra_count); - if (err == EAGAIN) { + if (err < 0 && errno == EAGAIN) { /* * Kick the queue once we have reached the limit; * without this the threads processing the inodes @@ -658,10 +739,13 @@ bno = XFS_AGINO_TO_AGBNO(mp, cur_irec->ino_startnum); do { - pf_queue_io(args, XFS_AGB_TO_FSB(mp, args->agno, bno), - blks_per_cluster, - (cur_irec->ino_isa_dir != 0) ? - B_DIR_INODE : B_INODE); + struct xfs_buf_map map; + + map.bm_bn = XFS_AGB_TO_DADDR(mp, args->agno, bno); + map.bm_len = XFS_FSB_TO_BB(mp, blks_per_cluster); + pf_queue_io(args, &map, 1, + (cur_irec->ino_isa_dir != 0) ? B_DIR_INODE + : B_INODE); bno += blks_per_cluster; num_inos += inodes_per_cluster; } while (num_inos < XFS_IALLOC_INODES(mp)); @@ -721,7 +805,7 @@ xfs_mount_t *pmp) { mp = pmp; - mp_fd = libxfs_device_to_fd(mp->m_dev); + mp_fd = libxfs_device_to_fd(mp->m_ddev_targp->dev); pf_max_bytes = sysconf(_SC_PAGE_SIZE) << 7; pf_max_bbs = pf_max_bytes >> BBSHIFT; pf_max_fsbs = pf_max_bytes >> mp->m_sb.sb_blocklog; @@ -781,6 +865,142 @@ return args; } +/* + * prefetch_ag_range runs a prefetch-and-process loop across a range of AGs. It + * begins with @start+ag, and finishes with @end_ag - 1 (i.e. does not prefetch + * or process @end_ag). The function starts prefetch on the first AG, then loops + * starting prefetch on the next AG and then blocks processing the current AG as + * the prefetch queue brings inodes into the processing queue. + * + * There is only one prefetch taking place at a time, so the prefetch on the + * next AG only starts once the current AG has been completely prefetched. Hence + * the prefetch of the next AG will start some time before the processing of the + * current AG finishes, ensuring that when we iterate an start processing the + * next AG there is already a significant queue of inodes to process. + * + * Prefetch is done this way to prevent it from running too far ahead of the + * processing. Allowing it to do so can cause cache thrashing, where new + * prefetch causes previously prefetched buffers to be reclaimed before the + * processing thread uses them. This results in reading all the inodes and + * metadata twice per phase and it greatly slows down the processing. Hence we + * have to carefully control how far ahead we prefetch... + */ +static void +prefetch_ag_range( + struct work_queue *work, + xfs_agnumber_t start_ag, + xfs_agnumber_t end_ag, + bool dirs_only, + void (*func)(struct work_queue *, + xfs_agnumber_t, void *)) +{ + int i; + struct prefetch_args *pf_args[2]; + + pf_args[start_ag & 1] = start_inode_prefetch(start_ag, dirs_only, NULL); + for (i = start_ag; i < end_ag; i++) { + /* Don't prefetch end_ag */ + if (i + 1 < end_ag) + pf_args[(~i) & 1] = start_inode_prefetch(i + 1, + dirs_only, pf_args[i & 1]); + func(work, i, pf_args[i & 1]); + } +} + +struct pf_work_args { + xfs_agnumber_t start_ag; + xfs_agnumber_t end_ag; + bool dirs_only; + void (*func)(struct work_queue *, xfs_agnumber_t, void *); +}; + +static void +prefetch_ag_range_work( + struct work_queue *work, + xfs_agnumber_t unused, + void *args) +{ + struct pf_work_args *wargs = args; + + prefetch_ag_range(work, wargs->start_ag, wargs->end_ag, + wargs->dirs_only, wargs->func); + free(args); +} + +/* + * Do inode prefetch in the most optimal way for the context under which repair + * has been run. + */ +void +do_inode_prefetch( + struct xfs_mount *mp, + int stride, + void (*func)(struct work_queue *, + xfs_agnumber_t, void *), + bool check_cache, + bool dirs_only) +{ + int i; + struct work_queue queue; + struct work_queue *queues; + int queues_started = 0; + + /* + * If the previous phases of repair have not overflowed the buffer + * cache, then we don't need to re-read any of the metadata in the + * filesystem - it's all in the cache. In that case, run a thread per + * CPU to maximise parallelism of the queue to be processed. + */ + if (check_cache && !libxfs_bcache_overflowed()) { + queue.mp = mp; + create_work_queue(&queue, mp, libxfs_nproc()); + for (i = 0; i < mp->m_sb.sb_agcount; i++) + queue_work(&queue, func, i, NULL); + destroy_work_queue(&queue); + return; + } + + /* + * single threaded behaviour - single prefetch thread, processed + * directly after each AG is queued. + */ + if (!stride) { + queue.mp = mp; + prefetch_ag_range(&queue, 0, mp->m_sb.sb_agcount, + dirs_only, func); + return; + } + + /* + * create one worker thread for each segment of the volume + */ + queues = malloc(thread_count * sizeof(work_queue_t)); + for (i = 0; i < thread_count; i++) { + struct pf_work_args *wargs; + + wargs = malloc(sizeof(struct pf_work_args)); + wargs->start_ag = i * stride; + wargs->end_ag = min((i + 1) * stride, + mp->m_sb.sb_agcount); + wargs->dirs_only = dirs_only; + wargs->func = func; + + create_work_queue(&queues[i], mp, 1); + queue_work(&queues[i], prefetch_ag_range_work, 0, wargs); + queues_started++; + + if (wargs->end_ag >= mp->m_sb.sb_agcount) + break; + } + + /* + * wait for workers to complete + */ + for (i = 0; i < queues_started; i++) + destroy_work_queue(&queues[i]); + free(queues); +} + void wait_for_inode_prefetch( prefetch_args_t *args) diff -Nru xfsprogs-3.1.9ubuntu2/repair/prefetch.h xfsprogs-3.2.1ubuntu1/repair/prefetch.h --- xfsprogs-3.1.9ubuntu2/repair/prefetch.h 2009-12-06 20:58:01.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/prefetch.h 2014-05-02 00:09:16.000000000 +0000 @@ -4,6 +4,7 @@ #include #include "incore.h" +struct work_queue; extern int do_prefetch; @@ -41,6 +42,15 @@ prefetch_args_t *prev_args); void +do_inode_prefetch( + struct xfs_mount *mp, + int stride, + void (*func)(struct work_queue *, + xfs_agnumber_t, void *), + bool check_cache, + bool dirs_only); + +void wait_for_inode_prefetch( prefetch_args_t *args); diff -Nru xfsprogs-3.1.9ubuntu2/repair/progress.c xfsprogs-3.2.1ubuntu1/repair/progress.c --- xfsprogs-3.1.9ubuntu2/repair/progress.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/progress.c 2014-05-02 00:09:16.000000000 +0000 @@ -124,6 +124,7 @@ */ pthread_mutex_init(&global_msgs.mutex, NULL); + global_msgs.format = NULL; global_msgs.count = glob_agcount; global_msgs.interval = report_interval; global_msgs.done = prog_rpt_done; @@ -169,6 +170,10 @@ msg_block_t *msgp = (msg_block_t *)p; __uint64_t percent; + /* It's possible to get here very early w/ no progress msg set */ + if (!msgp->format) + return NULL; + if ((msgbuf = (char *)malloc(DURATION_BUF_SIZE)) == NULL) do_error (_("progress_rpt: cannot malloc progress msg buffer\n")); diff -Nru xfsprogs-3.1.9ubuntu2/repair/protos.h xfsprogs-3.2.1ubuntu1/repair/protos.h --- xfsprogs-3.1.9ubuntu2/repair/protos.h 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/protos.h 2014-05-02 00:09:16.000000000 +0000 @@ -18,7 +18,8 @@ void xfs_init(libxfs_init_t *args); -int verify_sb(xfs_sb_t *sb, +int verify_sb(char *sb_buf, + xfs_sb_t *sb, int is_primary_sb); int verify_set_primary_sb(xfs_sb_t *root_sb, int sb_index, diff -Nru xfsprogs-3.1.9ubuntu2/repair/rt.c xfsprogs-3.2.1ubuntu1/repair/rt.c --- xfsprogs-3.1.9ubuntu2/repair/rt.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/rt.c 2013-10-10 21:07:17.000000000 +0000 @@ -206,7 +206,7 @@ continue; } bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno), - XFS_FSB_TO_BB(mp, 1)); + XFS_FSB_TO_BB(mp, 1), NULL); if (!bp) { do_warn(_("can't read block %d for rtbitmap inode\n"), bmbno); @@ -268,7 +268,7 @@ continue; } bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno), - XFS_FSB_TO_BB(mp, 1)); + XFS_FSB_TO_BB(mp, 1), NULL); if (!bp) { do_warn(_("can't read block %d for rtsummary inode\n"), sumbno); diff -Nru xfsprogs-3.1.9ubuntu2/repair/sb.c xfsprogs-3.2.1ubuntu1/repair/sb.c --- xfsprogs-3.1.9ubuntu2/repair/sb.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/sb.c 2014-07-21 09:15:17.000000000 +0000 @@ -40,6 +40,7 @@ xfs_ino_t rsumino; xfs_ino_t uquotino; xfs_ino_t gquotino; + xfs_ino_t pquotino; __uint16_t versionnum; rootino = dest->sb_rootino; @@ -47,6 +48,7 @@ rsumino = dest->sb_rsumino; uquotino = dest->sb_uquotino; gquotino = dest->sb_gquotino; + pquotino = dest->sb_pquotino; versionnum = dest->sb_versionnum; @@ -57,6 +59,7 @@ dest->sb_rsumino = rsumino; dest->sb_uquotino = uquotino; dest->sb_gquotino = gquotino; + dest->sb_pquotino = pquotino; dest->sb_versionnum = versionnum; @@ -135,8 +138,9 @@ for (i = 0; !done && i < bsize; i += BBSIZE) { c_bufsb = (char *)sb + i; libxfs_sb_from_disk(&bufsb, (xfs_dsb_t *)c_bufsb); + libxfs_sb_quota_from_disk(&bufsb); - if (verify_sb(&bufsb, 0) != XR_OK) + if (verify_sb(c_bufsb, &bufsb, 0) != XR_OK) continue; do_warn(_("found candidate secondary superblock...\n")); @@ -166,17 +170,37 @@ } /* - * calculate what inode alignment field ought to be - * based on internal superblock info + * Calculate what inode alignment field ought to be + * based on internal superblock info and determine if it is valid. + * + * For v5 superblocks, the inode alignment will either match that of the + * standard XFS_INODE_BIG_CLUSTER_SIZE, or it will be scaled based on the inode + * size. Either value is valid in this case. + * + * Return true if the alignment is valid, false otherwise. */ -static int -calc_ino_align(xfs_sb_t *sb) +static bool +sb_validate_ino_align(struct xfs_sb *sb) { - xfs_extlen_t align; + xfs_extlen_t align; + + if (!xfs_sb_version_hasalign(sb)) + return true; + /* standard cluster size alignment is always valid */ align = XFS_INODE_BIG_CLUSTER_SIZE >> sb->sb_blocklog; + if (align == sb->sb_inoalignmt) + return true; - return(align); + /* alignment scaled by inode size is v5 only for now */ + if (!xfs_sb_version_hascrc(sb)) + return false; + + align *= sb->sb_inodesize / XFS_DINODE_MIN_SIZE; + if (align == sb->sb_inoalignmt) + return true; + + return false; } /* @@ -222,10 +246,9 @@ */ int -verify_sb(xfs_sb_t *sb, int is_primary_sb) +verify_sb(char *sb_buf, xfs_sb_t *sb, int is_primary_sb) { __uint32_t bsize; - xfs_extlen_t align; int i; /* check magic number and version number */ @@ -241,8 +264,34 @@ if (is_primary_sb && sb->sb_inprogress == 1) return(XR_BAD_INPROGRESS); - /* check to make sure blocksize is legal 2^N, 9 <= N <= 16 */ + /* + * before going *any further*, validate the sector size and if the + * version says we should have CRCs enabled, validate that. + */ + + /* check to make sure sectorsize is legal 2^N, 9 <= N <= 15 */ + if (sb->sb_sectsize == 0) + return(XR_BAD_SECT_SIZE_DATA); + bsize = 1; + for (i = 0; bsize < sb->sb_sectsize && + i < sizeof(sb->sb_sectsize) * NBBY; i++) { + bsize <<= 1; + } + + if (i < XFS_MIN_SECTORSIZE_LOG || i > XFS_MAX_SECTORSIZE_LOG) + return(XR_BAD_SECT_SIZE_DATA); + + /* check sb sectorsize field against sb sectlog field */ + if (i != sb->sb_sectlog) + return(XR_BAD_SECT_SIZE_DATA); + + /* sector size in range - CRC check time */ + if (xfs_sb_version_hascrc(sb) && + !xfs_verify_cksum(sb_buf, sb->sb_sectsize, XFS_SB_CRC_OFF)) + return XR_BAD_CRC; + + /* check to make sure blocksize is legal 2^N, 9 <= N <= 16 */ if (sb->sb_blocksize == 0) return(XR_BAD_BLOCKSIZE); @@ -278,26 +327,6 @@ sb->sb_inopblock != howmany(sb->sb_blocksize,sb->sb_inodesize)) return(XR_BAD_INO_SIZE_DATA); - /* check to make sure sectorsize is legal 2^N, 9 <= N <= 15 */ - - if (sb->sb_sectsize == 0) - return(XR_BAD_SECT_SIZE_DATA); - - bsize = 1; - - for (i = 0; bsize < sb->sb_sectsize && - i < sizeof(sb->sb_sectsize) * NBBY; i++) { - bsize <<= 1; - } - - if (i < XFS_MIN_SECTORSIZE_LOG || i > XFS_MAX_SECTORSIZE_LOG) - return(XR_BAD_SECT_SIZE_DATA); - - /* check sb sectorsize field against sb sectlog field */ - - if (i != sb->sb_sectlog) - return(XR_BAD_SECT_SIZE_DATA); - if (xfs_sb_version_hassector(sb)) { /* check to make sure log sector is legal 2^N, 9 <= N <= 15 */ @@ -361,12 +390,8 @@ /* * verify correctness of inode alignment if it's there */ - if (xfs_sb_version_hasalign(sb)) { - align = calc_ino_align(sb); - - if (align != sb->sb_inoalignmt) - return(XR_BAD_INO_ALIGN); - } + if (!sb_validate_ino_align(sb)) + return(XR_BAD_INO_ALIGN); /* * verify max. % of inodes (sb_imax_pct) @@ -464,9 +489,11 @@ do_error(_("couldn't seek to offset 0 in filesystem\n")); } - libxfs_sb_to_disk(buf, sbp, XFS_SB_ALL_BITS); + if (xfs_sb_version_hascrc(sbp)) + xfs_update_cksum((char *)buf, size, XFS_SB_CRC_OFF); + if (write(x.dfd, buf, size) != size) { free(buf); do_error(_("primary superblock write failed!\n")); @@ -476,7 +503,7 @@ } /* - * get a possible superblock -- don't check for internal consistency + * get a possible superblock -- checks for internal consistency */ int get_sb(xfs_sb_t *sbp, xfs_off_t off, int size, xfs_agnumber_t agno) @@ -492,6 +519,7 @@ exit(1); } memset(buf, 0, size); + memset(sbp, 0, sizeof(*sbp)); /* try and read it first */ @@ -499,6 +527,7 @@ do_warn( _("error reading superblock %u -- seek to offset %" PRId64 " failed\n"), agno, off); + free(buf); return(XR_EOF); } @@ -510,9 +539,11 @@ do_error("%s\n", strerror(error)); } libxfs_sb_from_disk(sbp, buf); - free(buf); + libxfs_sb_quota_from_disk(sbp); - return (verify_sb(sbp, 0)); + rval = verify_sb((char *)buf, sbp, agno == 0); + free(buf); + return rval; } /* returns element on list with highest reference count */ @@ -569,8 +600,6 @@ fs_geo_list_t *next; fs_geo_list_t *current; - current = list; - for (current = list; current != NULL; current = next) { next = current->next; free(current); @@ -661,7 +690,7 @@ * primary and compare the geometries in the secondaries against * the geometry indicated by the primary. * - * returns 1 if bad, 0 if ok + * returns 0 if ok, else error code (XR_EOF, XR_INSUFF_SEC_SB, etc). */ int verify_set_primary_sb(xfs_sb_t *rsb, @@ -726,13 +755,11 @@ off = (xfs_off_t)agno * rsb->sb_agblocks << rsb->sb_blocklog; checked[agno] = 1; + retval = get_sb(sb, off, size, agno); + if (retval == XR_EOF) + goto out_free_list; - if (get_sb(sb, off, size, agno) == XR_EOF) { - retval = 1; - goto out; - } - - if (verify_sb(sb, 0) == XR_OK) { + if (retval == XR_OK) { /* * save away geometry info. * don't bother checking the sb @@ -752,8 +779,10 @@ /* * see if we have enough superblocks to bother with */ - if (num_ok < num_sbs / 2) - return(XR_INSUFF_SEC_SB); + if (num_ok < num_sbs / 2) { + retval = XR_INSUFF_SEC_SB; + goto out_free_list; + } current = get_best_geo(list); @@ -837,7 +866,6 @@ out_free_list: free_geo(list); -out: free(sb); free(checked); return(retval); diff -Nru xfsprogs-3.1.9ubuntu2/repair/scan.c xfsprogs-3.2.1ubuntu1/repair/scan.c --- xfsprogs-3.1.9ubuntu2/repair/scan.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/scan.c 2014-07-21 09:13:53.000000000 +0000 @@ -46,19 +46,9 @@ __uint64_t fdblocks; __uint64_t icount; __uint64_t ifreecount; + __uint32_t fibtfreecount; }; -static void -scanfunc_allocbt( - struct xfs_btree_block *block, - int level, - xfs_agblock_t bno, - xfs_agnumber_t agno, - int suspect, - int isroot, - __uint32_t magic, - struct aghdr_cnts *agcnts); - void set_mp(xfs_mount_t *mpp) { @@ -78,20 +68,29 @@ xfs_agnumber_t agno, int suspect, int isroot, + __uint32_t magic, void *priv), int isroot, - void *priv) + __uint32_t magic, + void *priv, + const struct xfs_buf_ops *ops) { xfs_buf_t *bp; bp = libxfs_readbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, root), - XFS_FSB_TO_BB(mp, 1), 0); + XFS_FSB_TO_BB(mp, 1), 0, ops); if (!bp) { do_error(_("can't read btree block %d/%d\n"), agno, root); return; } + if (bp->b_error == EFSBADCRC || bp->b_error == EFSCORRUPTED) { + do_warn(_("btree block %d/%d is suspect, error %d\n"), + agno, root, bp->b_error); + suspect = 1; + } + (*func)(XFS_BUF_TO_BLOCK(bp), nlevels - 1, root, agno, suspect, - isroot, priv); + isroot, magic, priv); libxfs_putbuf(bp); } @@ -114,7 +113,8 @@ bmap_cursor_t *bm_cursor, int isroot, int check_dups, - int *dirty), + int *dirty, + __uint64_t magic), int type, int whichfork, xfs_ino_t ino, @@ -123,27 +123,44 @@ blkmap_t **blkmapp, bmap_cursor_t *bm_cursor, int isroot, - int check_dups) + int check_dups, + __uint64_t magic, + const struct xfs_buf_ops *ops) { xfs_buf_t *bp; int err; int dirty = 0; + bool badcrc = false; bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, root), - XFS_FSB_TO_BB(mp, 1), 0); + XFS_FSB_TO_BB(mp, 1), 0, ops); if (!bp) { do_error(_("can't read btree block %d/%d\n"), XFS_FSB_TO_AGNO(mp, root), XFS_FSB_TO_AGBNO(mp, root)); return(1); } + + /* + * only check for bad CRC here - caller will determine if there + * is a corruption or not and whether it got corrected and so needs + * writing back. CRC errors always imply we need to write the block. + */ + if (bp->b_error == EFSBADCRC) { + do_warn(_("btree block %d/%d is suspect, error %d\n"), + XFS_FSB_TO_AGNO(mp, root), + XFS_FSB_TO_AGBNO(mp, root), bp->b_error); + badcrc = true; + } + err = (*func)(XFS_BUF_TO_BLOCK(bp), nlevels - 1, type, whichfork, root, ino, tot, nex, blkmapp, - bm_cursor, isroot, check_dups, &dirty); + bm_cursor, isroot, check_dups, &dirty, + magic); ASSERT(dirty == 0 || (dirty && !no_modify)); - if (dirty && !no_modify) + if ((dirty || badcrc) && !no_modify) libxfs_writebuf(bp, 0); else libxfs_putbuf(bp); @@ -152,7 +169,7 @@ } int -scanfunc_bmap( +scan_bmapbt( struct xfs_btree_block *block, int level, int type, @@ -165,7 +182,8 @@ bmap_cursor_t *bm_cursor, int isroot, int check_dups, - int *dirty) + int *dirty, + __uint64_t magic) { int i; int err; @@ -174,17 +192,12 @@ xfs_bmbt_rec_t *rp; xfs_dfiloff_t first_key; xfs_dfiloff_t last_key; - char *forkname; + char *forkname = get_forkname(whichfork); int numrecs; xfs_agnumber_t agno; xfs_agblock_t agbno; int state; - if (whichfork == XFS_DATA_FORK) - forkname = _("data"); - else - forkname = _("attr"); - /* * unlike the ag freeblock btrees, if anything looks wrong * in an inode bmap tree, just bail. it's possible that @@ -192,7 +205,7 @@ * another inode are claiming the same block but that's * highly unlikely. */ - if (be32_to_cpu(block->bb_magic) != XFS_BMAP_MAGIC) { + if (be32_to_cpu(block->bb_magic) != magic) { do_warn( _("bad magic # %#x in inode %" PRIu64 " (%s fork) bmbt block %" PRIu64 "\n"), be32_to_cpu(block->bb_magic), ino, forkname, bno); @@ -206,6 +219,16 @@ return(1); } + if (magic == XFS_BMAP_CRC_MAGIC) { + /* verify owner */ + if (be64_to_cpu(block->bb_u.l.bb_owner) != ino) { + do_warn( +_("expected owner inode %" PRIu64 ", got %llu, bmbt block %" PRIu64 "\n"), + ino, be64_to_cpu(block->bb_u.l.bb_owner), bno); + return(1); + } + } + if (check_dups == 0) { /* * check sibling pointers. if bad we have a conflict @@ -266,7 +289,7 @@ agno = XFS_FSB_TO_AGNO(mp, bno); agbno = XFS_FSB_TO_AGBNO(mp, bno); - pthread_mutex_lock(&ag_locks[agno]); + pthread_mutex_lock(&ag_locks[agno].lock); state = get_bmap(agno, agbno); switch (state) { case XR_E_UNKNOWN: @@ -312,7 +335,7 @@ state, ino, bno); break; } - pthread_mutex_unlock(&ag_locks[agno]); + pthread_mutex_unlock(&ag_locks[agno].lock); } else { /* * attribute fork for realtime files is in the regular @@ -408,9 +431,10 @@ return(1); } - err = scan_lbtree(be64_to_cpu(pp[i]), level, scanfunc_bmap, + err = scan_lbtree(be64_to_cpu(pp[i]), level, scan_bmapbt, type, whichfork, ino, tot, nex, blkmapp, - bm_cursor, 0, check_dups); + bm_cursor, 0, check_dups, magic, + &xfs_bmbt_buf_ops); if (err) return(1); @@ -481,35 +505,7 @@ } static void -scanfunc_bno( - struct xfs_btree_block *block, - int level, - xfs_agblock_t bno, - xfs_agnumber_t agno, - int suspect, - int isroot, - void *agcnts) -{ - return scanfunc_allocbt(block, level, bno, agno, - suspect, isroot, XFS_ABTB_MAGIC, agcnts); -} - -static void -scanfunc_cnt( - struct xfs_btree_block *block, - int level, - xfs_agblock_t bno, - xfs_agnumber_t agno, - int suspect, - int isroot, - void *agcnts) -{ - return scanfunc_allocbt(block, level, bno, agno, - suspect, isroot, XFS_ABTC_MAGIC, agcnts); -} - -static void -scanfunc_allocbt( +scan_allocbt( struct xfs_btree_block *block, int level, xfs_agblock_t bno, @@ -517,8 +513,9 @@ int suspect, int isroot, __uint32_t magic, - struct aghdr_cnts *agcnts) + void *priv) { + struct aghdr_cnts *agcnts = priv; const char *name; int i; xfs_alloc_ptr_t *pp; @@ -529,9 +526,20 @@ xfs_extlen_t lastcount = 0; xfs_agblock_t lastblock = 0; - assert(magic == XFS_ABTB_MAGIC || magic == XFS_ABTC_MAGIC); - - name = (magic == XFS_ABTB_MAGIC) ? "bno" : "cnt"; + switch (magic) { + case XFS_ABTB_CRC_MAGIC: + case XFS_ABTB_MAGIC: + name = "bno"; + break; + case XFS_ABTC_CRC_MAGIC: + case XFS_ABTC_MAGIC: + name = "cnt"; + break; + default: + name = "(unknown)"; + assert(0); + break; + } if (be32_to_cpu(block->bb_magic) != magic) { do_warn(_("bad magic # %#x in bt%s block %d/%d\n"), @@ -615,7 +623,8 @@ continue; } - if (magic == XFS_ABTB_MAGIC) { + if (magic == XFS_ABTB_MAGIC || + magic == XFS_ABTB_CRC_MAGIC) { if (b <= lastblock) { do_warn(_( "out-of-order bno btree record %d (%u %u) block %u/%u\n"), @@ -648,7 +657,8 @@ * no warning messages -- we'll catch * FREE1 blocks later */ - if (magic == XFS_ABTC_MAGIC) { + if (magic == XFS_ABTC_MAGIC || + magic == XFS_ABTC_CRC_MAGIC) { set_bmap_ext(agno, b, blen, XR_E_FREE); break; @@ -709,10 +719,20 @@ * as possible. */ if (bno != 0 && verify_agbno(mp, agno, bno)) { - scan_sbtree(bno, level, agno, suspect, - (magic == XFS_ABTB_MAGIC) ? - scanfunc_bno : scanfunc_cnt, 0, - (void *)agcnts); + switch (magic) { + case XFS_ABTB_CRC_MAGIC: + case XFS_ABTB_MAGIC: + scan_sbtree(bno, level, agno, suspect, + scan_allocbt, 0, magic, priv, + &xfs_allocbt_buf_ops); + break; + case XFS_ABTC_CRC_MAGIC: + case XFS_ABTC_MAGIC: + scan_sbtree(bno, level, agno, suspect, + scan_allocbt, 0, magic, priv, + &xfs_allocbt_buf_ops); + break; + } } } } @@ -862,9 +882,9 @@ for (j = 0; j < XFS_INODES_PER_CHUNK; j++) { if (XFS_INOBT_IS_FREE_DISK(rp, j)) { nfree++; - add_aginode_uncertain(agno, ino + j, 1); + add_aginode_uncertain(mp, agno, ino + j, 1); } else { - add_aginode_uncertain(agno, ino + j, 0); + add_aginode_uncertain(mp, agno, ino + j, 0); } } } @@ -878,6 +898,208 @@ return suspect; } +static int +scan_single_finobt_chunk( + xfs_agnumber_t agno, + xfs_inobt_rec_t *rp, + int suspect) +{ + xfs_ino_t lino; + xfs_agino_t ino; + xfs_agblock_t agbno; + int j; + int nfree; + int off; + int state; + ino_tree_node_t *first_rec, *last_rec, *ino_rec; + + ino = be32_to_cpu(rp->ir_startino); + off = XFS_AGINO_TO_OFFSET(mp, ino); + agbno = XFS_AGINO_TO_AGBNO(mp, ino); + lino = XFS_AGINO_TO_INO(mp, agno, ino); + + /* + * on multi-block block chunks, all chunks start at the beginning of the + * block. with multi-chunk blocks, all chunks must start on 64-inode + * boundaries since each block can hold N complete chunks. if fs has + * aligned inodes, all chunks must start at a fs_ino_alignment*N'th + * agbno. skip recs with badly aligned starting inodes. + */ + if (ino == 0 || + (inodes_per_block <= XFS_INODES_PER_CHUNK && off != 0) || + (inodes_per_block > XFS_INODES_PER_CHUNK && + off % XFS_INODES_PER_CHUNK != 0) || + (fs_aligned_inodes && agbno % fs_ino_alignment != 0)) { + do_warn( + _("badly aligned finobt inode rec (starting inode = %" PRIu64 ")\n"), + lino); + suspect++; + } + + /* + * verify numeric validity of inode chunk first before inserting into a + * tree. don't have to worry about the overflow case because the + * starting ino number of a chunk can only get within 255 inodes of max + * (NULLAGINO). if it gets closer, the agino number will be illegal as + * the agbno will be too large. + */ + if (verify_aginum(mp, agno, ino)) { + do_warn( +_("bad starting inode # (%" PRIu64 " (0x%x 0x%x)) in finobt rec, skipping rec\n"), + lino, agno, ino); + return ++suspect; + } + + if (verify_aginum(mp, agno, + ino + XFS_INODES_PER_CHUNK - 1)) { + do_warn( +_("bad ending inode # (%" PRIu64 " (0x%x 0x%zx)) in finobt rec, skipping rec\n"), + lino + XFS_INODES_PER_CHUNK - 1, + agno, + ino + XFS_INODES_PER_CHUNK - 1); + return ++suspect; + } + + /* + * cross check state of each block containing inodes referenced by the + * finobt against what we have already scanned from the alloc inobt. + */ + if (off == 0 && !suspect) { + for (j = 0; + j < XFS_INODES_PER_CHUNK; + j += mp->m_sb.sb_inopblock) { + agbno = XFS_AGINO_TO_AGBNO(mp, ino + j); + + state = get_bmap(agno, agbno); + if (state == XR_E_INO) { + continue; + } else if ((state == XR_E_UNKNOWN) || + (state == XR_E_INUSE_FS && agno == 0 && + ino + j >= first_prealloc_ino && + ino + j < last_prealloc_ino)) { + do_warn( +_("inode chunk claims untracked block, finobt block - agno %d, bno %d, inopb %d\n"), + agno, agbno, mp->m_sb.sb_inopblock); + + set_bmap(agno, agbno, XR_E_INO); + suspect++; + } else { + do_warn( +_("inode chunk claims used block, finobt block - agno %d, bno %d, inopb %d\n"), + agno, agbno, mp->m_sb.sb_inopblock); + return ++suspect; + } + } + } + + /* + * ensure we have an incore entry for each chunk + */ + find_inode_rec_range(mp, agno, ino, ino + XFS_INODES_PER_CHUNK, + &first_rec, &last_rec); + + if (first_rec) { + if (suspect) + return suspect; + + /* + * verify consistency between finobt record and incore state + */ + if (first_rec->ino_startnum != ino) { + do_warn( +_("finobt rec for ino %" PRIu64 " (%d/%u) does not match existing rec (%d/%d)\n"), + lino, agno, ino, agno, first_rec->ino_startnum); + return ++suspect; + } + + nfree = 0; + for (j = 0; j < XFS_INODES_PER_CHUNK; j++) { + int isfree = XFS_INOBT_IS_FREE_DISK(rp, j); + + if (isfree) + nfree++; + + /* + * inode allocation state should be consistent between + * the inobt and finobt + */ + if (!suspect && + isfree != is_inode_free(first_rec, j)) + suspect++; + } + + goto check_freecount; + } + + /* + * the finobt contains a record that the previous alloc inobt scan never + * found. insert the inodes into the appropriate tree. + */ + do_warn(_("undiscovered finobt record, ino %" PRIu64 " (%d/%u)\n"), + lino, agno, ino); + + if (!suspect) { + /* + * inodes previously inserted into the uncertain tree should be + * superceded by these when the uncertain tree is processed + */ + nfree = 0; + if (XFS_INOBT_IS_FREE_DISK(rp, 0)) { + nfree++; + ino_rec = set_inode_free_alloc(mp, agno, ino); + } else { + ino_rec = set_inode_used_alloc(mp, agno, ino); + } + for (j = 1; j < XFS_INODES_PER_CHUNK; j++) { + if (XFS_INOBT_IS_FREE_DISK(rp, j)) { + nfree++; + set_inode_free(ino_rec, j); + } else { + set_inode_used(ino_rec, j); + } + } + } else { + /* + * this should handle the case where the inobt scan may have + * already added uncertain inodes + */ + nfree = 0; + for (j = 0; j < XFS_INODES_PER_CHUNK; j++) { + if (XFS_INOBT_IS_FREE_DISK(rp, j)) { + add_aginode_uncertain(mp, agno, ino + j, 1); + nfree++; + } else { + add_aginode_uncertain(mp, agno, ino + j, 0); + } + } + } + +check_freecount: + + /* + * Verify that the record freecount matches the actual number of free + * inodes counted in the record. Don't increment 'suspect' here, since + * we have already verified the allocation state of the individual + * inodes against the in-core state. This will have already incremented + * 'suspect' if something is wrong. If suspect hasn't been set at this + * point, these warnings mean that we have a simple freecount + * inconsistency or a stray finobt record (as opposed to a broader tree + * corruption). Issue a warning and continue the scan. The final btree + * reconstruction will correct this naturally. + */ + if (nfree != be32_to_cpu(rp->ir_freecount)) { + do_warn( +_("finobt ir_freecount/free mismatch, inode chunk %d/%u, freecount %d nfree %d\n"), + agno, ino, be32_to_cpu(rp->ir_freecount), nfree); + } + + if (!nfree) { + do_warn( +_("finobt record with no free inodes, inode chunk %d/%u\n"), agno, ino); + } + + return suspect; +} /* * this one walks the inode btrees sucking the info there into @@ -896,13 +1118,14 @@ * that we aren't sure about go into the uncertain list. */ static void -scanfunc_ino( +scan_inobt( struct xfs_btree_block *block, int level, xfs_agblock_t bno, xfs_agnumber_t agno, int suspect, int isroot, + __uint32_t magic, void *priv) { struct aghdr_cnts *agcnts = priv; @@ -915,7 +1138,7 @@ hdr_errors = 0; - if (be32_to_cpu(block->bb_magic) != XFS_IBT_MAGIC) { + if (be32_to_cpu(block->bb_magic) != magic) { do_warn(_("bad magic # %#x in inobt block %d/%d\n"), be32_to_cpu(block->bb_magic), agno, bno); hdr_errors++; @@ -985,12 +1208,29 @@ * the block. skip processing of bogus records. */ for (i = 0; i < numrecs; i++) { - agcnts->agicount += XFS_INODES_PER_CHUNK; - agcnts->icount += XFS_INODES_PER_CHUNK; - agcnts->agifreecount += be32_to_cpu(rp[i].ir_freecount); - agcnts->ifreecount += be32_to_cpu(rp[i].ir_freecount); + if (magic == XFS_IBT_MAGIC || + magic == XFS_IBT_CRC_MAGIC) { + agcnts->agicount += XFS_INODES_PER_CHUNK; + agcnts->icount += XFS_INODES_PER_CHUNK; + agcnts->agifreecount += + be32_to_cpu(rp[i].ir_freecount); + agcnts->ifreecount += + be32_to_cpu(rp[i].ir_freecount); - suspect = scan_single_ino_chunk(agno, &rp[i], suspect); + suspect = scan_single_ino_chunk(agno, &rp[i], + suspect); + } else { + /* + * the finobt tracks records with free inodes, + * so only the free inode count is expected to be + * consistent with the agi + */ + agcnts->fibtfreecount += + be32_to_cpu(rp[i].ir_freecount); + + suspect = scan_single_finobt_chunk(agno, &rp[i], + suspect); + } } if (suspect) @@ -1032,7 +1272,8 @@ if (be32_to_cpu(pp[i]) != 0 && verify_agbno(mp, agno, be32_to_cpu(pp[i]))) scan_sbtree(be32_to_cpu(pp[i]), level, agno, - suspect, scanfunc_ino, 0, priv); + suspect, scan_inobt, 0, magic, priv, + &xfs_inobt_buf_ops); } } @@ -1041,12 +1282,12 @@ xfs_agf_t *agf, struct aghdr_cnts *agcnts) { - xfs_agfl_t *agfl; xfs_buf_t *agflbuf; xfs_agnumber_t agno; xfs_agblock_t bno; int count; int i; + __be32 *freelist; agno = be32_to_cpu(agf->agf_seqno); @@ -1060,16 +1301,30 @@ agflbuf = libxfs_readbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), - XFS_FSS_TO_BB(mp, 1), 0); + XFS_FSS_TO_BB(mp, 1), 0, &xfs_agfl_buf_ops); if (!agflbuf) { do_abort(_("can't read agfl block for ag %d\n"), agno); return; } - agfl = XFS_BUF_TO_AGFL(agflbuf); + if (agflbuf->b_error == EFSBADCRC) + do_warn(_("agfl has bad CRC for ag %d\n"), agno); + + freelist = XFS_BUF_TO_AGFL_BNO(mp, agflbuf); i = be32_to_cpu(agf->agf_flfirst); + + if (no_modify) { + /* agf values not fixed in verify_set_agf, so recheck */ + if (be32_to_cpu(agf->agf_flfirst) >= XFS_AGFL_SIZE(mp) || + be32_to_cpu(agf->agf_fllast) >= XFS_AGFL_SIZE(mp)) { + do_warn(_("agf %d freelist blocks bad, skipping " + "freelist scan\n"), i); + return; + } + } + count = 0; for (;;) { - bno = be32_to_cpu(agfl->agfl_bno[i]); + bno = be32_to_cpu(freelist[i]); if (verify_agbno(mp, agno, bno)) set_bmap(agno, bno, XR_E_FREE); else @@ -1098,11 +1353,15 @@ struct aghdr_cnts *agcnts) { xfs_agblock_t bno; + __uint32_t magic; bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]); if (bno != 0 && verify_agbno(mp, agno, bno)) { + magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_ABTB_CRC_MAGIC + : XFS_ABTB_MAGIC; scan_sbtree(bno, be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]), - agno, 0, scanfunc_bno, 1, agcnts); + agno, 0, scan_allocbt, 1, magic, agcnts, + &xfs_allocbt_buf_ops); } else { do_warn(_("bad agbno %u for btbno root, agno %d\n"), bno, agno); @@ -1110,8 +1369,11 @@ bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]); if (bno != 0 && verify_agbno(mp, agno, bno)) { + magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_ABTC_CRC_MAGIC + : XFS_ABTC_MAGIC; scan_sbtree(bno, be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]), - agno, 0, scanfunc_cnt, 1, agcnts); + agno, 0, scan_allocbt, 1, magic, agcnts, + &xfs_allocbt_buf_ops); } else { do_warn(_("bad agbno %u for btbcnt root, agno %d\n"), bno, agno); @@ -1142,16 +1404,34 @@ { xfs_agblock_t bno; int i; + __uint32_t magic; bno = be32_to_cpu(agi->agi_root); if (bno != 0 && verify_agbno(mp, agno, bno)) { + magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_IBT_CRC_MAGIC + : XFS_IBT_MAGIC; scan_sbtree(bno, be32_to_cpu(agi->agi_level), - agno, 0, scanfunc_ino, 1, agcnts); + agno, 0, scan_inobt, 1, magic, agcnts, + &xfs_inobt_buf_ops); } else { do_warn(_("bad agbno %u for inobt root, agno %d\n"), be32_to_cpu(agi->agi_root), agno); } + if (xfs_sb_version_hasfinobt(&mp->m_sb)) { + bno = be32_to_cpu(agi->agi_free_root); + if (bno != 0 && verify_agbno(mp, agno, bno)) { + magic = xfs_sb_version_hascrc(&mp->m_sb) ? + XFS_FIBT_CRC_MAGIC : XFS_FIBT_MAGIC; + scan_sbtree(bno, be32_to_cpu(agi->agi_free_level), + agno, 0, scan_inobt, 1, magic, agcnts, + &xfs_inobt_buf_ops); + } else { + do_warn(_("bad agbno %u for finobt root, agno %d\n"), + be32_to_cpu(agi->agi_free_root), agno); + } + } + if (be32_to_cpu(agi->agi_count) != agcnts->agicount) { do_warn(_("agi_count %u, counted %u in ag %u\n"), be32_to_cpu(agi->agi_count), agcnts->agicount, agno); @@ -1162,6 +1442,13 @@ be32_to_cpu(agi->agi_freecount), agcnts->agifreecount, agno); } + if (xfs_sb_version_hasfinobt(&mp->m_sb) && + be32_to_cpu(agi->agi_freecount) != agcnts->fibtfreecount) { + do_warn(_("agi_freecount %u, counted %u in ag %u finobt\n"), + be32_to_cpu(agi->agi_freecount), agcnts->fibtfreecount, + agno); + } + for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) { xfs_agino_t agino = be32_to_cpu(agi->agi_unlinked[i]); @@ -1184,52 +1471,48 @@ void *arg) { struct aghdr_cnts *agcnts = arg; - xfs_agf_t *agf; - xfs_buf_t *agfbuf; + struct xfs_agf *agf; + struct xfs_buf *agfbuf = NULL; int agf_dirty = 0; - xfs_agi_t *agi; - xfs_buf_t *agibuf; + struct xfs_agi *agi; + struct xfs_buf *agibuf = NULL; int agi_dirty = 0; - xfs_sb_t *sb; - xfs_buf_t *sbbuf; + struct xfs_sb *sb = NULL; + struct xfs_buf *sbbuf = NULL; int sb_dirty = 0; int status; + char *objname = NULL; - sbbuf = libxfs_readbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_SB_DADDR), - XFS_FSS_TO_BB(mp, 1), 0); - if (!sbbuf) { - do_error(_("can't get root superblock for ag %d\n"), agno); - return; - } - - sb = (xfs_sb_t *)calloc(BBSIZE, 1); + sb = (struct xfs_sb *)calloc(BBSIZE, 1); if (!sb) { do_error(_("can't allocate memory for superblock\n")); - libxfs_putbuf(sbbuf); return; } + + sbbuf = libxfs_readbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_SB_DADDR), + XFS_FSS_TO_BB(mp, 1), 0, &xfs_sb_buf_ops); + if (!sbbuf) { + objname = _("root superblock"); + goto out_free_sb; + } libxfs_sb_from_disk(sb, XFS_BUF_TO_SBP(sbbuf)); + libxfs_sb_quota_from_disk(sb); agfbuf = libxfs_readbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), - XFS_FSS_TO_BB(mp, 1), 0); + XFS_FSS_TO_BB(mp, 1), 0, &xfs_agf_buf_ops); if (!agfbuf) { - do_error(_("can't read agf block for ag %d\n"), agno); - libxfs_putbuf(sbbuf); - free(sb); - return; + objname = _("agf block"); + goto out_free_sbbuf; } agf = XFS_BUF_TO_AGF(agfbuf); agibuf = libxfs_readbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), - XFS_FSS_TO_BB(mp, 1), 0); + XFS_FSS_TO_BB(mp, 1), 0, &xfs_agi_buf_ops); if (!agibuf) { - do_error(_("can't read agi block for ag %d\n"), agno); - libxfs_putbuf(agfbuf); - libxfs_putbuf(sbbuf); - free(sb); - return; + objname = _("agi block"); + goto out_free_agfbuf; } agi = XFS_BUF_TO_AGI(agibuf); @@ -1273,15 +1556,9 @@ } if (status && no_modify) { - libxfs_putbuf(agibuf); - libxfs_putbuf(agfbuf); - libxfs_putbuf(sbbuf); - free(sb); - do_warn(_("bad uncorrected agheader %d, skipping ag...\n"), agno); - - return; + goto out_free_agibuf; } scan_freelist(agf, agcnts); @@ -1290,21 +1567,33 @@ validate_agi(agi, agno, agcnts); ASSERT(agi_dirty == 0 || (agi_dirty && !no_modify)); + ASSERT(agf_dirty == 0 || (agf_dirty && !no_modify)); + ASSERT(sb_dirty == 0 || (sb_dirty && !no_modify)); + + /* + * Only pay attention to CRC/verifier errors if we can correct them. + * Note that we can get uncorrected EFSCORRUPTED errors here because + * the verifier will flag on out of range values that we can't correct + * until phase 5 when we have all the information necessary to rebuild + * the freespace/inode btrees. We can correct bad CRC errors + * immediately, though. + */ + if (!no_modify) { + agi_dirty += (agibuf->b_error == EFSBADCRC); + agf_dirty += (agfbuf->b_error == EFSBADCRC); + sb_dirty += (sbbuf->b_error == EFSBADCRC); + } if (agi_dirty && !no_modify) libxfs_writebuf(agibuf, 0); else libxfs_putbuf(agibuf); - ASSERT(agf_dirty == 0 || (agf_dirty && !no_modify)); - if (agf_dirty && !no_modify) libxfs_writebuf(agfbuf, 0); else libxfs_putbuf(agfbuf); - ASSERT(sb_dirty == 0 || (sb_dirty && !no_modify)); - if (sb_dirty && !no_modify) { if (agno == 0) memcpy(&mp->m_sb, sb, sizeof(xfs_sb_t)); @@ -1319,6 +1608,18 @@ print_inode_list(i); #endif return; + +out_free_agibuf: + libxfs_putbuf(agibuf); +out_free_agfbuf: + libxfs_putbuf(agfbuf); +out_free_sbbuf: + libxfs_putbuf(sbbuf); +out_free_sb: + free(sb); + + if (objname) + do_error(_("can't get %s for ag %d\n"), objname, agno); } #define SCAN_THREADS 32 @@ -1356,6 +1657,8 @@ ifreecount += agcnts[i].ifreecount; } + free(agcnts); + /* * Validate that our manual counts match the superblock. */ diff -Nru xfsprogs-3.1.9ubuntu2/repair/scan.h xfsprogs-3.2.1ubuntu1/repair/scan.h --- xfsprogs-3.1.9ubuntu2/repair/scan.h 2011-03-18 00:09:36.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/scan.h 2013-10-10 21:07:17.000000000 +0000 @@ -35,7 +35,8 @@ bmap_cursor_t *bm_cursor, int isroot, int check_dups, - int *dirty), + int *dirty, + __uint64_t magic), int type, int whichfork, xfs_ino_t ino, @@ -44,9 +45,11 @@ struct blkmap **blkmapp, bmap_cursor_t *bm_cursor, int isroot, - int check_dups); + int check_dups, + __uint64_t magic, + const struct xfs_buf_ops *ops); -int scanfunc_bmap( +int scan_bmapbt( struct xfs_btree_block *block, int level, int type, @@ -59,7 +62,8 @@ bmap_cursor_t *bm_cursor, int isroot, int check_dups, - int *dirty); + int *dirty, + __uint64_t magic); void scan_ags( diff -Nru xfsprogs-3.1.9ubuntu2/repair/versions.c xfsprogs-3.2.1ubuntu1/repair/versions.c --- xfsprogs-3.1.9ubuntu2/repair/versions.c 2009-01-28 10:42:24.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/versions.c 2013-10-10 21:07:17.000000000 +0000 @@ -61,26 +61,16 @@ /* * protect against stray bits in the quota flag field */ - if (sb->sb_qflags & ~(XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD| - XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT| - XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD| - XFS_PQUOTA_ACCT)) { + if (sb->sb_qflags & ~XFS_MOUNT_QUOTA_ALL) { /* * update the incore superblock, if we're in * no_modify mode, it'll never get flushed out * so this is ok. */ do_warn(_("bogus quota flags 0x%x set in superblock"), - sb->sb_qflags & ~(XFS_UQUOTA_ACCT| - XFS_UQUOTA_ENFD| - XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT| - XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD| - XFS_PQUOTA_ACCT)); - - sb->sb_qflags &= (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD| - XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT| - XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD| - XFS_PQUOTA_ACCT); + sb->sb_qflags & ~XFS_MOUNT_QUOTA_ALL); + + sb->sb_qflags &= XFS_MOUNT_QUOTA_ALL; if (!no_modify) do_warn(_(", bogus flags will be cleared\n")); @@ -127,6 +117,7 @@ fs_has_extflgbit = 0; have_uquotino = 0; have_gquotino = 0; + have_pquotino = 0; issue_warning = 0; /* @@ -165,7 +156,7 @@ return(1); } - if (XFS_SB_VERSION_NUM(sb) == XFS_SB_VERSION_4) { + if (XFS_SB_VERSION_NUM(sb) >= XFS_SB_VERSION_4) { if (!fs_sb_feature_bits_allowed) { if (!no_modify) { do_warn( @@ -263,6 +254,10 @@ if (sb->sb_gquotino != 0 && sb->sb_gquotino != NULLFSINO) have_gquotino = 1; + + if (sb->sb_pquotino != 0 && + sb->sb_pquotino != NULLFSINO) + have_pquotino = 1; } } diff -Nru xfsprogs-3.1.9ubuntu2/repair/xfs_repair.c xfsprogs-3.2.1ubuntu1/repair/xfs_repair.c --- xfsprogs-3.1.9ubuntu2/repair/xfs_repair.c 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/repair/xfs_repair.c 2014-07-21 09:15:17.000000000 +0000 @@ -29,6 +29,7 @@ #include "prefetch.h" #include "threads.h" #include "progress.h" +#include "dinode.h" #define rounddown(x, y) (((x)/(y))*(y)) @@ -69,7 +70,6 @@ }; -static int ihash_option_used; static int bhash_option_used; static long max_mem_specified; /* in megabytes */ static int phase2_threads = 32; @@ -91,7 +91,7 @@ " -v Verbose output.\n" " -c subopts Change filesystem parameters - use xfs_admin.\n" " -o subopts Override default behaviour, refer to man page.\n" -" -t interval Reporting interval in minutes.\n" +" -t interval Reporting interval in seconds.\n" " -d Repair dangerously.\n" " -V Reports version and exits.\n"), progname); exit(1); @@ -137,6 +137,8 @@ _("bad stripe width in superblock"); err_message[XR_BAD_SVN] = _("bad shared version number in superblock"); + err_message[XR_BAD_CRC] = + _("bad CRC in superblock"); done = 1; } @@ -239,13 +241,13 @@ pre_65_beta = 1; break; case IHASH_SIZE: - libxfs_ihash_size = (int)strtol(val, NULL, 0); - ihash_option_used = 1; + do_warn( + _("-o ihash option has been removed and will be ignored\n")); break; case BHASH_SIZE: if (max_mem_specified) do_abort( - _("-o bhash option cannot be used with -m option\n")); + _("-o bhash option cannot be used with -m option\n")); libxfs_bhash_size = (int)strtol(val, NULL, 0); bhash_option_used = 1; break; @@ -397,14 +399,18 @@ do_inoalign = mp->m_sinoalign; /* - * pre-calculate geometry of ag 0. We know what it looks - * like because we know what mkfs does -- 3 btree roots, - * and some number of blocks to prefill the agfl. + * Pre-calculate the geometry of ag 0. We know what it looks like + * because we know what mkfs does: 2 allocation btree roots (by block + * and by size), the inode allocation btree root, the free inode + * allocation btree root (if enabled) and some number of blocks to + * prefill the agfl. */ bnobt_root = howmany(4 * mp->m_sb.sb_sectsize, mp->m_sb.sb_blocksize); bcntbt_root = bnobt_root + 1; inobt_root = bnobt_root + 2; fino_bno = inobt_root + XFS_MIN_FREELIST_RAW(1, 1, mp) + 1; + if (xfs_sb_version_hasfinobt(&mp->m_sb)) + fino_bno++; /* * If the log is allocated in the first allocation group we need to @@ -529,11 +535,14 @@ xfs_buf_t *sbp; xfs_mount_t xfs_m; char *msgbuf; + struct xfs_sb psb; + int rval; progname = basename(argv[0]); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); + dinode_bmbt_translation_init(); temp_mp = &xfs_m; setbuf(stdout, NULL); @@ -557,11 +566,12 @@ exit(1); } - /* prepare the mount structure */ - sbp = libxfs_readbuf(x.ddev, XFS_SB_DADDR, - 1 << (XFS_MAX_SECTORSIZE_LOG - BBSHIFT), 0); - memset(&xfs_m, 0, sizeof(xfs_mount_t)); - libxfs_sb_from_disk(&xfs_m.m_sb, XFS_BUF_TO_SBP(sbp)); + rval = get_sb(&psb, 0, XFS_MAX_SECTORSIZE, 0); + if (rval != XR_OK) { + do_warn(_("Primary superblock bad after phase 1!\n" + "Exiting now.\n")); + exit(1); + } /* * if the sector size of the filesystem we are trying to repair is @@ -580,7 +590,7 @@ geom.sectsize = BBSIZE; } - if (xfs_m.m_sb.sb_sectsize < geom.sectsize) { + if (psb.sb_sectsize < geom.sectsize) { long old_flags; old_flags = fcntl(fd, F_GETFL, 0); @@ -592,7 +602,10 @@ } } } - mp = libxfs_mount(&xfs_m, &xfs_m.m_sb, x.ddev, x.logdev, x.rtdev, 0); + + /* prepare the mount structure */ + memset(&xfs_m, 0, sizeof(xfs_mount_t)); + mp = libxfs_mount(&xfs_m, &psb, x.ddev, x.logdev, x.rtdev, 0); if (!mp) { fprintf(stderr, @@ -600,8 +613,6 @@ progname); exit(1); } - libxfs_putbuf(sbp); - libxfs_purgebuf(sbp); /* * set XFS-independent status vars from the mount/sb structure @@ -609,13 +620,49 @@ glob_agcount = mp->m_sb.sb_agcount; chunks_pblock = mp->m_sb.sb_inopblock / XFS_INODES_PER_CHUNK; - max_symlink_blocks = howmany(MAXPATHLEN - 1, mp->m_sb.sb_blocksize); + max_symlink_blocks = libxfs_symlink_blocks(mp, MAXPATHLEN); inodes_per_cluster = MAX(mp->m_sb.sb_inopblock, XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog); + /* + * Automatic striding for high agcount filesystems. + * + * More AGs indicates that the filesystem is either large or can handle + * more IO parallelism. Either way, we should try to process multiple + * AGs at a time in such a configuration to try to saturate the + * underlying storage and speed the repair process. Only do this if + * prefetching is enabled. + * + * Given mkfs defaults for 16AGs for "multidisk" configurations, we want + * to target these for an increase in thread count. Hence a stride value + * of 15 is chosen to ensure we get at least 2 AGs being scanned at once + * on such filesystems. + * + * Limit the maximum thread count based on the available CPU power that + * is available. If we use too many threads, we might run out of memory + * and CPU power before we run out of IO concurrency. We limit to 8 + * threads/CPU as this is enough threads to saturate a CPU on fast + * devices, yet few enough that it will saturate but won't overload slow + * devices. + */ + if (!ag_stride && glob_agcount >= 16 && do_prefetch) + ag_stride = 15; + if (ag_stride) { + int max_threads = platform_nproc() * 8; + thread_count = (glob_agcount + ag_stride - 1) / ag_stride; - thread_init(); + while (thread_count > max_threads) { + ag_stride *= 2; + thread_count = (glob_agcount + ag_stride - 1) / + ag_stride; + } + if (thread_count > 0) + thread_init(); + else { + thread_count = 1; + ag_stride = 0; + } } if (ag_stride && report_interval) { @@ -646,9 +693,7 @@ unsigned long max_mem; struct rlimit rlim; - libxfs_icache_purge(); libxfs_bcache_purge(); - cache_destroy(libxfs_icache); cache_destroy(libxfs_bcache); mem_used = (mp->m_sb.sb_icount >> (10 - 2)) + @@ -675,44 +720,41 @@ mp->m_sb.sb_dblocks >> (10 + 1)); if (max_mem <= mem_used) { - /* - * Turn off prefetch and minimise libxfs cache if - * physical memory is deemed insufficient - */ if (max_mem_specified) { do_abort( _("Required memory for repair is greater that the maximum specified\n" "with the -m option. Please increase it to at least %lu.\n"), mem_used / 1024); - } else { - do_warn( - _("Not enough RAM available for repair to enable prefetching.\n" - "This will be _slow_.\n" - "You need at least %luMB RAM to run with prefetching enabled.\n"), - mem_used * 1280 / (1024 * 1024)); } - do_prefetch = 0; - libxfs_bhash_size = 64; - } else { - max_mem -= mem_used; - if (max_mem >= (1 << 30)) - max_mem = 1 << 30; - libxfs_bhash_size = max_mem / (HASH_CACHE_RATIO * - (mp->m_inode_cluster_size >> 10)); - if (libxfs_bhash_size < 512) - libxfs_bhash_size = 512; + do_warn( + _("Memory available for repair (%luMB) may not be sufficient.\n" + "At least %luMB is needed to repair this filesystem efficiently\n" + "If repair fails due to lack of memory, please\n"), + max_mem / 1024, mem_used / 1024); + if (do_prefetch) + do_warn( + _("turn prefetching off (-P) to reduce the memory footprint.\n")); + else + do_warn( + _("increase system RAM and/or swap space to at least %luMB.\n"), + mem_used * 2 / 1024); + + max_mem = mem_used; } + max_mem -= mem_used; + if (max_mem >= (1 << 30)) + max_mem = 1 << 30; + libxfs_bhash_size = max_mem / (HASH_CACHE_RATIO * + (mp->m_inode_cluster_size >> 10)); + if (libxfs_bhash_size < 512) + libxfs_bhash_size = 512; + if (verbose) do_log(_(" - block cache size set to %d entries\n"), libxfs_bhash_size * HASH_CACHE_RATIO); - if (!ihash_option_used) - libxfs_ihash_size = libxfs_bhash_size; - - libxfs_icache = cache_init(libxfs_ihash_size, - &libxfs_icache_operations); - libxfs_bcache = cache_init(libxfs_bhash_size, + libxfs_bcache = cache_init(0, libxfs_bhash_size, &libxfs_bcache_operations); } @@ -773,7 +815,7 @@ _("Inode allocation btrees are too corrupted, skipping phases 6 and 7\n")); } - if (lost_quotas && !have_uquotino && !have_gquotino) { + if (lost_quotas && !have_uquotino && !have_gquotino && !have_pquotino) { if (!no_modify) { do_warn( _("Warning: no quota inodes were found. Quotas disabled.\n")); @@ -850,11 +892,10 @@ dsb = XFS_BUF_TO_SBP(sbp); - if (be16_to_cpu(dsb->sb_qflags) & (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)) { + if (be16_to_cpu(dsb->sb_qflags) & XFS_ALL_QUOTA_CHKD) { do_warn(_("Note - quota info will be regenerated on next " "quota mount.\n")); - dsb->sb_qflags &= cpu_to_be16(~(XFS_UQUOTA_CHKD | - XFS_OQUOTA_CHKD)); + dsb->sb_qflags &= cpu_to_be16(~XFS_ALL_QUOTA_CHKD); } if (clear_sunit) { @@ -883,6 +924,11 @@ if (verbose) summary_report(); do_log(_("done\n")); + + if (dangerously && !no_modify) + do_warn( +_("Repair of readonly mount complete. Immediate reboot encouraged.\n")); + pftrace_done(); return (0); diff -Nru xfsprogs-3.1.9ubuntu2/rtcp/xfs_rtcp.c xfsprogs-3.2.1ubuntu1/rtcp/xfs_rtcp.c --- xfsprogs-3.1.9ubuntu2/rtcp/xfs_rtcp.c 2011-10-21 22:46:09.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/rtcp/xfs_rtcp.c 2014-05-02 00:09:16.000000000 +0000 @@ -27,7 +27,7 @@ void usage() { - fprintf(stderr, _("%s [-e extsize] [-p] source target\n"), progname); + fprintf(stderr, _("%s [-e extsize] [-p] [-V] source target\n"), progname); exit(2); } @@ -224,6 +224,7 @@ if ( !(fsxattr.fsx_xflags & XFS_XFLAG_REALTIME) ) { fprintf(stderr, _("%s: %s is not a realtime file.\n"), progname, tbuf); + close( tofd ); return( -1 ); } @@ -234,6 +235,7 @@ fprintf(stderr, _("%s: %s file extent size is %d, " "instead of %d.\n"), progname, tbuf, fsxattr.fsx_extsize, fextsize); + close( tofd ); return( -1 ); } } diff -Nru xfsprogs-3.1.9ubuntu2/VERSION xfsprogs-3.2.1ubuntu1/VERSION --- xfsprogs-3.1.9ubuntu2/VERSION 2012-12-12 23:21:22.000000000 +0000 +++ xfsprogs-3.2.1ubuntu1/VERSION 2014-07-21 09:13:53.000000000 +0000 @@ -2,6 +2,6 @@ # This file is used by configure to get version information # PKG_MAJOR=3 -PKG_MINOR=1 -PKG_REVISION=9 +PKG_MINOR=2 +PKG_REVISION=1 PKG_BUILD=1