#define FSFILT_OP_LINK 9
#define FSFILT_OP_CANCEL_UNLINK 10
-struct obd_reservation_handle {
+struct obd_handle {
void *orh_filt_handle;
int orh_reserve;
};
}
static inline int fsfilt_reserve(struct obd_device *obd, struct super_block *sb,
- int reserve, struct obd_reservation_handle **h)
+ int reserve, struct obd_handle **h)
{
- struct obd_reservation_handle *handle;
+ struct obd_handle *handle;
OBD_ALLOC(handle, sizeof(*handle));
if (!handle)
return 0;
}
+static inline void fsfilt_release(struct obd_device *obd,
+ struct obd_handle *handle)
+{
+ struct obd_handle *h = handle;
+
+ spin_lock(&obd->obd_osfs_lock);
+ obd->obd_reserve_space -= h->orh_reserve;
+ LASSERT(obd->obd_reserve_space >= 0);
+ spin_unlock(&obd->obd_osfs_lock);
+
+ OBD_FREE(h, sizeof(*h));
+}
+
static inline void *fsfilt_start_log(struct obd_device *obd,
struct inode *inode, int op,
struct obd_trans_info *oti, int logs)
{
unsigned long now = jiffies;
- struct obd_reservation_handle *parent_handle = oti?oti->oti_handle:NULL;
- struct obd_reservation_handle *h;
+ struct obd_handle *parent_handle = oti ? oti->oti_handle : NULL, *h;
int reserve = 0;
int rc;
logs);
CDEBUG(D_HA, "started handle %p (%p)\n", h->orh_filt_handle,
parent_handle);
+ if (IS_ERR(h->orh_filt_handle)) {
+ rc = PTR_ERR(h->orh_filt_handle);
+ fsfilt_release(obd, h);
+ RETURN(ERR_PTR(rc));
+ }
if (oti != NULL) {
if (parent_handle == NULL) {
int objcount,
struct fsfilt_objinfo *fso,
int niocount, struct niobuf_local *nb,
- struct obd_trans_info *oti,int numlogs)
+ struct obd_trans_info *oti, int logs)
{
unsigned long now = jiffies;
- struct obd_reservation_handle *parent_handle = oti?oti->oti_handle:NULL;
- struct obd_reservation_handle *h;
+ struct obd_handle *parent_handle = oti ? oti->oti_handle : NULL, *h;
int reserve = 0;
int rc;
if (obd->obd_fsops->fs_get_op_len)
- reserve = obd->obd_fsops->fs_get_op_len(objcount, fso, numlogs);
+ reserve = obd->obd_fsops->fs_get_op_len(objcount, fso, logs);
rc = fsfilt_reserve(obd, fso->fso_dentry->d_inode->i_sb, reserve, &h);
if (rc)
h->orh_filt_handle = obd->obd_fsops->fs_brw_start(objcount, fso,
niocount, nb,
- parent_handle, numlogs);
+ parent_handle, logs);
CDEBUG(D_HA, "started handle %p (%p)\n", h->orh_filt_handle,
parent_handle);
void *handle, int force_sync)
{
unsigned long now = jiffies;
- struct obd_reservation_handle *h = handle;
+ struct obd_handle *h = handle;
int rc;
rc = obd->obd_fsops->fs_commit(inode, h->orh_filt_handle, force_sync);
if (time_after(jiffies, now + 15 * HZ))
CERROR("long journal start time %lus\n", (jiffies - now) / HZ);
- spin_lock(&obd->obd_osfs_lock);
- obd->obd_reserve_space -= h->orh_reserve;
- LASSERT(obd->obd_reserve_space >= 0);
- spin_unlock(&obd->obd_osfs_lock);
- OBD_FREE(h, sizeof(*h));
+ fsfilt_release(obd, h);
return rc;
}
static inline int fsfilt_commit_async(struct obd_device *obd,
- struct inode *inode,
- void *handle,
- void **wait_handle)
+ struct inode *inode, void *handle,
+ void **wait_handle)
{
unsigned long now = jiffies;
- struct obd_reservation_handle *h = handle;
+ struct obd_handle *h = handle;
int rc;
rc = obd->obd_fsops->fs_commit_async(inode, h->orh_filt_handle,
if (time_after(jiffies, now + 15 * HZ))
CERROR("long journal start time %lus\n", (jiffies - now) / HZ);
- spin_lock(&obd->obd_osfs_lock);
- obd->obd_reserve_space -= h->orh_reserve;
- LASSERT(obd->obd_reserve_space >= 0);
- spin_unlock(&obd->obd_osfs_lock);
- OBD_FREE(h, sizeof(*h));
+ fsfilt_release(obd, h);
return rc;
}
-static inline int fsfilt_commit_wait(struct obd_device *obd, struct inode *inode,
- void *handle)
+static inline int fsfilt_commit_wait(struct obd_device *obd,
+ struct inode *inode, void *handle)
{
unsigned long now = jiffies;
int rc = obd->obd_fsops->fs_commit_wait(inode, handle);
void *handle, struct iattr *iattr,int do_trunc)
{
unsigned long now = jiffies;
- struct obd_reservation_handle *h = handle;
+ struct obd_handle *h = handle;
int rc;
rc = obd->obd_fsops->fs_setattr(dentry, h->orh_filt_handle, iattr, do_trunc);
if (time_after(jiffies, now + 15 * HZ))
static inline int fsfilt_set_md(struct obd_device *obd, struct inode *inode,
void *handle, void *md, int size)
{
- struct obd_reservation_handle *h = handle;
+ struct obd_handle *h = handle;
return obd->obd_fsops->fs_set_md(inode, h->orh_filt_handle, md, size);
}
void *handle, fsfilt_cb_t cb_func,
void *cb_data)
{
- struct obd_reservation_handle *h = handle;
+ struct obd_handle *h = handle;
return obd->obd_fsops->fs_add_journal_cb(obd, last_rcvd,
h->orh_filt_handle, cb_func,
cb_data);
int logs)
{
/* For updates to the last recieved file */
- int nblocks = EXT3_DATA_TRANS_BLOCKS;
+ int nblocks = EXT3_SINGLEDATA_TRANS_BLOCKS;
+ journal_t *journal;
void *handle;
if (current->journal_info) {
switch(op) {
case FSFILT_OP_RMDIR:
case FSFILT_OP_UNLINK:
+ /* delete one file + create/update logs for each stripe */
nblocks += EXT3_DELETE_TRANS_BLOCKS;
nblocks += (EXT3_INDEX_EXTRA_TRANS_BLOCKS +
- EXT3_DATA_TRANS_BLOCKS) * logs;
+ EXT3_SINGLEDATA_TRANS_BLOCKS) * logs;
break;
case FSFILT_OP_RENAME:
/* modify additional directory */
- nblocks += EXT3_DATA_TRANS_BLOCKS;
+ nblocks += EXT3_SINGLEDATA_TRANS_BLOCKS;
/* no break */
case FSFILT_OP_SYMLINK:
/* additional block + block bitmap + GDT for long symlink */
nblocks += 3;
/* no break */
case FSFILT_OP_CREATE:
+ /* create/update logs for each stripe */
nblocks += (EXT3_INDEX_EXTRA_TRANS_BLOCKS +
- EXT3_DATA_TRANS_BLOCKS) * logs;
+ EXT3_SINGLEDATA_TRANS_BLOCKS) * logs;
+ /* no break */
case FSFILT_OP_MKDIR:
case FSFILT_OP_MKNOD:
/* modify one inode + block bitmap + GDT */
/* no break */
case FSFILT_OP_LINK:
/* modify parent directory */
- nblocks += EXT3_INDEX_EXTRA_TRANS_BLOCKS+EXT3_DATA_TRANS_BLOCKS;
+ nblocks += EXT3_INDEX_EXTRA_TRANS_BLOCKS +
+ EXT3_DATA_TRANS_BLOCKS;
break;
case FSFILT_OP_SETATTR:
/* Setattr on inode */
}
LASSERT(current->journal_info == desc_private);
+ journal = EXT3_SB(inode->i_sb)->s_journal;
+ if (nblocks > journal->j_max_transaction_buffers) {
+ CERROR("too many credits %d for op %ux%u using %d instead\n",
+ nblocks, op, logs, journal->j_max_transaction_buffers);
+ nblocks = journal->j_max_transaction_buffers;
+ }
journal_start:
lock_kernel();
if (!IS_ERR(handle))
LASSERT(current->journal_info == handle);
+ else
+ CERROR("error starting handle for op %u (%u credits): rc %ld\n",
+ op, nblocks, PTR_ERR(handle));
return handle;
}
case FSFILT_OP_UNLINK:
return 3 * logs;
}
-
} else {
int i;
int needed = 0;