CFLAGS=-g -Wall -Werror -luuid
MOUNTPOINT=.
BINS=open-unlink flock-copyup fsync truncate bug418 rmdircheckinode \
- creat-open rename mapper queryfile mkodf_sb
+ creat-open rename mapper queryfile mkodf_sb get_branch_id
all: $(BINS)
--- /dev/null
+/*
+ * Copyright (c) 2007-2007 Erez Zadok
+ * Copyright (c) 2007-2007 Rachita Kothiyal
+ * Copyright (c) 2007-2007 Stony Brook University
+ * Copyright (c) 2007-2007 The Research Foundation of SUNY
+ *
+ * For specific licensing information, see the COPYING file distributed with
+ * this package.
+ *
+ * This Copyright notice must be kept intact and distributed with all sources.
+ */
+
+/* Get branch id for a branch, by path name*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define UUID_LEN 16
+int main(int argc, char *argv[])
+{
+ int fd;
+ unsigned int version;
+ unsigned int no_branches;
+ unsigned int bid;
+ unsigned int pathlength;
+ char path[100];
+ unsigned int permission;
+ unsigned char *uuid;
+ int i;
+ size_t bytes;
+
+ uuid = (unsigned char *)malloc(UUID_LEN);
+
+ fd = open(argv[1], O_RDONLY, 0);
+ bytes = read(fd, &version, 4);
+ bytes = read(fd, &no_branches, 4);
+
+ for (i = 0; i < no_branches; i++) {
+ bytes = read(fd, &bid, 4);
+ bytes = read(fd, &pathlength, 4);
+ bytes = read(fd, path, pathlength);
+ path[pathlength] = '\0';
+ if (strcmp(path, argv[2]) == 0){
+ printf("%d", bid);
+ break;
+ }
+ bytes = read(fd, &permission, 4);
+ bytes = read(fd, uuid, UUID_LEN);
+ }
+
+ close(fd);
+ free(uuid);
+ return 0;
+}
if [ "$TYPE" = "w" ]; then
WH_LOC=`echo $LINE | cut -d' ' -f 2`
NAME=`echo $LINE | cut -d' ' -f 3`
+ elif [ "$TYPE" = "o" ]; then
+ OPQ_LOC=`echo $LINE | cut -d' ' -f 2`
+ NAME=`echo $LINE | cut -d' ' -f 3`
else
NAME=`echo $LINE | cut -d' ' -f 2`
fi
- unset DIR FILE IMMUTABLE SOURCE SYMLINK WH
+ unset DIR FILE IMMUTABLE SOURCE SYMLINK WH OPQ
( echo $TYPE | grep -q d ) && DIR=1
( echo $TYPE | grep -q f ) && FILE=1
( echo $TYPE | grep -q s ) && SOURCE=1
( echo $TYPE | grep -q l ) && SYMLINK=1
( echo $TYPE | grep -q w ) && WH=1
+ ( echo $TYPE | grep -q o ) && OPQ=1
if [ ! -z "$SOURCE" ] ; then
if [ ! -z "$DIR" ] ; then
wh_abs_path=$wh_dir"/"$wh_file
touch $wh_abs_path
fi
+ elif [ ! -z "$OPQ" ]; then
+ if [ "$ODF" -eq "1" ]; then
+ if [ ! -d $ODF_DIR/ns/$NAME ]; then
+ mkdir -p $ODF_DIR"/ns/"$NAME || exit $?
+ fi
+ branch_id=$(./progs/get_branch_id $ODF_DIR/sb $OPQ_LOC)
+ branch_id=`expr $branch_id + 1`;
+ chgrp $branch_id $ODF_DIR"/ns/"$NAME
+ else
+ touch $OPQ_LOC"/"$NAME"/.wh.__dir_opaque"
+ fi
else
echo "What type am i: $TYPE" 1>&2
exit $?
for i in $browse_path; do
(
if [ "$i" == $ODF_DIR/ns/ ]; then
- find $i -type f -samefile $ODF_DIR/whiteout | sed "s:$i:w $i :g"
- break
+ find $i -type f -samefile $ODF_DIR/whiteout | sed "s:$i:w $i :g"
+ find $i -type d -gid +0 | sed "s:$i:o $i :g"
+ break
fi
find $i -type d -printf 'd %p\n'
find $i -type f -not -name ".wh.*" -printf 'f %p\n'
if [ $ODF -eq 0 ]; then
- find $i -type f -name ".wh.*" | sed "s:$i/:w $i :g" | sed "s:\.wh\.::g"
+ find $i -type f -name ".wh.[a-zA-Z0-9]*" | sed "s:$i/:w $i :g" | sed "s:\.wh\.::g"
+ find $i -type f -name ".wh.__dir_opaque" | sed "s:$i/:o $i :g" | sed "s:\/\.wh\.__dir_opaque::g"
fi
find $i -type b -printf 'b %p\n'
find $i -type c -printf 'c %p\n'
first=`echo $line | cut -d" " -f 1`
if [ "$first" == "w" ]; then
echo $line | sed "s: [a-zA-Z0-9\/\_\-]* : $ODF_DIR/ns/ :g" >> /tmp/expected-$$-tmp
+ elif [ "$first" == "o" ]; then
+ echo $line | sed "s: [a-zA-Z0-9\/\_\-]* : $ODF_DIR/ns/ :g" >> /tmp/expected-$$-tmp
else
echo $line >> /tmp/expected-$$-tmp
fi
function rw {
init_odf $LOWER_DIR0 $LOWER_DIR1 $LOWER_DIR2
( directories ; beforefiles ) | create_hierarchy
-
mount_union "" $LOWER_DIR0 $LOWER_DIR1 $LOWER_DIR2
touch $MOUNTPOINT/y
#Sanity check the lower level dirs/files
( directories ; afterfiles_rw ) | check_hierarchy
-
discard_odf
}
function ro {
init_odf $LOWER_DIR0 $LOWER_DIR1=ro $LOWER_DIR2=ro
( directories ; beforefiles ) | create_hierarchy
-
mount_union "" $LOWER_DIR0 $LOWER_DIR1=ro $LOWER_DIR2=ro
touch $MOUNTPOINT/y
unmount_union
( directories ; afterfiles_ro ) | check_hierarchy
-
discard_odf
}
function BUG383 {
init_odf $LOWER_DIR0 $LOWER_DIR1=ro $LOWER_DIR2=ro
( directories ; beforefiles_383 ) | create_hierarchy
-
mount_union "" $LOWER_DIR0 $LOWER_DIR1=ro $LOWER_DIR2=ro
local SM=`umask`
unmount_union
( directories ; afterfiles_383 ) | check_hierarchy
-
discard_odf
}
f $LOWER_DIR0/dir/ro
d $LOWER_DIR1
d $LOWER_DIR1/dir
-f $LOWER_DIR1/dir/.wh.__dir_opaque
+o $LOWER_DIR1 dir
f $LOWER_DIR1/dir/rw
d $LOWER_DIR2
d $LOWER_DIR3
userdel -f -r $UNPRIV_USER
}
+init_odf $LOWER_DIR1=rw $LOWER_DIR0=ro
branch_files | create_hierarchy
chmod 777 $LOWER_DIR0
chmod 700 $LOWER_DIR0/dir
chmod 700 $LOWER_DIR1/dir
chmod 644 $LOWER_DIR0/dir/ro
-chmod 644 $LOWER_DIR1/dir/.wh.__dir_opaque
+if [ $ODF -eq "0" ]; then
+ chmod 644 $LOWER_DIR1/dir/.wh.__dir_opaque
+else
+ chmod 644 $ODF_DIR/ns/dir
+fi
chmod 644 $LOWER_DIR1/dir/rw
PRIV_USER="root"
chown $PRIV_USER $LOWER_DIR0/dir
chown $PRIV_USER $LOWER_DIR1/dir
chown $UNPRIV_USER $LOWER_DIR0/dir/ro
-chown $UNPRIV_USER $LOWER_DIR1/dir/.wh.__dir_opaque
+if [ $ODF -eq "0" ]; then
+ chown $UNPRIV_USER $LOWER_DIR1/dir/.wh.__dir_opaque
+else
+ chown $UNPRIV_USER $ODF_DIR/ns/dir
+fi
chown $UNPRIV_USER $LOWER_DIR1/dir/rw
mount_union "" $LOWER_DIR1=rw $LOWER_DIR0=ro
# unmount, remove user, ...
cleanup
-branch_files | check_hierarchy $TOP_LOWER_DIR
-
+branch_files | check_hierarchy
+discard_odf
complete_test
function beforefiles {
cat <<FILES
-f $LOWER_DIR0/d1/.wh.x
+w $LOWER_DIR0 d1/x
-f $LOWER_DIR0/d1/d2/.wh.d3
+w $LOWER_DIR0 d1/d2/d3
FILES
}
d $LOWER_DIR0/d1/d2/d3
-f $LOWER_DIR0/d1/d2/d3/.wh.__dir_opaque
-f $LOWER_DIR0/d1/x/.wh.__dir_opaque
-f $LOWER_DIR0/y/.wh.__dir_opaque
+o $LOWER_DIR0 d1/d2/d3
+o $LOWER_DIR0 d1/x
+o $LOWER_DIR0 y
FILES
}
d $LOWER_DIR0/d1/x
d $LOWER_DIR0/d1/d2/d3
-f $LOWER_DIR0/d1/d2/d3/.wh.__dir_opaque
-f $LOWER_DIR0/d1/x/.wh.__dir_opaque
-f $LOWER_DIR0/y/.wh.__dir_opaque
+o $LOWER_DIR0 d1/d2/d3
+o $LOWER_DIR0 d1/x
+o $LOWER_DIR0 y
FILES
}
##### simple tests
+init_odf $LOWER_DIR0 $LOWER_DIR1 $LOWER_DIR2
( directories ; beforefiles) | create_hierarchy
mount_union "" $LOWER_DIR0 $LOWER_DIR1 $LOWER_DIR2
checktype $MOUNTPOINT/d1/d2/d3/d4 '-'
unmount_union
-( directories ; afterfiles_rw ) | check_hierarchy $TOP_LOWER_DIR
-
+( directories ; afterfiles_rw ) | check_hierarchy
+discard_odf
#### simple tests
+init_odf $LOWER_DIR0 $LOWER_DIR1=ro $LOWER_DIR2=ro
( directories ; beforefiles) | create_hierarchy
mount_union "" $LOWER_DIR0 $LOWER_DIR1=ro $LOWER_DIR2=ro
checktype $MOUNTPOINT/d1/d2/d3/d4 '-'
unmount_union
-( directories ; afterfiles_ro ) | check_hierarchy $TOP_LOWER_DIR
+( directories ; afterfiles_ro ) | check_hierarchy
+discard_odf
complete_test
cat <<FILES
d $TOP_LOWER_DIR
d $LOWER_DIR0
-f $LOWER_DIR0/.wh.a
+w $LOWER_DIR0 a
d $LOWER_DIR1
f $LOWER_DIR1/a
d $LOWER_DIR2
}
+init_odf
( files ) | create_hierarchy
mount_union "" $LOWER_DIR0 $LOWER_DIR1=ro
./progs/open-unlink $MOUNTPOINT/a || exit $?
unmount_union
-( afterfiles_ro ) | check_hierarchy $TOP_LOWER_DIR
-
+( afterfiles_ro ) | check_hierarchy
+discard_odf
complete_test
d $LOWER_DIR0/s.child
f $LOWER_DIR0/s.child/foo
d $LOWER_DIR0/s.wh
-f $LOWER_DIR0/s.wh/.wh.foo
+w $LOWER_DIR0 s.wh/foo
f $LOWER_DIR0/d.file
d $LOWER_DIR0/d.dir
d $LOWER_DIR0/d.child
f $LOWER_DIR0/d.child/foo
d $LOWER_DIR0/d.wh
-f $LOWER_DIR0/d.wh/.wh.foo
+w $LOWER_DIR0 d.wh/foo
d $LOWER_DIR1
d $LOWER_DIR2
d $LOWER_DIR3
}
function afterfiles_dir2none {
beforefiles | sed -e "`renamestr $LOWER_DIR0/s.dir $LOWER_DIR0/d.none`"
- echo "f $LOWER_DIR0/d.none/.wh.__dir_opaque"
+ if [ $ODF -eq 0 ]; then
+ echo "o $LOWER_DIR0 d.none"
+ fi
}
# dir->file
}
function afterfiles_dir2dir {
beforefiles | grep -v "$LOWER_DIR0/s.dir"
- echo "f $LOWER_DIR0/d.dir/.wh.__dir_opaque"
+ if [ $ODF -eq 0 ]; then
+ echo "o $LOWER_DIR0 d.dir"
+ fi
}
# dir->child
return $?
}
function afterfiles_dir2wh {
- beforefiles | grep -v "$LOWER_DIR0/s.dir" | grep -v "$LOWER_DIR0/d.wh/.wh.foo"
- echo "f $LOWER_DIR0/d.wh/.wh.__dir_opaque"
+ beforefiles | grep -v "$LOWER_DIR0/s.dir" | grep -v "$LOWER_DIR0 d.wh/foo"
+ if [ $ODF -eq 0 ]; then
+ echo "o $LOWER_DIR0 d.wh"
+ fi
}
beforefiles | grep -v "$LOWER_DIR0/s.child"
echo "d $LOWER_DIR0/d.none"
echo "f $LOWER_DIR0/d.none/foo"
- echo "f $LOWER_DIR0/d.none/.wh.__dir_opaque"
+ if [ $ODF -eq 0 ]; then
+ echo "o $LOWER_DIR0 d.none"
+ fi
}
# child->file
function afterfiles_child2dir {
beforefiles | grep -v "$LOWER_DIR0/s.child"
echo "f $LOWER_DIR0/d.dir/foo"
- echo "f $LOWER_DIR0/d.dir/.wh.__dir_opaque"
+ if [ $ODF -eq 0 ]; then
+ echo "o $LOWER_DIR0 d.dir"
+ fi
}
# child->child
return $?
}
function afterfiles_child2wh {
- beforefiles | grep -v "$LOWER_DIR0/s.child" | grep -v "$LOWER_DIR0/d.wh/.wh.foo"
+ beforefiles | grep -v "$LOWER_DIR0/s.child" | grep -v "$LOWER_DIR0 d.wh/foo"
echo "f $LOWER_DIR0/d.wh/foo"
- echo "f $LOWER_DIR0/d.wh/.wh.__dir_opaque"
+ if [ $ODF -eq 0 ]; then
+ echo "o $LOWER_DIR0 d.wh"
+ fi
}
}
function afterfiles_wh2none {
beforefiles | sed -e 's/s\.wh/d\.none/'
- echo "f $LOWER_DIR0/d.none/.wh.__dir_opaque"
+ if [ $ODF -eq 0 ]; then
+ echo "o $LOWER_DIR0 d.none"
+ fi
}
# wh->file
return $?
}
function afterfiles_wh2dir {
- beforefiles | grep -v "$LOWER_DIR0/s.wh"
- echo "f $LOWER_DIR0/d.dir/.wh.foo"
- echo "f $LOWER_DIR0/d.dir/.wh.__dir_opaque"
+ beforefiles | grep -v "$LOWER_DIR0[/ ]s.wh"
+ echo "w $LOWER_DIR0 d.dir/foo"
+ if [ $ODF -eq 0 ]; then
+ echo "o $LOWER_DIR0 d.dir"
+ fi
}
# wh->child
return $?
}
function afterfiles_wh2wh {
- beforefiles | grep -v "$LOWER_DIR0/s.wh"
- echo "f $LOWER_DIR0/d.wh/.wh.__dir_opaque"
+ beforefiles | grep -v "$LOWER_DIR0[/ ]s.wh"
+ if [ $ODF -eq 0 ]; then
+ echo "o $LOWER_DIR0 d.wh"
+ fi
}
SRC="file dir child wh"
do
for d in $DST
do
+ init_odf $LOWER_DIR0
beforefiles | create_hierarchy
mount_union "" $LOWER_DIR0
${s}2${d}
- afterfiles_${s}2${d} | check_hierarchy $TOP_LOWER_DIR
+ afterfiles_${s}2${d} | check_hierarchy
unmount_union
echo -n "[${s} ${d}] "
+ discard_odf
done
done
f $LOWER_DIR0/b
-f $LOWER_DIR1/d1/d2/d3/d4/.wh.c
+w $LOWER_DIR1 d1/d2/d3/d4/c
FILES
}
d $LOWER_DIR0/d5
l $LOWER_DIR0/d5/e
-f $LOWER_DIR1/d1/d2/d3/d4/.wh.c
d $LOWER_DIR0/d1/d2
d $LOWER_DIR0/d1/d2/d3
d $LOWER_DIR0/d1/d2/d3/d4
l $LOWER_DIR0/d1/d2/d3/d4/c
FILES
+if [ $ODF -eq 0 ]; then
+cat <<FILES
+w $LOWER_DIR1 d1/d2/d3/d4/c
+FILES
+fi
}
##### simple tests
+init_odf $LOWER_DIR0 $LOWER_DIR1
( directories ; beforefiles) | create_hierarchy
mount_union "" $LOWER_DIR0 $LOWER_DIR1
do_link $MOUNTPOINT/a $MOUNTPOINT/d1/d2/d3/d4/c || exit $?
unmount_union
-( directories ; afterfiles_rw ) | check_hierarchy $TOP_LOWER_DIR
+( directories ; ( [ $ODF -eq 0 ] && afterfiles_rw ) || afterfiles_ro ) | check_hierarchy
+discard_odf
+init_odf $LOWER_DIR0 $LOWER_DIR1=ro
( directories ; beforefiles) | create_hierarchy
mount_union "" $LOWER_DIR0 $LOWER_DIR1=ro
ln --symbolic $MOUNTPOINT/a $MOUNTPOINT/d1/d2/d3/d4/c || exit $?
unmount_union
-( directories ; afterfiles_ro ) | check_hierarchy $TOP_LOWER_DIR
-
+( directories ; afterfiles_ro ) | check_hierarchy
+discard_odf
complete_test
# read-only test
function rw_test {
+ init_odf
(directories) | create_hierarchy
dd if=/dev/zero of=$LOWER_DIR0/a bs=4000 count=2 2>/dev/null
fi
unmount_union
+ discard_odf
echo -n "[rw] "
}
# read-only tests
function ro_test {
+ init_odf
(directories) | create_hierarchy
dd if=/dev/zero of=$LOWER_DIR0/a bs=4000 count=2 2>/dev/null
fi
unmount_union
+ discard_odf
echo -n "[ro] "
}
function afterfiles_ro {
cat <<FILES
-f $LOWER_DIR0/.wh.a
+w $LOWER_DIR0 a
f $LOWER_DIR1/a
-f $LOWER_DIR0/.wh.b
+w $LOWER_DIR0 b
f $LOWER_DIR1/b
-f $LOWER_DIR0/.wh.c
+w $LOWER_DIR0 c
f $LOWER_DIR1/c
-f $LOWER_DIR0/.wh.d
-
-f $LOWER_DIR0/d1/d2/.wh.e
+w $LOWER_DIR0 d1/d2/e
f $LOWER_DIR1/d1/d2/e
-f $LOWER_DIR0/.wh.g
+w $LOWER_DIR0 g
l $LOWER_DIR1/g
FILES
+if [ $ODF -eq 0 ]; then
+cat <<FILES
+w $LOWER_DIR0 d
+FILES
+fi
}
function afterfiles_rw {
cat <<FILES
-f $LOWER_DIR0/.wh.a
+w $LOWER_DIR0 a
f $LOWER_DIR1/a
-f $LOWER_DIR1/.wh.b
+w $LOWER_DIR1 b
-f $LOWER_DIR0/.wh.c
+w $LOWER_DIR0 c
f $LOWER_DIR1/c
-f $LOWER_DIR0/.wh.d
+w $LOWER_DIR0 d
-f $LOWER_DIR1/d1/d2/.wh.e
+w $LOWER_DIR1 d1/d2/e
-f $LOWER_DIR1/.wh.g
+w $LOWER_DIR1 g
FILES
}
}
function afterfiles_createback_rw {
+if [ $ODF -eq 0 ]; then
cat <<FILES
-f $LOWER_DIR0/a
f $LOWER_DIR1/a
-
+w $LOWER_DIR1 b
+f $LOWER_DIR1/c
+w $LOWER_DIR1 d1/d2/e
+w $LOWER_DIR1 g
+FILES
+fi
+cat <<FILES
+f $LOWER_DIR0/a
f $LOWER_DIR0/b
-f $LOWER_DIR1/.wh.b
-
f $LOWER_DIR0/c
-f $LOWER_DIR1/c
-
f $LOWER_DIR0/d
-
f $LOWER_DIR0/d1/d2/e
-f $LOWER_DIR1/d1/d2/.wh.e
-
f $LOWER_DIR0/g
-f $LOWER_DIR1/.wh.g
FILES
}
function test1
{
##### simple test
+init_odf
( files ; beforefiles) | create_hierarchy
mount_union "" $LOWER_DIR0 $LOWER_DIR1=ro
checktype $MOUNTPOINT/g '-'
unmount_union
-( files ; afterfiles_ro ) | check_hierarchy $TOP_LOWER_DIR
+( files ; afterfiles_ro ) | check_hierarchy
+discard_odf
echo -n "[ro] "
}
function test2
{
##### now unlink files and then create them before unmount
+init_odf
( files ; beforefiles) | create_hierarchy
mount_union "" $LOWER_DIR0 $LOWER_DIR1=ro
checktype $MOUNTPOINT/g 'f'
unmount_union
-( files ; afterfiles_createback_ro ) | check_hierarchy $TOP_LOWER_DIR
+( files ; afterfiles_createback_ro ) | check_hierarchy
+discard_odf
echo -n "[ro createback] "
}
function test3
{
##### now unlink files and then create them after unmount
+init_odf
( files ; beforefiles) | create_hierarchy
mount_union "" $LOWER_DIR0 $LOWER_DIR1=ro
checktype $MOUNTPOINT/g '-'
unmount_union
-( files ; afterfiles_ro ) | check_hierarchy $TOP_LOWER_DIR
+( files ; afterfiles_ro ) | check_hierarchy
+# For ODF case, no discard_odf here, coz we want to use this mounted
+# ODF for the test4 below. Also note there is no init_odf in test4
+# below for the same reason.
echo -n "[ro] "
}
checktype $MOUNTPOINT/g 'f'
unmount_union
-( files ; afterfiles_createback_ro) | check_hierarchy $TOP_LOWER_DIR
-
+( files ; afterfiles_createback_ro) | check_hierarchy
+discard_odf
echo -n "[ro createback 2] "
}
function test5
{
##### simple test with rw branches
+init_odf
( files ; beforefiles) | create_hierarchy
mount_union "" $LOWER_DIR0 $LOWER_DIR1
unmount_union
-( files ; afterfiles_rw) | check_hierarchy $TOP_LOWER_DIR
+( files ; [ $ODF -eq 0 ] && afterfiles_rw) | check_hierarchy
+discard_odf
echo -n "[rw] "
}
function test6
{
##### now unlink files and then create them before unmount
+init_odf
( files ; beforefiles) | create_hierarchy
mount_union "" $LOWER_DIR0 $LOWER_DIR1
checktype $MOUNTPOINT/g 'f'
unmount_union
-( files ; afterfiles_createback_rw ) | check_hierarchy $TOP_LOWER_DIR
-
+( files ; afterfiles_createback_rw ) | check_hierarchy
+discard_odf
echo -n "[rw createback] "
}
function test7
{
##### now unlink files and then create them after unmount
+init_odf
( files ; beforefiles) | create_hierarchy
mount_union "" $LOWER_DIR0 $LOWER_DIR1
checktype $MOUNTPOINT/g '-'
unmount_union
-( files ; afterfiles_rw ) | check_hierarchy $TOP_LOWER_DIR
+( files ; [ $ODF -eq 0 ] && afterfiles_rw ) | check_hierarchy
mount_union "" $LOWER_DIR0 $LOWER_DIR1
checktype $MOUNTPOINT/g 'f'
unmount_union
-( files ; afterfiles_createback_rw) | check_hierarchy $TOP_LOWER_DIR
+( files ; afterfiles_createback_rw) | check_hierarchy
+discard_odf
echo -n "[rw createback 2] "
}