can be cause of random memory corruption with 2.4 kernel.
b=12134
i=wangdi
i=green
Description: update patchless client
Details : Add support for patchless client with 2.6.20, 2.6.21 and RHEL 5
+Severity : normal
+Frequency : only with 2.4 kernel
+Bugzilla : 12134
+Description: random memory corruption
+Details : size of struct ll_inode_info is to big for union inode.u and this
+ can be cause of random memory corruption.
+
--------------------------------------------------------------------------------
2007-05-03 Cluster File Systems, Inc. <info@clusterfs.com>
OBD_MD_FLSIZE | OBD_MD_FLBLOCKS |
OBD_MD_FLATIME | OBD_MD_FLMTIME |
OBD_MD_FLCTIME);
- if (0 /* ll_is_inode_dirty(inode) */) {
+ if (ll_is_inode_dirty(inode)) {
oa->o_flags = MDS_BFLAG_UNCOMMITTED_WRITES;
oa->o_valid |= OBD_MD_FLFLAGS;
}
if (rc == EAGAIN) {
/* We are the last writer, so the MDS has instructed us to get
* the file size and any write cookies, then close again. */
- //ll_queue_done_writing(inode);
+ ll_queue_done_writing(inode);
rc = 0;
} else if (rc) {
CERROR("inode %lu mdc close failed: rc = %d\n",
lsm->lsm_oinfo[stripe]->loi_kms = kms;
unlock_res_and_lock(lock);
lov_stripe_unlock(lsm);
- //ll_try_done_writing(inode);
+ ll_try_done_writing(inode);
iput:
iput(inode);
break;
lvb = lock->l_lvb_data;
lsm->lsm_oinfo[stripe].loi_rss = lvb->lvb_size;
- LOCK_INODE_MUTEX(inode);
lock_res_and_lock(lock);
+ ll_inode_size_lock(inode, 1);
kms = MAX(lsm->lsm_oinfo[stripe].loi_kms, lvb->lvb_size);
kms = ldlm_extent_shift_kms(NULL, kms);
if (lsm->lsm_oinfo[stripe].loi_kms != kms)
LDLM_DEBUG(lock, "updating kms from "LPU64" to "LPU64,
lsm->lsm_oinfo[stripe].loi_kms, kms);
lsm->lsm_oinfo[stripe].loi_kms = kms;
+ ll_inode_size_unlock(inode, 1);
unlock_res_and_lock(lock);
- UNLOCK_INODE_MUTEX(inode);
}
iput:
if (oa == NULL)
RETURN(-ENOMEM);
- down(&lli->lli_open_sem);
+ down(&lli->lli_size_sem);
lsm = lli->lli_smd;
if (lsm == NULL)
GOTO(out, rc = -ENOENT);
OBD_FREE(lsm2, lsm_size);
GOTO(out, rc);
out:
- up(&lli->lli_open_sem);
+ up(&lli->lli_size_sem);
obdo_free(oa);
return rc;
}
int rc = 0;
ENTRY;
- down(&lli->lli_open_sem);
+ down(&lli->lli_size_sem);
lsm = lli->lli_smd;
if (lsm) {
- up(&lli->lli_open_sem);
+ up(&lli->lli_size_sem);
CDEBUG(D_IOCTL, "stripe already exists for ino %lu\n",
inode->i_ino);
RETURN(-EEXIST);
ll_release_openhandle(file->f_dentry, &oit);
out:
- up(&lli->lli_open_sem);
+ up(&lli->lli_size_sem);
ll_intent_release(&oit);
RETURN(rc);
out_req_free:
#include <lustre_lite.h>
#include "llite_internal.h"
+#ifdef HAVE_CLOSE_THREAD
/* record that a write is in flight */
void llap_write_pending(struct inode *inode, struct ll_async_page *llap)
{
EXIT;
}
-#if 0
/* If we know the file size and have the cookies:
* - send a DONE_WRITING rpc
*
rc = mdc_done_writing(ll_i2sbi(inode)->ll_mdc_exp, &obdo);
out:
}
-#endif
+
static struct ll_inode_info *ll_close_next_lli(struct ll_close_queue *lcq)
{
spin_unlock(&lcq->lcq_lock);
return lli;
}
+#else
+static struct ll_inode_info *ll_close_next_lli(struct ll_close_queue *lcq)
+{
+ if (lcq->lcq_list.next == NULL)
+ return ERR_PTR(-1);
+
+ return NULL;
+}
+#endif
static int ll_close_thread(void *arg)
{
wait_for_completion(&lcq->lcq_comp);
OBD_FREE(lcq, sizeof(*lcq));
}
+
+
struct ll_inode_info {
int lli_inode_magic;
- struct semaphore lli_size_sem;
+ struct semaphore lli_size_sem; /* protect open and change size */
void *lli_size_sem_owner;
- struct semaphore lli_open_sem;
struct semaphore lli_write_sem;
struct lov_stripe_md *lli_smd;
char *lli_symlink_name;
/* this lock protects s_d_w and p_w_ll and mmap_cnt */
spinlock_t lli_lock;
+#ifdef HAVE_CLOSE_THREAD
struct list_head lli_pending_write_llaps;
+ struct list_head lli_close_item;
int lli_send_done_writing;
+#endif
atomic_t lli_mmap_cnt;
- struct list_head lli_close_item;
-
/* for writepage() only to communicate to fsync */
int lli_async_rc;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
return container_of(inode, struct ll_inode_info, lli_vfs_inode);
#else
+ CLASSERT(sizeof(inode->u) >= sizeof(struct ll_inode_info));
return (struct ll_inode_info *)&(inode->u.generic_ip);
#endif
}
int ll_objects_destroy(struct ptlrpc_request *request, struct inode *dir);
struct inode *ll_iget(struct super_block *sb, ino_t hash,
struct lustre_md *lic);
-struct dentry *ll_find_alias(struct inode *, struct dentry *);
int ll_mdc_cancel_unused(struct lustre_handle *, struct inode *, int flags,
void *opaque);
int ll_mdc_blocking_ast(struct ldlm_lock *, struct ldlm_lock_desc *,
extern struct cache_definition ll_cache_definition;
void ll_removepage(struct page *page);
int ll_readpage(struct file *file, struct page *page);
-struct ll_async_page *llap_from_cookie(void *cookie);
struct ll_async_page *llap_cast_private(struct page *page);
void ll_readahead_init(struct inode *inode, struct ll_readahead_state *ras);
void ll_ra_accounting(struct ll_async_page *llap,struct address_space *mapping);
struct completion lcq_comp;
};
+#ifdef HAVE_CLOSE_THREAD
void llap_write_pending(struct inode *inode, struct ll_async_page *llap);
void llap_write_complete(struct inode *inode, struct ll_async_page *llap);
void ll_open_complete(struct inode *inode);
int ll_is_inode_dirty(struct inode *inode);
void ll_try_done_writing(struct inode *inode);
void ll_queue_done_writing(struct inode *inode);
+#else
+static inline void llap_write_pending(struct inode *inode,
+ struct ll_async_page *llap) { return; };
+static inline void llap_write_complete(struct inode *inode,
+ struct ll_async_page *llap) { return; };
+static inline void ll_open_complete(struct inode *inode) { return; };
+static inline int ll_is_inode_dirty(struct inode *inode) { return 0; };
+static inline void ll_try_done_writing(struct inode *inode) { return; };
+static inline void ll_queue_done_writing(struct inode *inode) { return; };
+//static inline void ll_close_thread_shutdown(struct ll_close_queue *lcq) { return; };
+//static inline int ll_close_thread_start(struct ll_close_queue **lcq_ret) { return 0; };
+#endif
void ll_close_thread_shutdown(struct ll_close_queue *lcq);
int ll_close_thread_start(struct ll_close_queue **lcq_ret);
}
RETURN(0);
}
-
+
void ll_lli_init(struct ll_inode_info *lli)
{
- sema_init(&lli->lli_open_sem, 1);
+ lli->lli_inode_magic = LLI_INODE_MAGIC;
sema_init(&lli->lli_size_sem, 1);
sema_init(&lli->lli_write_sem, 1);
lli->lli_flags = 0;
lli->lli_maxbytes = PAGE_CACHE_MAXBYTES;
spin_lock_init(&lli->lli_lock);
- INIT_LIST_HEAD(&lli->lli_pending_write_llaps);
- lli->lli_inode_magic = LLI_INODE_MAGIC;
sema_init(&lli->lli_och_sem, 1);
lli->lli_mds_read_och = lli->lli_mds_write_och = NULL;
lli->lli_mds_exec_och = NULL;
lli->lli_open_fd_read_count = lli->lli_open_fd_write_count = 0;
lli->lli_open_fd_exec_count = 0;
INIT_LIST_HEAD(&lli->lli_dead_list);
+#ifdef HAVE_CLOSE_THREAD
+ INIT_LIST_HEAD(&lli->lli_pending_write_llaps);
+#endif
}
/* COMPAT_146 */
0, 0, 0, async_flags);
if (rc == 0) {
LL_CDEBUG_PAGE(D_PAGE, llap->llap_page, "write queued\n");
- //llap_write_pending(inode, llap);
+ llap_write_pending(inode, llap);
GOTO(out, 0);
}
unlock_page(page);
- if (0 && cmd & OBD_BRW_WRITE) {
+ if (cmd & OBD_BRW_WRITE) {
llap_write_complete(page->mapping->host, llap);
ll_try_done_writing(page->mapping->host);
}
CDEBUG(D_VFSTRACE, "VFS Op\n");
/* on symlinks lli_open_sem protects lli_symlink_name allocation/data */
- down(&lli->lli_open_sem);
+ down(&lli->lli_size_sem);
rc = ll_readlink_internal(inode, &request, &symname);
if (rc)
GOTO(out, rc);
rc = vfs_readlink(dentry, buffer, buflen, symname);
ptlrpc_req_finished(request);
out:
- up(&lli->lli_open_sem);
+ up(&lli->lli_size_sem);
RETURN(rc);
}
#endif
CDEBUG(D_VFSTRACE, "VFS Op\n");
- down(&lli->lli_open_sem);
+ down(&lli->lli_size_sem);
rc = ll_readlink_internal(inode, &request, &symname);
- up(&lli->lli_open_sem);
+ up(&lli->lli_size_sem);
if (rc) {
path_release(nd); /* Kernel assumes that ->follow_link()
releases nameidata on error */