[PATCH]InterMezzo Patch against linux-2.6.6
"Yang, Chen" <[email protected]> Wed, 12 May 2004 03:27:08 +0800 (CST)
| Newsgroups | gmane.comp.file-systems.intermezzo.devel,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
------=_20040512032708_79068
Content-Type: text/plain; charset="gb2312"
Content-Transfer-Encoding: us-ascii
Hi, All:
Below is the patch of InterMezzo again linux-2.6.6, I can confirm that
it's effective. I'm sad to see it's removed in bkl. It seems that this
is the last patch for InterMezzo. :(
Main modification:
"Muli Ben-Yehuda"([email protected])'s patch for intermezzo stack lossage
"Anton Blanchard"([email protected])'s patch for partial stack lossage
Chen Yang's fix to initialized kml_start_recno
Chen Yang's fix to filter TCGETS from presto_ioctl processing
Thanks.
--
Yang, Chen
------=_20040512032708_79068
Content-Type: text/plain; name="patch-2.6.6"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="patch-2.6.6"
diff -urN linux-2.6.6/fs/intermezzo.orig/dir.c linux-2.6.6/fs/intermezzo/dir.c
--- linux-2.6.6/fs/intermezzo.orig/dir.c 2004-05-10 10:32:26.000000000 +0800
+++ linux-2.6.6/fs/intermezzo/dir.c 2004-05-12 03:05:36.661145127 +0800
@@ -874,17 +874,19 @@
int presto_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- char buf[1024];
struct izo_ioctl_data *data = NULL;
struct presto_dentry_data *dd;
int rc;
+ char* buf;
+ static const size_t bufsz = 1024;
ENTRY;
/* Try the filesystem's ioctl first, and return if it succeeded. */
dd = presto_d2d(file->f_dentry);
if (dd && dd->dd_fset) {
- int (*cache_ioctl)(struct inode *, struct file *, unsigned int, unsigned long ) = filter_c2cdfops(dd->dd_fset->fset_cache->cache_filter)->ioctl;
+ int (*cache_ioctl)(struct inode *, struct file *, unsigned int, unsigned long);
+ cache_ioctl = filter_c2cdfops(dd->dd_fset->fset_cache->cache_filter)->ioctl;
rc = -ENOTTY;
if (cache_ioctl)
rc = cache_ioctl(inode, file, cmd, arg);
@@ -899,47 +901,53 @@
return -EPERM;
}
- memset(buf, 0, sizeof(buf));
-
- if (izo_ioctl_getdata(buf, buf + 1024, (void *)arg)) {
+ if(cmd == TCGETS) {
+ EXIT;
+ return -ENOTTY;
+ }
+ /* allocate a zero'd buffer for data */
+ PRESTO_ALLOC(buf, bufsz);
+ if (!buf) {
+ EXIT;
+ return -ENOMEM;
+ }
+
+ if (izo_ioctl_getdata(buf, buf + bufsz, (void *)arg)) {
CERROR("intermezzo ioctl: data error\n");
- return -EINVAL;
+ rc = -EINVAL;
+ goto done;
}
data = (struct izo_ioctl_data *)buf;
switch(cmd) {
case IZO_IOC_REINTKML: {
- int rc;
int cperr;
rc = kml_reint_rec(file, data);
- EXIT;
cperr = copy_to_user((char *)arg, data, sizeof(*data));
if (cperr) {
CERROR("WARNING: cperr %d\n", cperr);
rc = -EFAULT;
}
- return rc;
+ goto done;
}
case IZO_IOC_GET_RCVD: {
struct izo_rcvd_rec rec;
struct presto_file_set *fset;
- int rc;
fset = presto_fset(file->f_dentry);
if (fset == NULL) {
- EXIT;
- return -ENODEV;
- }
+ rc = -ENODEV;
+ goto done;
+ }
+
rc = izo_rcvd_get(&rec, fset, data->ioc_uuid);
- if (rc < 0) {
- EXIT;
- return rc;
- }
+ if (rc < 0)
+ goto done;
- EXIT;
- return copy_to_user((char *)arg, &rec, sizeof(rec))? -EFAULT : 0;
+ rc = copy_to_user((char *)arg, &rec, sizeof(rec))? -EFAULT : 0;
+ goto done;
}
case IZO_IOC_REPSTATUS: {
@@ -948,12 +956,11 @@
struct izo_rcvd_rec rec;
struct presto_file_set *fset;
int minor;
- int rc;
fset = presto_fset(file->f_dentry);
if (fset == NULL) {
- EXIT;
- return -ENODEV;
+ rc = -ENODEV;
+ goto done;
}
minor = presto_f2m(fset);
@@ -962,13 +969,11 @@
rc = izo_repstatus(fset, client_kmlsize,
lr_client, &rec);
- if (rc < 0) {
- EXIT;
- return rc;
- }
+ if (rc < 0)
+ goto done;
- EXIT;
- return copy_to_user((char *)arg, &rec, sizeof(rec))? -EFAULT : 0;
+ rc = copy_to_user((char *)arg, &rec, sizeof(rec))? -EFAULT : 0;
+ goto done;
}
case IZO_IOC_GET_CHANNEL: {
@@ -976,30 +981,28 @@
fset = presto_fset(file->f_dentry);
if (fset == NULL) {
- EXIT;
- return -ENODEV;
+ rc = -ENODEV;
+ goto done;
}
data->ioc_dev = fset->fset_cache->cache_psdev->uc_minor;
CDEBUG(D_PSDEV, "CHANNEL %d\n", data->ioc_dev);
- EXIT;
- return copy_to_user((char *)arg, data, sizeof(*data))? -EFAULT : 0;
+ rc = copy_to_user((char *)arg, data, sizeof(*data))? -EFAULT : 0;
+ goto done;
}
case IZO_IOC_SET_IOCTL_UID:
izo_authorized_uid = data->ioc_uid;
- EXIT;
- return 0;
+ rc = 0;
+ goto done;
case IZO_IOC_SET_PID:
rc = izo_psdev_setpid(data->ioc_dev);
- EXIT;
- return rc;
+ goto done;
case IZO_IOC_SET_CHANNEL:
rc = izo_psdev_setchannel(file, data->ioc_dev);
- EXIT;
- return rc;
+ goto done;
case IZO_IOC_GET_KML_SIZE: {
struct presto_file_set *fset;
@@ -1007,14 +1010,14 @@
fset = presto_fset(file->f_dentry);
if (fset == NULL) {
- EXIT;
- return -ENODEV;
+ rc = -ENODEV;
+ goto done;
}
kmlsize = presto_kml_offset(fset) + fset->fset_kml_logical_off;
- EXIT;
- return copy_to_user((char *)arg, &kmlsize, sizeof(kmlsize))?-EFAULT : 0;
+ rc = copy_to_user((char *)arg, &kmlsize, sizeof(kmlsize))?-EFAULT : 0;
+ goto done;
}
case IZO_IOC_PURGE_FILE_DATA: {
@@ -1022,37 +1025,37 @@
fset = presto_fset(file->f_dentry);
if (fset == NULL) {
- EXIT;
- return -ENODEV;
+ rc = -ENODEV;
+ goto done;
}
rc = izo_purge_file(fset, data->ioc_inlbuf1);
- EXIT;
- return rc;
+ goto done;
}
case IZO_IOC_GET_FILEID: {
rc = izo_get_fileid(file, data);
- EXIT;
if (rc)
- return rc;
- return copy_to_user((char *)arg, data, sizeof(*data))? -EFAULT : 0;
+ goto done;
+
+ rc = copy_to_user((char *)arg, data, sizeof(*data))? -EFAULT : 0;
+ goto done;
}
case IZO_IOC_SET_FILEID: {
rc = izo_set_fileid(file, data);
- EXIT;
if (rc)
- return rc;
- return copy_to_user((char *)arg, data, sizeof(*data))? -EFAULT : 0;
+ goto done;
+
+ rc = copy_to_user((char *)arg, data, sizeof(*data))? -EFAULT : 0;
+ goto done;
}
case IZO_IOC_ADJUST_LML: {
struct lento_vfs_context *info;
info = (struct lento_vfs_context *)data->ioc_inlbuf1;
rc = presto_adjust_lml(file, info);
- EXIT;
- return rc;
+ goto done;
}
case IZO_IOC_CONNECT: {
@@ -1061,16 +1064,15 @@
fset = presto_fset(file->f_dentry);
if (fset == NULL) {
- EXIT;
- return -ENODEV;
+ rc = -ENODEV;
+ goto done;
}
minor = presto_f2m(fset);
rc = izo_upc_connect(minor, data->ioc_ino,
data->ioc_generation, data->ioc_uuid,
data->ioc_flags);
- EXIT;
- return rc;
+ goto done;
}
case IZO_IOC_GO_FETCH_KML: {
@@ -1079,15 +1081,14 @@
fset = presto_fset(file->f_dentry);
if (fset == NULL) {
- EXIT;
- return -ENODEV;
+ rc = -ENODEV;
+ goto done;
}
minor = presto_f2m(fset);
rc = izo_upc_go_fetch_kml(minor, fset->fset_name,
data->ioc_uuid, data->ioc_kmlsize);
- EXIT;
- return rc;
+ goto done;
}
case IZO_IOC_REVOKE_PERMIT:
@@ -1095,26 +1096,23 @@
rc = izo_revoke_permit(file->f_dentry, data->ioc_uuid);
else
rc = izo_revoke_permit(file->f_dentry, NULL);
- EXIT;
- return rc;
+ goto done;
case IZO_IOC_CLEAR_FSET:
rc = izo_clear_fsetroot(file->f_dentry);
- EXIT;
- return rc;
+ goto done;
case IZO_IOC_CLEAR_ALL_FSETS: {
struct presto_file_set *fset;
fset = presto_fset(file->f_dentry);
if (fset == NULL) {
- EXIT;
- return -ENODEV;
+ rc = -ENODEV;
+ goto done;
}
rc = izo_clear_all_fsetroots(fset->fset_cache);
- EXIT;
- return rc;
+ goto done;
}
case IZO_IOC_SET_FSET:
@@ -1124,9 +1122,7 @@
rc = presto_set_fsetroot_from_ioc(file->f_dentry,
data->ioc_inlbuf1,
data->ioc_flags);
- EXIT;
- return rc;
-
+ goto done;
case IZO_IOC_MARK: {
int res = 0; /* resulting flags - returned to user */
@@ -1182,16 +1178,16 @@
}
if (error) {
- EXIT;
- return error;
+ rc = error;
+ goto done;
}
data->ioc_mark_what = res;
CDEBUG(D_DOWNCALL, "mark inode: %ld, and: %x, or: %x, what %x\n",
file->f_dentry->d_inode->i_ino, data->ioc_and_flag,
data->ioc_or_flag, data->ioc_mark_what);
- EXIT;
- return copy_to_user((char *)arg, data, sizeof(*data))? -EFAULT : 0;
+ rc = copy_to_user((char *)arg, data, sizeof(*data))? -EFAULT : 0;
+ goto done;
}
#if 0
case IZO_IOC_CLIENT_MAKE_BRANCH: {
@@ -1200,16 +1196,15 @@
fset = presto_fset(file->f_dentry);
if (fset == NULL) {
- EXIT;
- return -ENODEV;
+ rc = -ENODEV;
+ goto done;
}
minor = presto_f2m(fset);
rc = izo_upc_client_make_branch(minor, fset->fset_name,
data->ioc_inlbuf1,
data->ioc_inlbuf2);
- EXIT;
- return rc;
+ goto done;
}
#endif
case IZO_IOC_SERVER_MAKE_BRANCH: {
@@ -1218,14 +1213,14 @@
fset = presto_fset(file->f_dentry);
if (fset == NULL) {
- EXIT;
- return -ENODEV;
+ rc = -ENODEV;
+ goto done;
}
minor = presto_f2m(fset);
izo_upc_server_make_branch(minor, data->ioc_inlbuf1);
- EXIT;
- return 0;
+ rc = 0;
+ goto done;
}
case IZO_IOC_SET_KMLSIZE: {
struct presto_file_set *fset;
@@ -1234,38 +1229,33 @@
fset = presto_fset(file->f_dentry);
if (fset == NULL) {
- EXIT;
- return -ENODEV;
+ rc = -ENODEV;
+ goto done;
}
minor = presto_f2m(fset);
rc = izo_upc_set_kmlsize(minor, fset->fset_name, data->ioc_uuid,
data->ioc_kmlsize);
- if (rc != 0) {
- EXIT;
- return rc;
- }
+ if (rc != 0)
+ goto done;
rc = izo_rcvd_get(&rec, fset, data->ioc_uuid);
if (rc == -EINVAL) {
/* We don't know anything about this uuid yet; no
* worries. */
memset(&rec, 0, sizeof(rec));
- } else if (rc <= 0) {
+ } else if (rc <= 0) { /* do we really want to return 0 if rc == 0 here? */
CERROR("InterMezzo: error reading last_rcvd: %d\n", rc);
- EXIT;
- return rc;
+ goto done;
}
rec.lr_remote_offset = data->ioc_kmlsize;
rc = izo_rcvd_write(fset, &rec);
if (rc <= 0) {
CERROR("InterMezzo: error writing last_rcvd: %d\n", rc);
- EXIT;
- return rc;
+ goto done;
}
- EXIT;
- return rc;
+ goto done;
}
case IZO_IOC_BRANCH_UNDO: {
struct presto_file_set *fset;
@@ -1273,15 +1263,14 @@
fset = presto_fset(file->f_dentry);
if (fset == NULL) {
- EXIT;
- return -ENODEV;
+ rc = -ENODEV;
+ goto done;
}
minor = presto_f2m(fset);
rc = izo_upc_branch_undo(minor, fset->fset_name,
data->ioc_inlbuf1);
- EXIT;
- return rc;
+ goto done;
}
case IZO_IOC_BRANCH_REDO: {
struct presto_file_set *fset;
@@ -1289,24 +1278,26 @@
fset = presto_fset(file->f_dentry);
if (fset == NULL) {
- EXIT;
- return -ENODEV;
+ rc = -ENODEV;
+ goto done;
}
minor = presto_f2m(fset);
rc = izo_upc_branch_redo(minor, fset->fset_name,
data->ioc_inlbuf1);
- EXIT;
- return rc;
+ goto done;
}
default:
- EXIT;
- return -ENOTTY;
+ rc = -ENOTTY;
+ goto done;
}
+ rc = 0;
+done:
+ PRESTO_FREE(buf,bufsz);
EXIT;
- return 0;
+ return rc;
}
struct file_operations presto_dir_fops = {
diff -urN linux-2.6.6/fs/intermezzo.orig/journal.c linux-2.6.6/fs/intermezzo/journal.c
--- linux-2.6.6/fs/intermezzo.orig/journal.c 2004-05-10 10:31:58.000000000 +0800
+++ linux-2.6.6/fs/intermezzo/journal.c 2004-05-12 03:05:36.665144618 +0800
@@ -1235,12 +1235,16 @@
return izo_rcvd_write(fset, &rec);
}
+/* we are called from presto_finish_kml_truncate, which is called */
+/* with fset->fset_kml.fd_lock held. Allocations must be GFP_ATOMIC */
struct file * presto_copy_kml_tail(struct presto_file_set *fset,
unsigned long int start)
{
struct file *f;
int len;
loff_t read_off, write_off, bytes;
+ char* buf;
+ size_t bufsz;
ENTRY;
@@ -1254,29 +1258,42 @@
write_off = 0;
read_off = start;
bytes = fset->fset_kml.fd_offset - start;
- while (bytes > 0) {
- char buf[4096];
- int toread;
- if (bytes > sizeof(buf))
- toread = sizeof(buf);
- else
- toread = bytes;
+ bufsz = bytes;
+ /* can't use PRESTO_ALLOC - alloction must be atomic */
+ buf = kmalloc(bufsz, GFP_ATOMIC);
+ if (!buf) {
+ CERROR("IZO: out of memory at %s:%d (trying to "
+ "allocate %d)\n", __FILE__, __LINE__,
+ bufsz);
+ filp_close(f, NULL);
+ EXIT;
+ return ERR_PTR(-ENOMEM);
+ }
+
+ presto_kmem_inc(buf, bufsz);
+ memset(buf, 0, bufsz);
- len = presto_fread(fset->fset_kml.fd_file, buf, toread,
+ while (bytes > 0) {
+ len = presto_fread(fset->fset_kml.fd_file, buf, bufsz,
&read_off);
if (len <= 0)
break;
if (presto_fwrite(f, buf, len, &write_off) != len) {
+ kfree(buf);
+ presto_kmem_dec(buf, bufsz);
filp_close(f, NULL);
+ kfree(buf);
EXIT;
return ERR_PTR(-EIO);
}
bytes -= len;
}
-
+
+ kfree(buf);
+ presto_kmem_dec(buf, bufsz);
EXIT;
return f;
}
@@ -1580,19 +1597,27 @@
return error;
}
+#define RECORD_LENGTH 4096
+
int presto_get_fileid(int minor, struct presto_file_set *fset,
struct dentry *dentry)
{
int opcode = KML_OPCODE_GET_FILEID;
struct rec_info rec;
- char *buffer, *path, *logrecord, record[4096]; /*include path*/
+ char *buffer, *path, *logrecord, *record; /*include path*/
struct dentry *root;
__u32 uid, gid, pathlen;
int error, size;
struct kml_suffix *suffix;
+ size_t record_size;
ENTRY;
+ record = kmalloc(RECORD_LENGTH, GFP_KERNEL);
+ if (!record)
+ return -ENOMEM;
+ memset(record, 0, RECORD_LENGTH);
+
root = fset->fset_dentry;
uid = cpu_to_le32(dentry->d_inode->i_uid);
@@ -1605,9 +1630,13 @@
size_round(le32_to_cpu(pathlen)) +
sizeof(struct kml_suffix);
+ record_size = max(4096, size);
+ error = -ENOMEM;
+ PRESTO_ALLOC(record, record_size);
+ if (!record)
+ goto free_buffer;
+
CDEBUG(D_FILE, "kml size: %d\n", size);
- if ( size > sizeof(record) )
- CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__);
memset(&rec, 0, sizeof(rec));
rec.is_kml = 1;
@@ -1628,6 +1657,9 @@
size_round(le32_to_cpu(pathlen)), path,
fset->fset_name);
+ PRESTO_FREE(record, record_size);
+
+ free_buffer:
BUFF_FREE(buffer);
EXIT;
return error;
diff -urN linux-2.6.6/fs/intermezzo.orig/vfs.c linux-2.6.6/fs/intermezzo/vfs.c
--- linux-2.6.6/fs/intermezzo.orig/vfs.c 2004-05-10 10:32:27.000000000 +0800
+++ linux-2.6.6/fs/intermezzo/vfs.c 2004-05-12 03:05:36.669144110 +0800
@@ -297,7 +297,7 @@
int presto_do_close(struct presto_file_set *fset, struct file *file)
{
- struct rec_info rec;
+ struct rec_info rec={0,0,0,0};
int rc = -ENOSPC;
void *handle;
struct inode *inode = file->f_dentry->d_inode;
@@ -362,7 +362,7 @@
int presto_do_setattr(struct presto_file_set *fset, struct dentry *dentry,
struct iattr *iattr, struct lento_vfs_context *info)
{
- struct rec_info rec;
+ struct rec_info rec={0,0,0,0};
struct inode *inode = dentry->d_inode;
struct inode_operations *iops;
int error;
@@ -552,7 +552,7 @@
struct dentry *dentry, int mode,
struct lento_vfs_context *info)
{
- struct rec_info rec;
+ struct rec_info rec={0,0,0,0};
int error;
struct presto_version tgt_dir_ver, new_file_ver;
struct inode_operations *iops;
@@ -714,7 +714,7 @@
struct dentry *dir, struct dentry *new_dentry,
struct lento_vfs_context *info)
{
- struct rec_info rec;
+ struct rec_info rec={0,0,0,0};
struct inode *inode;
int error;
struct inode_operations *iops;
@@ -863,7 +863,7 @@
int presto_do_unlink(struct presto_file_set *fset, struct dentry *dir,
struct dentry *dentry, struct lento_vfs_context *info)
{
- struct rec_info rec;
+ struct rec_info rec={0,0,0,0};
struct inode_operations *iops;
struct presto_version tgt_dir_ver, old_file_ver;
struct izo_rollback_data rb;
@@ -1066,7 +1066,7 @@
struct dentry *dentry, const char *oldname,
struct lento_vfs_context *info)
{
- struct rec_info rec;
+ struct rec_info rec={0,0,0,0};
int error;
struct presto_version tgt_dir_ver, new_link_ver;
struct inode_operations *iops;
@@ -1225,7 +1225,7 @@
struct dentry *dentry, int mode,
struct lento_vfs_context *info)
{
- struct rec_info rec;
+ struct rec_info rec={0,0,0,0};
int error;
struct presto_version tgt_dir_ver, new_dir_ver;
void *handle;
@@ -1385,7 +1385,7 @@
int presto_do_rmdir(struct presto_file_set *fset, struct dentry *dir,
struct dentry *dentry, struct lento_vfs_context *info)
{
- struct rec_info rec;
+ struct rec_info rec={0,0,0,0};
int error;
struct presto_version tgt_dir_ver, old_dir_ver;
struct izo_rollback_data rb;
@@ -1529,7 +1529,7 @@
struct dentry *dentry, int mode, dev_t dev,
struct lento_vfs_context *info)
{
- struct rec_info rec;
+ struct rec_info rec={0,0,0,0};
int error = -EPERM;
struct presto_version tgt_dir_ver, new_node_ver;
struct inode_operations *iops;
@@ -1693,7 +1693,7 @@
struct dentry *new_parent, struct dentry *new_dentry,
struct lento_vfs_context *info)
{
- struct rec_info rec;
+ struct rec_info rec={0,0,0,0};
int error;
struct inode_operations *iops;
struct presto_version src_dir_ver, tgt_dir_ver;
@@ -2298,7 +2298,7 @@
size_t buffer_len, int flags, mode_t *mode,
struct lento_vfs_context *info)
{
- struct rec_info rec;
+ struct rec_info rec={0,0,0,0};
struct inode *inode = dentry->d_inode;
struct inode_operations *iops;
int error;
------=_20040512032708_79068--
-------------------------------------------------------
This SF.Net email is sponsored by Sleepycat Software
Learn developer strategies Cisco, Motorola, Ericsson & Lucent use to deliver
higher performing products faster, at low TCO.
http://www.sleepycat.com/telcomwpreg.php?From=osdnemail3