[Pvfs2-developers] immutable files
Murali Vilayannur
vilayann at mcs.anl.gov
Mon Sep 25 23:38:00 EDT 2006
Hey all,
Attached patch implements support for immutable files in PVFS2.
Immutable files are tagged specially using a utility (pvfs2-xattr) like so
./src/apps/admin/pvfs2-xattr -s -k user.pvfs2.meta_hint -v +immutable /mnt/pvfs/File
The utility can use either the pvfs2 system interfaces or the vfs system
call interfaces to do the right thing.
Once tagged, Immutable files can be cached indefinitely bcos they don't
change which is the
eventual goal of the patch. It does not do that part (caching) efficiently
(yet!).
I used this as an opportunity to implement noatime,
nodiratime and append only files and mount time options properly.
If one wishes to tag a file append only,
./src/apps/admin/pvfs2-xattr -s -k user.pvfs2.meta_hint -v +append /mnt/pvfs/File
or disable atime updates
./src/apps/admin/pvfs2-xattr -s -k user.pvfs2.meta_hint -v +noatime /file
Right now, I allow the system interfaces to revert these special
attributes (although that does open a can of worms in terms of stale
caches etc) but the VFS interfaces do not allow the revert.
I can change it if people feel strongly about this..
./src/apps/admin/pvfs2-xattr -s -k user.pvfs2.meta_hint -v -immutable /mnt/pvfs/File
can be used to remove the immutable file tag so long as it uses the system
interfaces.
I am going to implement a better strategy for using the kernel's page
cache since doing it PAGE_SIZE bytes is fairly inefficient.
Suggestions and comments welcome..
Thanks,
Murali
-------------- next part --------------
Index: configure
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/configure,v
retrieving revision 1.314
diff -u -r1.314 configure
--- configure 20 Sep 2006 22:59:49 -0000 1.314
+++ configure 26 Sep 2006 03:21:54 -0000
@@ -9386,6 +9386,69 @@
done
+ echo "$as_me:$LINENO: checking for generic_file_readv api in kernel" >&5
+echo $ECHO_N "checking for generic_file_readv api in kernel... $ECHO_C" >&6
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+ #define __KERNEL__
+ #include <linux/fs.h>
+ int generic_file_readv(struct inode *inode)
+ {
+ return 0;
+ }
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GENERIC_FILE_READV 1
+_ACEOF
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
echo "$as_me:$LINENO: checking for generic_permission api in kernel" >&5
echo $ECHO_N "checking for generic_permission api in kernel... $ECHO_C" >&6
Index: pvfs2-config.h.in
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/pvfs2-config.h.in,v
retrieving revision 1.83
diff -u -r1.83 pvfs2-config.h.in
--- pvfs2-config.h.in 20 Sep 2006 22:59:50 -0000 1.83
+++ pvfs2-config.h.in 26 Sep 2006 03:21:54 -0000
@@ -71,6 +71,9 @@
/* Define to 1 if you have the <fstab.h> header file. */
#undef HAVE_FSTAB_H
+/* Define if kernel has generic_file_readv */
+#undef HAVE_GENERIC_FILE_READV
+
/* Define if kernel has generic_getxattr */
#undef HAVE_GENERIC_GETXATTR
Index: include/pvfs2-sysint.h
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/include/pvfs2-sysint.h,v
retrieving revision 1.70
diff -u -r1.70 pvfs2-sysint.h
--- include/pvfs2-sysint.h 16 Sep 2006 21:13:14 -0000 1.70
+++ include/pvfs2-sysint.h 26 Sep 2006 03:21:54 -0000
@@ -42,6 +42,7 @@
PVFS2_ALIGN_VAR(char*, dist_params); /* NOTE: caller must free if valid */
PVFS_size dirent_count;
PVFS_ds_type objtype;
+ PVFS_flags flags;
uint32_t mask;
};
typedef struct PVFS_sys_attr_s PVFS_sys_attr;
Index: include/pvfs2-types.h
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/include/pvfs2-types.h,v
retrieving revision 1.135
diff -u -r1.135 pvfs2-types.h
--- include/pvfs2-types.h 22 Sep 2006 19:27:29 -0000 1.135
+++ include/pvfs2-types.h 26 Sep 2006 03:21:55 -0000
@@ -136,6 +136,7 @@
typedef uint32_t PVFS_gid;
typedef uint64_t PVFS_time;
typedef uint32_t PVFS_permissions;
+typedef uint64_t PVFS_flags;
#define encode_PVFS_uid encode_uint32_t
#define decode_PVFS_uid decode_uint32_t
#define encode_PVFS_gid encode_uint32_t
@@ -144,6 +145,8 @@
#define decode_PVFS_time decode_int64_t
#define encode_PVFS_permissions encode_uint32_t
#define decode_PVFS_permissions decode_uint32_t
+#define encode_PVFS_flags encode_uint64_t
+#define decode_PVFS_flags decode_uint64_t
/* contiguous range of handles */
typedef struct
@@ -222,6 +225,11 @@
#define decode_PVFS_ds_type decode_enum
#define encode_PVFS_ds_type encode_enum
+
+/* PVFS Object Flags (PVFS_flags); Add more as we implement them */
+#define PVFS_IMMUTABLE_FL 0x1ULL
+#define PVFS_APPEND_FL 0x2ULL
+#define PVFS_NOATIME_FL 0x4ULL
/* Key/Value Pairs */
/* Extended attributes are stored on objects with */
Index: maint/config/kernel.m4
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/maint/config/kernel.m4,v
retrieving revision 1.14
diff -u -r1.14 kernel.m4
--- maint/config/kernel.m4 20 Sep 2006 22:59:52 -0000 1.14
+++ maint/config/kernel.m4 26 Sep 2006 03:21:56 -0000
@@ -434,6 +434,25 @@
#include <asm/ioctl32.h>
] )
+ AC_MSG_CHECKING(for generic_file_readv api in kernel)
+ dnl if this test passes, the kernel does not have it
+ dnl if this test fails, the kernel has it defined with a different
+ dnl signature! deliberately, the signature for this method has been
+ dnl changed for it to give a compiler error.
+
+ AC_TRY_COMPILE([
+ #define __KERNEL__
+ #include <linux/fs.h>
+ int generic_file_readv(struct inode *inode)
+ {
+ return 0;
+ }
+ ], [],
+ AC_MSG_RESULT(no),
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_GENERIC_FILE_READV, 1, Define if kernel has generic_file_readv),
+ )
+
AC_MSG_CHECKING(for generic_permission api in kernel)
dnl if this test passes, the kernel does not have it
dnl if this test fails, the kernel has it defined with a different
Index: src/apps/admin/module.mk.in
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/apps/admin/module.mk.in,v
retrieving revision 1.40
diff -u -r1.40 module.mk.in
--- src/apps/admin/module.mk.in 13 Sep 2006 20:22:45 -0000 1.40
+++ src/apps/admin/module.mk.in 26 Sep 2006 03:21:56 -0000
@@ -21,6 +21,7 @@
$(DIR)/pvfs2-fsck.c\
$(DIR)/pvfs2-cp.c \
$(DIR)/pvfs2-viewdist.c \
+ $(DIR)/pvfs2-xattr.c \
$(DIR)/pvfs2-touch.c \
$(DIR)/pvfs2-remove-object.c \
$(DIR)/pvfs2-ln.c \
Index: src/apps/admin/pvfs2-stat.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/apps/admin/pvfs2-stat.c,v
retrieving revision 1.8
diff -u -r1.8 pvfs2-stat.c
--- src/apps/admin/pvfs2-stat.c 16 Sep 2006 21:48:39 -0000 1.8
+++ src/apps/admin/pvfs2-stat.c 26 Sep 2006 03:21:56 -0000
@@ -478,7 +478,22 @@
{
fprintf(stdout, " dir entries : %llu\n", llu(attr->dirent_count));
}
-
+
+ if ((attr->mask & PVFS_ATTR_SYS_TYPE) &&
+ (attr->objtype & PVFS_TYPE_METAFILE))
+ {
+ if (attr->flags == 0)
+ fprintf(stdout, " flags : none");
+ else
+ fprintf(stdout, " flags : ");
+ if (attr->flags & PVFS_IMMUTABLE_FL)
+ fprintf(stdout, "immutable, ");
+ if (attr->flags & PVFS_APPEND_FL)
+ fprintf(stdout, "append-only, ");
+ if (attr->flags & PVFS_NOATIME_FL)
+ fprintf(stdout, "noatime ");
+ fprintf(stdout, "\n");
+ }
}
static void usage(int argc, char** argv)
Index: src/client/sysint/sys-getattr.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/client/sysint/sys-getattr.sm,v
retrieving revision 1.103
diff -u -r1.103 sys-getattr.sm
--- src/client/sysint/sys-getattr.sm 16 Sep 2006 21:13:15 -0000 1.103
+++ src/client/sysint/sys-getattr.sm 26 Sep 2006 03:21:57 -0000
@@ -846,11 +846,15 @@
}
}
- /* special case for when users ask for dfile count */
- if(attr->objtype == PVFS_TYPE_METAFILE &&
- sm_p->getattr.req_attrmask & PVFS_ATTR_META_DFILES)
+ if(attr->objtype == PVFS_TYPE_METAFILE)
{
- sysresp->attr.dfile_count = attr->u.meta.dfile_count;
+ /* Copy if there are any special object specific flags */
+ sysresp->attr.flags = attr->u.meta.hint.flags;
+ /* special case for when users ask for dfile count */
+ if (sm_p->getattr.req_attrmask & PVFS_ATTR_META_DFILES)
+ {
+ sysresp->attr.dfile_count = attr->u.meta.dfile_count;
+ }
}
if (attr->objtype == PVFS_TYPE_DIRECTORY)
{
@@ -902,7 +906,6 @@
if (js_p->error_code == 0)
{
-
/* convert outgoing attribute mask based on what we got */
sysresp->attr.mask = PVFS_util_object_to_sys_attr_mask(
sm_p->getattr.attr.mask);
Index: src/client/sysint/sys-io.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/client/sysint/sys-io.sm,v
retrieving revision 1.151
diff -u -r1.151 sys-io.sm
--- src/client/sysint/sys-io.sm 16 Sep 2006 21:13:15 -0000 1.151
+++ src/client/sysint/sys-io.sm 26 Sep 2006 03:21:58 -0000
@@ -449,7 +449,13 @@
js_p->error_code = -PVFS_EBADF;
goto exit;
}
-
+ /* cannot write to an immutable file */
+ if (sm_p->u.io.io_type == PVFS_IO_WRITE
+ && (attr->u.meta.hint.flags & PVFS_IMMUTABLE_FL))
+ {
+ js_p->error_code = -PVFS_EPERM;
+ goto exit;
+ }
ret = PINT_dist_lookup(attr->u.meta.dist);
if (ret)
{
Index: src/client/sysint/sys-truncate.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/client/sysint/sys-truncate.sm,v
retrieving revision 1.51
diff -u -r1.51 sys-truncate.sm
--- src/client/sysint/sys-truncate.sm 16 Sep 2006 21:13:15 -0000 1.51
+++ src/client/sysint/sys-truncate.sm 26 Sep 2006 03:21:59 -0000
@@ -184,6 +184,13 @@
assert(attr->mask & PVFS_ATTR_META_DIST);
assert(attr->u.meta.dfile_count > 0);
assert(attr->u.meta.dist_size > 0);
+ /* cannot truncate an append-only or immutable file */
+ if ((attr->u.meta.hint.flags & PVFS_IMMUTABLE_FL)
+ || (attr->u.meta.hint.flags & PVFS_APPEND_FL))
+ {
+ js_p->error_code = -PVFS_EPERM;
+ return 1;
+ }
sm_p->msgarray_count = attr->u.meta.dfile_count;
Index: src/common/misc/pint-util.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/common/misc/pint-util.c,v
retrieving revision 1.15
diff -u -r1.15 pint-util.c
--- src/common/misc/pint-util.c 13 Sep 2006 20:22:48 -0000 1.15
+++ src/common/misc/pint-util.c 26 Sep 2006 03:21:59 -0000
@@ -230,6 +230,7 @@
}
dest->u.meta.dist_size = src->u.meta.dist_size;
}
+ memcpy(&dest->u.meta.hint, &src->u.meta.hint, sizeof(dest->u.meta.hint));
}
if (src->mask & PVFS_ATTR_SYMLNK_TARGET)
Index: src/common/misc/pvfs2-internal.h
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/common/misc/pvfs2-internal.h,v
retrieving revision 1.5
diff -u -r1.5 pvfs2-internal.h
--- src/common/misc/pvfs2-internal.h 22 Sep 2006 19:27:30 -0000 1.5
+++ src/common/misc/pvfs2-internal.h 26 Sep 2006 03:21:59 -0000
@@ -55,6 +55,16 @@
#define SYMLINK_TARGET_KEYSTR "st\0"
#define SYMLINK_TARGET_KEYLEN 3
+/* Optional xattrs have "user.pvfs2." as a prefix */
+#define SPECIAL_DIST_NAME_KEYSTR "dist_name\0"
+#define SPECIAL_DIST_NAME_KEYLEN 21
+#define SPECIAL_DIST_PARAMS_KEYSTR "dist_params\0"
+#define SPECIAL_DIST_PARAMS_KEYLEN 23
+#define SPECIAL_NUM_DFILES_KEYSTR "num_dfiles\0"
+#define SPECIAL_NUM_DFILES_KEYLEN 22
+#define SPECIAL_METAFILE_HINT_KEYSTR "meta_hint\0"
+#define SPECIAL_METAFILE_HINT_KEYLEN 21
+
#define IO_MAX_REGIONS 64
#endif /* PVFS2_INTERNAL_H */
Index: src/common/misc/pvfs2-util.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/common/misc/pvfs2-util.c,v
retrieving revision 1.94
diff -u -r1.94 pvfs2-util.c
--- src/common/misc/pvfs2-util.c 16 Sep 2006 21:13:16 -0000 1.94
+++ src/common/misc/pvfs2-util.c 26 Sep 2006 03:22:01 -0000
@@ -164,6 +164,7 @@
dest_attr->dfile_count = src_attr->dfile_count;
dest_attr->objtype = src_attr->objtype;
dest_attr->mask = src_attr->mask;
+ dest_attr->flags = src_attr->flags;
if (src_attr->mask & PVFS_ATTR_SYS_SIZE)
{
Index: src/kernel/linux-2.6/file.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/file.c,v
retrieving revision 1.125
diff -u -r1.125 file.c
--- src/kernel/linux-2.6/file.c 20 Sep 2006 22:59:53 -0000 1.125
+++ src/kernel/linux-2.6/file.c 26 Sep 2006 03:22:03 -0000
@@ -119,7 +119,7 @@
} io;
};
-static ssize_t do_read_write(struct rw_options *rw)
+static ssize_t do_direct_read_write(struct rw_options *rw)
{
pvfs2_kernel_op_t *new_op = NULL;
int buffer_index = -1;
@@ -222,7 +222,7 @@
ret = pvfs_bufmap_get(&buffer_index);
if (ret < 0)
{
- gossip_err("do_read_write: pvfs_bufmap_get() "
+ gossip_err("do_direct_read_write: pvfs_bufmap_get() "
"failure (%ld)\n", (long) ret);
goto out;
}
@@ -370,7 +370,7 @@
rw.io.read.inode = inode;
rw.io.read.copy_to_user = copy_to_user;
rw.io.read.readahead_size = readahead_size;
- return do_read_write(&rw);
+ return do_direct_read_write(&rw);
}
/** Read data from a specified offset in a file into a user buffer.
@@ -385,9 +385,14 @@
(file && file->f_dentry && file->f_dentry->d_name.name ?
(char *)file->f_dentry->d_name.name : "UNKNOWN"),
(unsigned long) *offset, (unsigned long) count);
-
- return pvfs2_inode_read(
- file->f_dentry->d_inode, buf, count, offset, 1, 0);
+ /* Reads from immutable files are staged through the page-cache */
+ if (IS_IMMUTABLE(file->f_dentry->d_inode)) {
+ gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_file_read: invoking generic_file_read\n");
+ return generic_file_read(file, buf, count, offset);
+ }
+ else {
+ return pvfs2_inode_read(file->f_dentry->d_inode, buf, count, offset, 1, 0);
+ }
}
/** Write data from a contiguous user buffer into a file at a specified
@@ -405,7 +410,7 @@
rw.count = count;
rw.offset = offset;
rw.io.write.file = file;
- return do_read_write(&rw);
+ return do_direct_read_write(&rw);
}
/*
@@ -559,7 +564,7 @@
return max_nr_iovecs;
}
-static ssize_t do_readv_writev(int type, struct file *file,
+static ssize_t do_direct_readv_writev(int type, struct file *file,
const struct iovec *iov, unsigned long nr_segs, loff_t *offset)
{
ssize_t ret;
@@ -847,7 +852,29 @@
unsigned long nr_segs,
loff_t *offset)
{
- return do_readv_writev(IO_READV, file, iov, nr_segs, offset);
+ if (IS_IMMUTABLE(file->f_dentry->d_inode))
+ {
+#ifdef HAVE_GENERIC_FILE_READV
+ gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_file_readv: invoking generic_file_readv\n");
+ return generic_file_readv(file, iov, nr_segs, offset);
+#else
+ ssize_t tot = 0;
+ unsigned long i;
+ gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_file_readv: invoking generic_file_read %ld\n", nr_segs);
+ for (i = 0; i < nr_segs; i++)
+ {
+ ssize_t tmp;
+ if ((tmp = generic_file_read(file, iov[i].iov_base, iov[i].iov_len, offset)) < 0)
+ {
+ return tmp;
+ }
+ tot += tmp;
+ }
+ return tot;
+#endif
+ }
+ else
+ return do_direct_readv_writev(IO_READV, file, iov, nr_segs, offset);
}
@@ -860,7 +887,7 @@
unsigned long nr_segs,
loff_t *offset)
{
- return do_readv_writev(IO_WRITEV, file, iov, nr_segs, offset);
+ return do_direct_readv_writev(IO_WRITEV, file, iov, nr_segs, offset);
}
@@ -1049,7 +1076,7 @@
}
-static ssize_t do_readx_writex(int type, struct file *file,
+static ssize_t do_direct_readx_writex(int type, struct file *file,
const struct iovec *iov, unsigned long nr_segs,
const struct xtvec *xtvec, unsigned long xtnr_segs)
{
@@ -1346,7 +1373,7 @@
}
if (ret > 0 && inode != NULL && pvfs2_inode != NULL)
{
- if (type == IO_READV)
+ if (type == IO_READX)
{
SetAtimeFlag(pvfs2_inode);
inode->i_atime = CURRENT_TIME;
@@ -1372,7 +1399,7 @@
const struct xtvec *xtvec,
unsigned long xtnr_segs)
{
- return do_readx_writex(IO_READX, file, iov, nr_segs, xtvec, xtnr_segs);
+ return do_direct_readx_writex(IO_READX, file, iov, nr_segs, xtvec, xtnr_segs);
}
#endif
@@ -1386,7 +1413,7 @@
const struct xtvec *xtvec,
unsigned long xtnr_segs)
{
- return do_readx_writex(IO_WRITEX, file, iov, nr_segs, xtvec, xtnr_segs);
+ return do_direct_readx_writex(IO_WRITEX, file, iov, nr_segs, xtvec, xtnr_segs);
}
#endif
@@ -2104,7 +2131,7 @@
gossip_debug(GOSSIP_FILE_DEBUG, "Failed to copy user buffer %d\n", (int) ret);
/* drop the buffer index */
pvfs_bufmap_put(buffer_index);
- gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_file_aio_read: pvfs_bufmap_put %d\n",
+ gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_file_aio_write: pvfs_bufmap_put %d\n",
buffer_index);
/* drop the reference count and deallocate */
put_op(new_op);
@@ -2127,7 +2154,7 @@
error = -ENOMEM;
/* drop the buffer index */
pvfs_bufmap_put(buffer_index);
- gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_file_aio_read: pvfs_bufmap_put %d\n",
+ gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_file_aio_write: pvfs_bufmap_put %d\n",
buffer_index);
/* drop the reference count and deallocate */
put_op(new_op);
@@ -2181,7 +2208,7 @@
error = new_op->downcall.resp.io.amt_complete;
wake_up_daemon_for_return(new_op);
pvfs_bufmap_put(buffer_index);
- gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_file_aio_read: pvfs_bufmap_put %d\n",
+ gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_file_aio_write: pvfs_bufmap_put %d\n",
(int) buffer_index);
if (error > 0)
{
Index: src/kernel/linux-2.6/inode.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/inode.c,v
retrieving revision 1.74
diff -u -r1.74 inode.c
--- src/kernel/linux-2.6/inode.c 20 Sep 2006 22:59:53 -0000 1.74
+++ src/kernel/linux-2.6/inode.c 26 Sep 2006 03:22:03 -0000
@@ -161,6 +161,9 @@
void pvfs2_truncate(struct inode *inode)
{
loff_t orig_size = i_size_read(inode);
+
+ if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ return;
gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2: pvfs2_truncate called on inode %llu "
"with size %ld\n", llu(get_handle_from_ino(inode)), (long) orig_size);
Index: src/kernel/linux-2.6/pvfs2-bufmap.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/pvfs2-bufmap.c,v
retrieving revision 1.43
diff -u -r1.43 pvfs2-bufmap.c
--- src/kernel/linux-2.6/pvfs2-bufmap.c 13 Sep 2006 20:22:55 -0000 1.43
+++ src/kernel/linux-2.6/pvfs2-bufmap.c 26 Sep 2006 03:22:04 -0000
@@ -345,20 +345,20 @@
*
* returns 0 on success, -errno on failure
*/
-int pvfs_bufmap_copy_to_user(void __user *to, int buffer_index, int size)
+int pvfs_bufmap_copy_to_user(void __user *to, int buffer_index, size_t size)
{
- int ret = 0, amt_copied = 0, amt_remaining = 0;
- int cur_copy_size = 0, index = 0;
+ size_t ret = 0, amt_copied = 0, amt_remaining = 0, cur_copy_size = 0;
+ int index = 0;
void __user *offset = to;
void *from_kaddr = NULL;
struct pvfs_bufmap_desc *from = &desc_array[buffer_index];
gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_to_user: to %p, from %p, index %d, "
- "size %d\n", to, from, buffer_index, size);
+ "size %zd\n", to, from, buffer_index, size);
if (bufmap_init == 0)
{
- gossip_err("pvfs2_bufmap_copy_to_user: not yet "
+ gossip_err("pvfs_bufmap_copy_to_user: not yet "
"initialized.\n");
gossip_err("pvfs2: please confirm that pvfs2-client daemon is running.\n");
return -EIO;
@@ -388,19 +388,19 @@
}
int pvfs_bufmap_copy_to_kernel(
- void *to, int buffer_index, int size)
+ void *to, int buffer_index, size_t size)
{
- int amt_copied = 0, amt_remaining = 0;
- int cur_copy_size = 0, index = 0;
+ size_t amt_copied = 0, amt_remaining = 0, cur_copy_size = 0;
+ int index = 0;
void *offset = to, *from_kaddr = NULL;
struct pvfs_bufmap_desc *from = &desc_array[buffer_index];
- gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_to_kernel: to %p, index %d, size %d\n",
+ gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_to_kernel: to %p, index %d, size %zd\n",
to, buffer_index, size);
if (bufmap_init == 0)
{
- gossip_err("pvfs2_bufmap_copy_to_kernel: not yet "
+ gossip_err("pvfs_bufmap_copy_to_kernel: not yet "
"initialized.\n");
gossip_err("pvfs2: please confirm that pvfs2-client daemon is running.\n");
return -EIO;
@@ -430,20 +430,20 @@
* returns 0 on success, -errno on failure
*/
int pvfs_bufmap_copy_from_user(
- int buffer_index, void __user *from, int size)
+ int buffer_index, void __user *from, size_t size)
{
- int ret = 0, amt_copied = 0, amt_remaining = 0;
- int cur_copy_size = 0, index = 0;
+ size_t ret = 0, amt_copied = 0, amt_remaining = 0, cur_copy_size = 0;
+ int index = 0;
void __user *offset = from;
void *to_kaddr = NULL;
struct pvfs_bufmap_desc *to = &desc_array[buffer_index];
gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_from_user: from %p, index %d, "
- "size %d\n", from, buffer_index, size);
+ "size %zd\n", from, buffer_index, size);
if (bufmap_init == 0)
{
- gossip_err("pvfs2_bufmap_copy_from_user: not yet "
+ gossip_err("pvfs_bufmap_copy_from_user: not yet "
"initialized.\n");
gossip_err("pvfs2: please confirm that pvfs2-client daemon is running.\n");
return -EIO;
@@ -488,10 +488,10 @@
int buffer_index,
const struct iovec *iov,
unsigned long nr_segs,
- int size)
+ size_t size)
{
- int ret = 0, amt_copied = 0;
- int cur_copy_size = 0, index = 0;
+ size_t ret = 0, amt_copied = 0, cur_copy_size = 0;
+ int index = 0;
void *to_kaddr = NULL;
void __user *from_addr = NULL;
struct iovec *copied_iovec = NULL;
@@ -499,11 +499,11 @@
unsigned int seg, page_offset = 0;
gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_iovec_from_user: index %d, "
- "size %d\n", buffer_index, size);
+ "size %zd\n", buffer_index, size);
if (bufmap_init == 0)
{
- gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_copy_iovec_from_user: not yet "
+ gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_iovec_from_user: not yet "
"initialized; returning\n");
return -EIO;
}
@@ -528,7 +528,7 @@
}
if (amt_copied != size)
{
- gossip_err("pvfs2_bufmap_copy_iovec_from_user: computed total (%d) is not equal to (%d)\n",
+ gossip_err("pvfs2_bufmap_copy_iovec_from_user: computed total (%zd) is not equal to (%zd)\n",
amt_copied, size);
kfree(copied_iovec);
return -EINVAL;
@@ -572,7 +572,7 @@
ret = copy_from_user(to_kaddr + page_offset, from_addr, cur_copy_size);
pvfs2_kunmap(to->page_array[index]);
#if 0
- gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_copy_iovec_from_user: copying from user %p to kernel %p %d bytes (to_kddr: %p,page_offset: %d)\n",
+ gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_copy_iovec_from_user: copying from user %p to kernel %p %zd bytes (to_kddr: %p,page_offset: %d)\n",
from_addr, to_kaddr + page_offset, cur_copy_size, to_kaddr, page_offset);
#endif
if (ret)
@@ -594,7 +594,7 @@
kfree(copied_iovec);
if (amt_copied != size)
{
- gossip_err("Failed to copy all the data from user space [%d instead of %d]\n",
+ gossip_err("Failed to copy all the data from user space [%zd instead of %zd]\n",
amt_copied, size);
return -EIO;
}
@@ -612,10 +612,11 @@
int buffer_index,
const struct iovec *iov,
unsigned long nr_segs,
- int size)
+ size_t size)
{
- int ret = 0, amt_copied = 0;
- int cur_copy_size = 0, index = 0;
+ size_t ret = 0, amt_copied = 0;
+ size_t cur_copy_size = 0;
+ int index = 0;
void *from_kaddr = NULL;
void __user *to_addr = NULL;
struct iovec *copied_iovec = NULL;
@@ -623,7 +624,7 @@
unsigned int seg, page_offset = 0;
gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_to_user_iovec: index %d, "
- "size %d\n", buffer_index, size);
+ "size %zd\n", buffer_index, size);
if (bufmap_init == 0)
{
@@ -652,7 +653,7 @@
}
if (amt_copied < size)
{
- gossip_err("pvfs2_bufmap_copy_to_user_iovec: computed total (%d) is less than (%d)\n",
+ gossip_err("pvfs2_bufmap_copy_to_user_iovec: computed total (%zd) is less than (%zd)\n",
amt_copied, size);
kfree(copied_iovec);
return -EINVAL;
@@ -734,14 +735,14 @@
* returns number of bytes copied on success,
* -errno on failure
*/
-int pvfs_bufmap_copy_to_user_task(
+size_t pvfs_bufmap_copy_to_user_task(
struct task_struct *tsk,
void __user *to,
int buffer_index,
- int size)
+ size_t size)
{
- int ret = 0, amt_copied = 0, amt_remaining = 0;
- int cur_copy_size = 0, index = 0;
+ size_t ret = 0, amt_copied = 0, amt_remaining = 0, cur_copy_size = 0;
+ int index = 0;
void *from_kaddr = NULL;
struct pvfs_bufmap_desc *from = &desc_array[buffer_index];
@@ -755,7 +756,7 @@
gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_to_user_task: "
" PID: %d, to %p, from %p, index %d, "
- " size %d\n", tsk->pid, to, from, buffer_index, size);
+ " size %zd\n", tsk->pid, to, from, buffer_index, size);
if (bufmap_init == 0)
{
Index: src/kernel/linux-2.6/pvfs2-bufmap.h
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/pvfs2-bufmap.h,v
retrieving revision 1.14
diff -u -r1.14 pvfs2-bufmap.h
--- src/kernel/linux-2.6/pvfs2-bufmap.h 13 Sep 2006 20:22:55 -0000 1.14
+++ src/kernel/linux-2.6/pvfs2-bufmap.h 26 Sep 2006 03:22:04 -0000
@@ -41,36 +41,48 @@
int pvfs_bufmap_copy_from_user(
int buffer_index,
void __user *from,
- int size);
+ size_t size);
int pvfs_bufmap_copy_iovec_from_user(
int buffer_index,
const struct iovec *iov,
unsigned long nr_segs,
- int size);
+ size_t size);
+
+int pvfs_bufmap_copy_iovec_from_kernel(
+ int buffer_index,
+ const struct iovec *iov,
+ unsigned long nr_segs,
+ size_t size);
int pvfs_bufmap_copy_to_user(
void __user *to,
int buffer_index,
- int size);
+ size_t size);
int pvfs_bufmap_copy_to_user_iovec(
int buffer_index,
const struct iovec *iov,
unsigned long nr_segs,
- int size);
+ size_t size);
+
+int pvfs_bufmap_copy_to_kernel_iovec(
+ int buffer_index,
+ const struct iovec *iov,
+ unsigned long nr_segs,
+ size_t size);
int pvfs_bufmap_copy_to_kernel(
void *to,
int buffer_index,
- int size);
+ size_t size);
#ifdef HAVE_AIO_VFS_SUPPORT
-int pvfs_bufmap_copy_to_user_task(
+size_t pvfs_bufmap_copy_to_user_task(
struct task_struct *tsk,
void __user *to,
int buffer_index,
- int size);
+ size_t size);
#endif
#endif /* __PVFS2_BUFMAP_H */
Index: src/kernel/linux-2.6/pvfs2-kernel.h
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/pvfs2-kernel.h,v
retrieving revision 1.131
diff -u -r1.131 pvfs2-kernel.h
--- src/kernel/linux-2.6/pvfs2-kernel.h 20 Sep 2006 22:59:53 -0000 1.131
+++ src/kernel/linux-2.6/pvfs2-kernel.h 26 Sep 2006 03:22:05 -0000
@@ -366,6 +366,7 @@
sector_t last_failed_block_index_read;
int error_code;
+ /* State of in-memory attributes not yet flushed to disk associated with this object */
unsigned long pinode_flags;
/* All allocated pvfs2_inode_t objects are chained to a list */
struct list_head list;
@@ -415,6 +416,16 @@
* file if set. NOTE: this is disabled by default.
*/
int suid;
+ /** noatime option (if set) is inspired by the nfs mount option
+ * that requires the file system to disable atime updates for all
+ * files if set. NOTE: this is disabled by default.
+ */
+ int noatime;
+ /** nodiratime option (if set) is inspired by the nfs mount option
+ * that requires the file system to disable atime updates for
+ * directories alone if set. NOTE: this is disabled by default.
+ */
+ int nodiratime;
} pvfs2_mount_options_t;
/** per superblock private pvfs2 info */
Index: src/kernel/linux-2.6/pvfs2-utils.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/pvfs2-utils.c,v
retrieving revision 1.140
diff -u -r1.140 pvfs2-utils.c
--- src/kernel/linux-2.6/pvfs2-utils.c 20 Sep 2006 22:59:53 -0000 1.140
+++ src/kernel/linux-2.6/pvfs2-utils.c 26 Sep 2006 03:22:07 -0000
@@ -98,6 +98,24 @@
return fsid;
}
+static void pvfs2_set_inode_flags(struct inode *inode,
+ PVFS_sys_attr *attrs)
+{
+ if (attrs->flags & PVFS_IMMUTABLE_FL)
+ inode->i_flags |= S_IMMUTABLE;
+ else
+ inode->i_flags &= ~S_IMMUTABLE;
+ if (attrs->flags & PVFS_APPEND_FL)
+ inode->i_flags |= S_APPEND;
+ else
+ inode->i_flags &= ~S_APPEND;
+ if (attrs->flags & PVFS_NOATIME_FL)
+ inode->i_flags |= S_NOATIME;
+ else
+ inode->i_flags &= ~S_NOATIME;
+ return;
+}
+
/* NOTE: symname is ignored unless the inode is a sym link */
int copy_attributes_to_inode(
struct inode *inode,
@@ -136,32 +154,34 @@
attrs->objtype == PVFS_TYPE_SYMLINK ? "symlink" :
"invalid/unknown");
-
- if ((attrs->objtype == PVFS_TYPE_METAFILE) &&
- (attrs->mask & PVFS_ATTR_SYS_SIZE))
+ if (attrs->objtype == PVFS_TYPE_METAFILE)
{
- inode_size = (loff_t)attrs->size;
- rounded_up_size =
- (inode_size + (4096 - (inode_size % 4096)));
+ pvfs2_set_inode_flags(inode, attrs);
+ if (attrs->mask & PVFS_ATTR_SYS_SIZE)
+ {
+ inode_size = (loff_t)attrs->size;
+ rounded_up_size =
+ (inode_size + (4096 - (inode_size % 4096)));
- pvfs2_lock_inode(inode);
+ pvfs2_lock_inode(inode);
#ifdef PVFS2_LINUX_KERNEL_2_4
#if (PVFS2_LINUX_KERNEL_2_4_MINOR_VER > 21)
- inode->i_bytes = inode_size;
+ inode->i_bytes = inode_size;
#endif
#else
- /* this is always ok for 2.6.x */
- inode->i_bytes = inode_size;
+ /* this is always ok for 2.6.x */
+ inode->i_bytes = inode_size;
#endif
- inode->i_blocks = (unsigned long)(rounded_up_size / 512);
- pvfs2_unlock_inode(inode);
+ inode->i_blocks = (unsigned long)(rounded_up_size / 512);
+ pvfs2_unlock_inode(inode);
- /*
- NOTE: make sure all the places we're called from have
- the inode->i_sem lock. we're fine in 99% of the cases
- since we're mostly called from a lookup.
- */
- inode->i_size = inode_size;
+ /*
+ NOTE: make sure all the places we're called from have
+ the inode->i_sem lock. we're fine in 99% of the cases
+ since we're mostly called from a lookup.
+ */
+ inode->i_size = inode_size;
+ }
}
else if ((attrs->objtype == PVFS_TYPE_SYMLINK) &&
(symname != NULL))
@@ -592,8 +612,18 @@
wbattr.ia_valid |= ATTR_MTIME;
if (CtimeFlag(pvfs2_inode))
wbattr.ia_valid |= ATTR_CTIME;
- if (AtimeFlag(pvfs2_inode))
+ /*
+ * We do not need to honor atime flushes if
+ * a) object has a noatime marker
+ * b) object is a directory and has a nodiratime marker on the fs
+ * c) entire file system is mounted with noatime option
+ */
+ if (!((inode->i_flags & S_NOATIME)
+ || (inode->i_sb->s_flags & MS_NOATIME)
+ || ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode))) && AtimeFlag(pvfs2_inode))
+ {
wbattr.ia_valid |= ATTR_ATIME;
+ }
if (ModeFlag(pvfs2_inode))
{
wbattr.ia_mode = inode->i_mode;
@@ -843,7 +873,8 @@
}
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
{
- gossip_err("pvfs2_inode_setxattr: Immutable inode or append-only inode; operation not permitted\n");
+ gossip_err("pvfs2_inode_setxattr: Immutable inode or append-only "
+ "inode; operation not permitted\n");
return -EPERM;
}
pvfs2_inode = PVFS2_I(inode);
Index: src/kernel/linux-2.6/super.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/super.c,v
retrieving revision 1.85
diff -u -r1.85 super.c
--- src/kernel/linux-2.6/super.c 20 Sep 2006 22:59:53 -0000 1.85
+++ src/kernel/linux-2.6/super.c 26 Sep 2006 03:22:07 -0000
@@ -18,6 +18,9 @@
#endif
static atomic_t pvfs2_inode_alloc_count, pvfs2_inode_dealloc_count;
+static char *keywords[] = {"intr", "acl", "suid", "noatime", "nodiratime"};
+static int num_possible_keywords = sizeof(keywords)/sizeof(char *);
+
static int parse_mount_options(
char *option_str, struct super_block *sb, int silent)
{
@@ -25,8 +28,6 @@
pvfs2_sb_info_t *pvfs2_sb = NULL;
int i = 0, j = 0, num_keywords = 0, got_device = 0;
- static char *keywords[] = {"intr", "acl", "suid"};
- static int num_possible_keywords = 3;
static char options[PVFS2_MAX_NUM_OPTIONS][PVFS2_MAX_MOUNT_OPT_LEN];
if (!silent)
@@ -123,6 +124,24 @@
pvfs2_sb->mnt_options.suid = 1;
break;
}
+ else if (strncmp(options[i], "noatime", 7) == 0)
+ {
+ if (!silent)
+ {
+ gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2: mount option "
+ "noatime specified\n");
+ }
+ pvfs2_sb->mnt_options.noatime = 1;
+ }
+ else if (strncmp(options[i], "nodiratime", 10) == 0)
+ {
+ if (!silent)
+ {
+ gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2: mount option "
+ "nodiratime specified\n");
+ }
+ pvfs2_sb->mnt_options.nodiratime = 1;
+ }
}
}
@@ -174,6 +193,7 @@
new_inode = &pvfs2_inode->vfs_inode;
gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2_alloc_inode: allocated %p\n", pvfs2_inode);
atomic_inc(&pvfs2_inode_alloc_count);
+ new_inode->i_flags &= ~(S_APPEND|S_IMMUTABLE|S_NOATIME);
}
return new_inode;
}
@@ -245,6 +265,7 @@
pvfs2_inode_initialize(pvfs2_inode);
inode->u.generic_ip = pvfs2_inode;
pvfs2_inode->vfs_inode = inode;
+ inode->i_flags &= ~(S_APPEND|S_IMMUTABLE|S_NOATIME);
if (pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_ALL_NOHINT) != 0)
{
@@ -513,6 +534,10 @@
((PVFS2_SB(sb)->mnt_options.acl == 1) ? MS_POSIXACL : 0));
sb->s_xattr = pvfs2_xattr_handlers;
#endif
+ sb->s_flags = ((sb->s_flags & ~MS_NOATIME) |
+ ((PVFS2_SB(sb)->mnt_options.noatime == 1) ? MS_NOATIME : 0));
+ sb->s_flags = ((sb->s_flags & ~MS_NODIRATIME) |
+ ((PVFS2_SB(sb)->mnt_options.nodiratime == 1) ? MS_NODIRATIME : 0));
}
new_op = op_alloc(PVFS2_VFS_OP_FS_MOUNT);
@@ -866,6 +891,10 @@
gossip_err("Failed to parse mount time options\n");
goto error_exit;
}
+ sb->s_flags = ((sb->s_flags & ~MS_NOATIME) |
+ ((PVFS2_SB(sb)->mnt_options.noatime == 1) ? MS_NOATIME : 0));
+ sb->s_flags = ((sb->s_flags & ~MS_NODIRATIME) |
+ ((PVFS2_SB(sb)->mnt_options.nodiratime == 1) ? MS_NODIRATIME : 0));
dev_name = PVFS2_SB(sb)->devname;
}
@@ -1011,9 +1040,13 @@
/* mark the superblock as whether it supports acl's or not */
sb->s_flags = ((sb->s_flags & ~MS_POSIXACL) |
((PVFS2_SB(sb)->mnt_options.acl == 1) ? MS_POSIXACL : 0));
+ sb->s_flags = ((sb->s_flags & ~MS_NOATIME) |
+ ((PVFS2_SB(sb)->mnt_options.noatime == 1) ? MS_NOATIME : 0));
+ sb->s_flags = ((sb->s_flags & ~MS_NODIRATIME) |
+ ((PVFS2_SB(sb)->mnt_options.nodiratime == 1) ? MS_NODIRATIME : 0));
}
else {
- sb->s_flags = (sb->s_flags & ~MS_POSIXACL);
+ sb->s_flags = (sb->s_flags & ~(MS_POSIXACL | MS_NOATIME | MS_NODIRATIME));
}
#if defined(HAVE_GENERIC_GETXATTR) && defined(CONFIG_FS_POSIX_ACL)
Index: src/kernel/linux-2.6/xattr-default.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/xattr-default.c,v
retrieving revision 1.3
diff -u -r1.3 xattr-default.c
--- src/kernel/linux-2.6/xattr-default.c 11 Sep 2006 15:42:40 -0000 1.3
+++ src/kernel/linux-2.6/xattr-default.c 26 Sep 2006 03:22:07 -0000
@@ -26,7 +26,7 @@
if (strcmp(name, "") == 0)
return -EINVAL;
- if ( !S_ISREG(inode->i_mode) &&
+ if (!S_ISREG(inode->i_mode) &&
(!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
{
return -EPERM;
Index: src/proto/endecode-funcs.h
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/proto/endecode-funcs.h,v
retrieving revision 1.19
diff -u -r1.19 endecode-funcs.h
--- src/proto/endecode-funcs.h 13 Sep 2006 20:22:56 -0000 1.19
+++ src/proto/endecode-funcs.h 26 Sep 2006 03:22:08 -0000
@@ -92,6 +92,7 @@
*(pptr) += roundup8(4 + len + 1); \
} while (0)
+
/* keyvals; a lot like strings; decoding points existing character data */
/* BTW we are skipping the read_sz field - keep that in mind */
#define encode_PVFS_ds_keyval(pptr,pbuf) do { \
Index: src/proto/pvfs2-attr.h
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/proto/pvfs2-attr.h,v
retrieving revision 1.39
diff -u -r1.39 pvfs2-attr.h
--- src/proto/pvfs2-attr.h 1 Aug 2006 00:27:15 -0000 1.39
+++ src/proto/pvfs2-attr.h 26 Sep 2006 03:22:08 -0000
@@ -50,6 +50,17 @@
#define PVFS_ATTR_DIR_ALL \
(PVFS_ATTR_DIR_DIRENT_COUNT | PVFS_ATTR_DIR_HINT)
+/* extended hint attributes for a metafile object */
+struct PVFS_metafile_hint_s
+{
+ PVFS_flags flags;
+};
+typedef struct PVFS_metafile_hint_s PVFS_metafile_hint;
+#ifdef __PINT_REQPROTO_ENCODE_FUNCS_C
+endecode_fields_1(PVFS_metafile_hint,
+ PVFS_flags, flags)
+#endif
+
/* attributes specific to metadata objects */
struct PVFS_metafile_attr_s
{
@@ -60,6 +71,7 @@
/* list of datafiles */
PVFS_handle *dfile_array;
uint32_t dfile_count;
+ PVFS_metafile_hint hint;
};
typedef struct PVFS_metafile_attr_s PVFS_metafile_attr;
#ifdef __PINT_REQPROTO_ENCODE_FUNCS_C
@@ -75,6 +87,7 @@
encode_skip4(pptr,); \
for (dfiles_i=0; dfiles_i<(x)->dfile_count; dfiles_i++) \
encode_PVFS_handle(pptr, &(x)->dfile_array[dfiles_i]); \
+ encode_PVFS_metafile_hint(pptr, &(x)->hint); \
} while (0)
#define decode_PVFS_metafile_attr_dfiles(pptr,x) do { int dfiles_i; \
decode_uint32_t(pptr, &(x)->dfile_count); \
@@ -83,6 +96,7 @@
* sizeof(*(x)->dfile_array)); \
for (dfiles_i=0; dfiles_i<(x)->dfile_count; dfiles_i++) \
decode_PVFS_handle(pptr, &(x)->dfile_array[dfiles_i]); \
+ decode_PVFS_metafile_hint(pptr, &(x)->hint); \
} while (0)
#endif
Index: src/proto/pvfs2-req-proto.h
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/proto/pvfs2-req-proto.h,v
retrieving revision 1.146
diff -u -r1.146 pvfs2-req-proto.h
--- src/proto/pvfs2-req-proto.h 15 Sep 2006 00:28:15 -0000 1.146
+++ src/proto/pvfs2-req-proto.h 26 Sep 2006 03:22:10 -0000
@@ -22,7 +22,7 @@
* compatibility (such as changing the semantics or protocol fields for an
* existing request type)
*/
-#define PVFS2_PROTO_MAJOR 2
+#define PVFS2_PROTO_MAJOR 3
/* update PVFS2_PROTO_MINOR on wire protocol changes that preserve backwards
* compatibility (such as adding a new request type)
*/
Index: src/server/get-attr.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/get-attr.sm,v
retrieving revision 1.83
diff -u -r1.83 get-attr.sm
--- src/server/get-attr.sm 16 Sep 2006 20:56:47 -0000 1.83
+++ src/server/get-attr.sm 26 Sep 2006 03:22:10 -0000
@@ -29,19 +29,12 @@
#include "pint-util.h"
#include "pvfs2-internal.h"
-enum
-{
- DIST_NAME_KEY = 0,
- DIST_PARAMS_KEY = 1,
- NUM_DFILES_KEY = 2,
- NUM_SPECIAL_KEYS = 3,
-};
-
PINT_server_trove_keys_s Trove_Special_Keys[] =
{
- {"user.pvfs2.dist_name", 21},
- {"user.pvfs2.dist_params", 23},
- {"user.pvfs2.num_dfiles", 22},
+ {"user.pvfs2.dist_name" , SPECIAL_DIST_NAME_KEYLEN},
+ {"user.pvfs2.dist_params", SPECIAL_DIST_PARAMS_KEYLEN},
+ {"user.pvfs2.num_dfiles" , SPECIAL_NUM_DFILES_KEYLEN},
+ {"user.pvfs2.meta_hint" , SPECIAL_METAFILE_HINT_KEYLEN},
};
enum
@@ -73,6 +66,10 @@
PINT_server_op *s_op, job_status_s *js_p);
static int getattr_read_metafile_distribution_if_required(
PINT_server_op *s_op, job_status_s *js_p);
+static int getattr_read_metafile_hint(
+ PINT_server_op *s_op, job_status_s *js_p);
+static int getattr_interpret_metafile_hint(
+ PINT_server_op *s_op, job_status_s *js_p);
static int getattr_setup_resp(
PINT_server_op *s_op, job_status_s *js_p);
static int getattr_setup_op(
@@ -83,11 +80,13 @@
nested machine pvfs2_get_attr_work_sm(
verify_attribs,
read_symlink_target,
+ read_metafile_hint,
read_metafile_datafile_handles_if_required,
read_metafile_distribution_if_required,
get_dirdata_handle,
get_dirent_count,
interpret_dirent_count,
+ interpret_metafile_hint,
get_dir_hint,
interpret_dir_hint,
setup_resp)
@@ -96,7 +95,7 @@
{
run getattr_verify_attribs;
STATE_SYMLINK => read_symlink_target;
- STATE_METAFILE => read_metafile_datafile_handles_if_required;
+ STATE_METAFILE => read_metafile_hint;
STATE_DIR => get_dirdata_handle;
default => setup_resp;
}
@@ -107,6 +106,19 @@
default => setup_resp;
}
+ state read_metafile_hint
+ {
+ run getattr_read_metafile_hint;
+ default => interpret_metafile_hint;
+ }
+
+ state interpret_metafile_hint
+ {
+ run getattr_interpret_metafile_hint;
+ STATE_METAFILE => read_metafile_datafile_handles_if_required;
+ default => setup_resp;
+ }
+
state read_metafile_datafile_handles_if_required
{
run getattr_read_metafile_datafile_handles_if_required;
@@ -315,19 +327,7 @@
resp_attr->mask &= ~PVFS_ATTR_META_DIST;
}
-
- if ((resp_attr->mask & PVFS_ATTR_META_DFILES) ||
- (resp_attr->mask & PVFS_ATTR_META_DIST))
- {
- gossip_debug(GOSSIP_GETATTR_DEBUG, " * client wants extra "
- "meta info, about to retrieve it now\n");
- js_p->error_code = STATE_METAFILE;
- }
- else
- {
- gossip_debug(GOSSIP_GETATTR_DEBUG, " * client doesn't want "
- "extra meta info, preparing response now\n");
- }
+ js_p->error_code = STATE_METAFILE;
}
else if (resp_attr->objtype == PVFS_TYPE_DATAFILE)
{
@@ -429,7 +429,7 @@
js_p->error_code = 0;
return 1;
}
-
+
s_op->key.buffer = Trove_Common_Keys[SYMLINK_TARGET_KEY].key;
s_op->key.buffer_sz = Trove_Common_Keys[SYMLINK_TARGET_KEY].size;
@@ -453,14 +453,99 @@
ret = job_trove_keyval_read(
s_op->u.getattr.fs_id, s_op->u.getattr.handle,
- &(s_op->key), &(s_op->val),
+ &s_op->key, &s_op->val,
0,
NULL, s_op, 0, js_p,
&i, server_job_context);
+
return ret;
}
+static int getattr_read_metafile_hint(
+ PINT_server_op *s_op, job_status_s *js_p)
+{
+ int ret = -PVFS_EINVAL;
+ job_id_t i;
+ char *buf = NULL;
+
+ assert(s_op->attr.objtype == PVFS_TYPE_METAFILE);
+ buf = (char *) calloc(sizeof(PVFS_metafile_hint) + 1, 1);
+ if (buf == NULL)
+ {
+ js_p->error_code = -PVFS_ENOMEM;
+ /*If we hit an error the DIST & DFILES are no longer valid*/
+ s_op->resp.u.getattr.attr.mask &= ~PVFS_ATTR_META_DIST;
+ s_op->resp.u.getattr.attr.mask &= ~PVFS_ATTR_META_DFILES;
+ return 1;
+ }
+
+ js_p->error_code = 0;
+
+ s_op->key.buffer = Trove_Special_Keys[METAFILE_HINT_KEY].key;
+ s_op->key.buffer_sz = Trove_Special_Keys[METAFILE_HINT_KEY].size;
+
+ s_op->val.buffer = buf;
+ s_op->val.buffer_sz = sizeof(s_op->resp.u.getattr.attr.u.meta.hint) + 1;
+
+ gossip_debug(GOSSIP_GETATTR_DEBUG,
+ " reading metafile hint (coll_id = %d, "
+ "handle = %llu, key = %s (%d), val_buf = %p (%d))\n",
+ s_op->u.getattr.fs_id,
+ llu(s_op->u.getattr.handle), (char *)s_op->key.buffer,
+ s_op->key.buffer_sz, s_op->val.buffer,
+ s_op->val.buffer_sz);
+
+ ret = job_trove_keyval_read(
+ s_op->u.getattr.fs_id, s_op->u.getattr.handle,
+ &s_op->key, &s_op->val,
+ 0,
+ NULL, s_op, 0, js_p,
+ &i, server_job_context);
+
+ return ret;
+}
+
+static int getattr_interpret_metafile_hint(
+ PINT_server_op *s_op, job_status_s *js_p)
+{
+ PVFS_object_attr *resp_attr = NULL;
+
+ resp_attr = &s_op->resp.u.getattr.attr;
+ assert(resp_attr->objtype == PVFS_TYPE_METAFILE);
+ if (js_p->error_code == 0 || js_p->error_code == -TROVE_ENOENT)
+ {
+ if (js_p->error_code == 0)
+ {
+ memcpy(&s_op->resp.u.getattr.attr.u.meta.hint, s_op->val.buffer,
+ sizeof(s_op->resp.u.getattr.attr.u.meta.hint));
+ }
+ if ((resp_attr->mask & PVFS_ATTR_META_DFILES) ||
+ (resp_attr->mask & PVFS_ATTR_META_DIST))
+ {
+ gossip_debug(GOSSIP_GETATTR_DEBUG, " * client wants extra "
+ "meta info, about to retrieve it now\n");
+ js_p->error_code = STATE_METAFILE;
+ }
+ else
+ {
+ gossip_debug(GOSSIP_GETATTR_DEBUG, " * client doesn't want "
+ "extra meta info, preparing response now\n");
+ js_p->error_code = 0;
+ }
+ }
+ else {
+ /*If we hit an error the DIST & DFILES are no longer valid*/
+ s_op->resp.u.getattr.attr.mask &= ~PVFS_ATTR_META_DIST;
+ s_op->resp.u.getattr.attr.mask &= ~PVFS_ATTR_META_DFILES;
+ }
+ if (s_op->val.buffer)
+ {
+ free(s_op->val.buffer);
+ s_op->val.buffer = NULL;
+ }
+ return 1;
+}
static int getattr_read_metafile_datafile_handles_if_required(
PINT_server_op *s_op, job_status_s *js_p)
@@ -531,6 +616,9 @@
gossip_err("Cannot allocate dfile array of count %d\n",
dfile_count);
js_p->error_code = -PVFS_ENOMEM;
+ /*If we hit an error the DIST & DFILES are no longer valid*/
+ s_op->resp.u.getattr.attr.mask &= ~PVFS_ATTR_META_DIST;
+ s_op->resp.u.getattr.attr.mask &= ~PVFS_ATTR_META_DFILES;
return 1;
}
@@ -587,6 +675,8 @@
"handle %llu,%d\n",llu(s_op->u.getattr.handle),
s_op->u.getattr.fs_id);
js_p->error_code = -PVFS_EINVAL;
+ /*If we hit an error the DIST & DFILES are no longer valid*/
+ s_op->resp.u.getattr.attr.mask &= ~PVFS_ATTR_META_DIST;
return 1;
}
assert(s_op->resp.u.getattr.attr.u.meta.dist_size > 0);
@@ -601,8 +691,11 @@
gossip_err("Cannot allocate dist of size %d\n",
s_op->val.buffer_sz);
js_p->error_code = -PVFS_ENOMEM;
+ /*If we hit an error the DIST & DFILES are no longer valid*/
+ s_op->resp.u.getattr.attr.mask &= ~PVFS_ATTR_META_DIST;
return 1;
}
+ s_op->free_val = 1;
ret = job_trove_keyval_read(
s_op->u.getattr.fs_id, s_op->u.getattr.handle,
@@ -628,10 +721,14 @@
}
if(js_p->error_code < 0)
{
- if(s_op->val.buffer)
+ if (s_op->free_val && s_op->val.buffer)
{
free(s_op->val.buffer);
+ s_op->free_val = 0;
}
+ /*If we hit an error the DIST & DFILES are no longer valid*/
+ s_op->resp.u.getattr.attr.mask &= ~PVFS_ATTR_META_DIST;
+ s_op->resp.u.getattr.attr.mask &= ~PVFS_ATTR_META_DFILES;
return 1;
}
@@ -922,7 +1019,6 @@
{
js_p->error_code = -PVFS_ENOMEM;
return 1;
-
}
for (i = 0; i < NUM_SPECIAL_KEYS; i++)
{
Index: src/server/pvfs2-server.h
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/pvfs2-server.h,v
retrieving revision 1.141
diff -u -r1.141 pvfs2-server.h
--- src/server/pvfs2-server.h 20 Sep 2006 04:36:15 -0000 1.141
+++ src/server/pvfs2-server.h 26 Sep 2006 03:22:11 -0000
@@ -135,14 +135,24 @@
} PINT_server_trove_keys_s;
extern PINT_server_trove_keys_s Trove_Common_Keys[];
-
-enum
+/* Reserved keys */
+enum
{
ROOT_HANDLE_KEY = 0,
DIR_ENT_KEY = 1,
METAFILE_HANDLES_KEY = 2,
METAFILE_DIST_KEY = 3,
- SYMLINK_TARGET_KEY = 4
+ SYMLINK_TARGET_KEY = 4,
+};
+
+/* optional; user-settable keys */
+enum
+{
+ DIST_NAME_KEY = 0,
+ DIST_PARAMS_KEY = 1,
+ NUM_DFILES_KEY = 2,
+ NUM_SPECIAL_KEYS = 3, /* not an index */
+ METAFILE_HINT_KEY = 3,
};
typedef enum
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pvfs2-xattr.c
Type: text/x-csrc
Size: 12598 bytes
Desc:
Url : http://www.beowulf-underground.org/pipermail/pvfs2-developers/attachments/20060925/656c618c/pvfs2-xattr-0001.bin
More information about the Pvfs2-developers
mailing list