if (!pblock)
goto out;
EXT_ASSERT(count <= cex->ec_len);
+ //if (count < cex->ec_len)
+ // CDEBUG(D_ERROR, "%d < %lu\n", count, cex->ec_len);
/* insert new extent */
nex.ee_block = cex->ec_block;
int *created, int create,
struct semaphore *optional_sem)
{
- int rc;
+ int rc = 0;
+ if (optional_sem != NULL)
+ down(optional_sem);
#ifdef EXT3_MULTIBLOCK_ALLOCATOR
- if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) {
+ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL)
rc = fsfilt_ext3_map_ext_inode_pages(inode, page, pages,
blocks, created, create);
- return rc;
- }
+ else
#endif
- if (optional_sem != NULL)
- down(optional_sem);
- rc = fsfilt_ext3_map_bm_inode_pages(inode, page, pages, blocks,
- created, create);
+ rc = fsfilt_ext3_map_bm_inode_pages(inode, page, pages, blocks,
+ created, create);
if (optional_sem != NULL)
up(optional_sem);
sbi->s_mdsnum = es->s_mdsnum;
}
#endif
+ if (!strncmp(obd->obd_type->typ_name, "obdfilter", 9)) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+ request_queue_t *q = bdev_get_queue(sb->s_bdev);
+ if (q->max_phys_segments * PAGE_SIZE < (1 << 20))
+#else
+ if (MAX_SEGMENTS * PAGE_SIZE < (1 << 20))
+#endif
+ CDEBUG(D_WARNING, "Lustre loves 1MB requests, "
+ "but current max_phys_segments=%d\n",
+ q->max_phys_segments);
+ }
return 0;
}
+static inline int ext3_match (int len, const char * const name,
+ struct ext3_dir_entry_2 * de)
+{
+ if (len != de->name_len)
+ return 0;
+ if (!de->inode)
+ return 0;
+ return !memcmp(name, de->name, len);
+}
+static int fsfilt_ext3_scan_for_entry(struct dentry *dentry)
+{
+ struct inode *dir = dentry->d_parent->d_inode;
+ int blksize = dir->i_sb->s_blocksize;
+ int blk = 0, err, num = 0, de_len;
+ struct ext3_dir_entry_2 * de;
+ int count = dir->i_size;
+ struct qstr *name;
+ char *dlimit;
+
+ name = &dentry->d_name;
+ while (count > 0) {
+ struct buffer_head *bh;
+
+ bh = ext3_bread(NULL, dir, blk++, 0, &err);
+ if (bh == NULL) {
+ CERROR("error read dir %lu+%d: %d\n",
+ dir->i_ino, blk, err);
+ break;
+ }
+
+ dlimit = bh->b_data + blksize;
+ de = (struct ext3_dir_entry_2 *) bh->b_data;
+ while ((char *) de < dlimit) {
+ if ((char *) de + name->len <= dlimit &&
+ ext3_match(name->len, name->name, de))
+ num++;
+ de_len = le16_to_cpu(de->rec_len);
+ de = (struct ext3_dir_entry_2 *) ((char *) de + de_len);
+ }
+
+ count -= blksize;
+ brelse(bh);
+ }
+
+ return num;
+}
+
extern int ext3_add_dir_entry(struct dentry *dentry);
extern int ext3_del_dir_entry(struct dentry *dentry);
unsigned long fid)
{
#ifdef EXT3_FEATURE_INCOMPAT_MDSNUM
+ struct mds_obd *mdsobd = &obd->u.mds;
struct dentry *dentry;
int err;
LASSERT(ino != 0);
* it cross-ref by subsequent lookups */
d_drop(dentry);
+ if (parent->d_inode->i_ino == id_ino(&mdsobd->mds_rootid)) {
+ err = fsfilt_ext3_scan_for_entry(dentry);
+ if (err != 0)
+ CDEBUG(D_ERROR, "existing %d entry %*s in %lu/%u\n",
+ err, dentry->d_name.len, dentry->d_name.name,
+ parent->d_inode->i_ino, parent->d_inode->i_generation);
+ }
+
dentry->d_flags |= DCACHE_CROSS_REF;
dentry->d_inum = ino;
dentry->d_mdsnum = mds;
struct dentry *dentry)
{
#ifdef EXT3_FEATURE_INCOMPAT_MDSNUM
+ struct inode *dir = dentry->d_parent->d_inode;
+ struct mds_obd *mdsobd = &obd->u.mds;
int err;
lock_24kernel();
err = ext3_del_dir_entry(dentry);
unlock_24kernel();
+ if (!err && dir->i_ino == id_ino(&mdsobd->mds_rootid)) {
+ int num = fsfilt_ext3_scan_for_entry(dentry);
+ if (num != 0)
+ CDEBUG(D_ERROR, "existing %d entry %*s in %lu/%u\n",
+ err, dentry->d_name.len, dentry->d_name.name,
+ dir->i_ino, dir->i_generation);
+ }
if (err == 0)
d_drop(dentry);
return err;