diff --git a/lustre/ChangeLog b/lustre/ChangeLog index c9dd44859d178d660a61e8fc090023bdf1dd7ce9..8b3c3dd507404e427d8987966649d2ac29bac41e 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -18,6 +18,14 @@ tbd Sun Microsystems, Inc. * RHEL 4 and RHEL 5/SLES 10 clients behaves differently on 'cd' to a removed cwd "./" (refer to Bugzilla 14399). +Severity : normal +Bugzilla : 14533 +Frequency : rare, on recovery +Description: read procfs can produce deadlock in some situation +Details : Holding lprocfs lock with send rpc can produce block for destroy + obd objects and this also block reconnect with -EALREADY. This isn't + fix all lprocfs bugs - but make it rare. + Severity : enhancement Bugzilla : 15152 Description: Update kernel to RHEL5 2.6.18-53.1.14.el5. diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index eb9264b3e4374d08b0ca1387c6a793a4ef5de06b..8caf3cd601d2bc5f9fb41ce81f12f48e776dc9b9 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -591,6 +591,8 @@ struct obd_statfs { }; extern void lustre_swab_obd_statfs (struct obd_statfs *os); +#define OBD_STATFS_NODELAY 0x0001 /* requests should be send without delay + * and resends for avoid deadlocks */ /* ost_body.data values for OST_BRW */ diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 297d8dbfe652d4d179f64e7b14e6af3497386e48..5b55e25db9f30bd86c8027acbdb83fcb31cb5d41 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -139,8 +139,11 @@ struct obd_info { * OSC. (e.g. lov_prep_enqueue_set initialises extent of the policy, * and osc_enqueue passes it into ldlm_lock_match & ldlm_cli_enqueue. */ ldlm_policy_data_t oi_policy; - /* Flags used while lock handling. The flags obtained on the enqueue - * request are set here, therefore they are request specific. */ + /* Flags used for set request specific flags: + - while lock handling, the flags obtained on the enqueue + request are set here. + - while stats, the flags used for control delay/resend. + */ int oi_flags; /* Lock handle specific for every OSC lock. */ struct lustre_handle *oi_lockh; @@ -915,7 +918,7 @@ struct obd_ops { int (*o_disconnect)(struct obd_export *exp); int (*o_statfs)(struct obd_device *obd, struct obd_statfs *osfs, - __u64 max_age); + __u64 max_age, __u32 flags); int (*o_statfs_async)(struct obd_device *obd, struct obd_info *oinfo, __u64 max_age, struct ptlrpc_request_set *set); int (*o_packmd)(struct obd_export *exp, struct lov_mds_md **disk_tgt, diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index a6bdb9c8fe8bd345533025b5aa5bf0ef2f8fe45f..e2a99e71665a61ef8735d66fd4e0dad194c697e2 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -781,7 +781,8 @@ static inline int obd_statfs_async(struct obd_device *obd, } static inline int obd_statfs_rqset(struct obd_device *obd, - struct obd_statfs *osfs, __u64 max_age) + struct obd_statfs *osfs, __u64 max_age, + __u32 flags) { struct ptlrpc_request_set *set = NULL; struct obd_info oinfo = { { { 0 } } }; @@ -793,6 +794,7 @@ static inline int obd_statfs_rqset(struct obd_device *obd, RETURN(-ENOMEM); oinfo.oi_osfs = osfs; + oinfo.oi_flags = flags; rc = obd_statfs_async(obd, &oinfo, max_age, set); if (rc == 0) rc = ptlrpc_set_wait(set); @@ -804,7 +806,7 @@ static inline int obd_statfs_rqset(struct obd_device *obd, * If the cache is older than @max_age we will get a new value from the * target. Use a value of "cfs_time_current() + HZ" to guarantee freshness. */ static inline int obd_statfs(struct obd_device *obd, struct obd_statfs *osfs, - __u64 max_age) + __u64 max_age, __u32 flags) { int rc = 0; ENTRY; @@ -818,7 +820,7 @@ static inline int obd_statfs(struct obd_device *obd, struct obd_statfs *osfs, CDEBUG(D_SUPER, "osfs "LPU64", max_age "LPU64"\n", obd->obd_osfs_age, max_age); if (cfs_time_before_64(obd->obd_osfs_age, max_age)) { - rc = OBP(obd, statfs)(obd, osfs, max_age); + rc = OBP(obd, statfs)(obd, osfs, max_age, flags); if (rc == 0) { spin_lock(&obd->obd_osfs_lock); memcpy(&obd->obd_osfs, osfs, sizeof(obd->obd_osfs)); diff --git a/lustre/liblustre/super.c b/lustre/liblustre/super.c index e3bb0ffe8b319fabad642cb50c1a7cf61de00c11..cd79894bbcb91746fc33c7842597cf7558a019ae 100644 --- a/lustre/liblustre/super.c +++ b/lustre/liblustre/super.c @@ -1104,7 +1104,7 @@ static int llu_statfs_internal(struct llu_sb_info *sbi, int rc; ENTRY; - rc = obd_statfs(class_exp2obd(sbi->ll_mdc_exp), osfs, max_age); + rc = obd_statfs(class_exp2obd(sbi->ll_mdc_exp), osfs, max_age, 0); if (rc) { CERROR("mdc_statfs fails: rc = %d\n", rc); RETURN(rc); @@ -1114,7 +1114,7 @@ static int llu_statfs_internal(struct llu_sb_info *sbi, osfs->os_bavail, osfs->os_blocks, osfs->os_ffree,osfs->os_files); rc = obd_statfs_rqset(class_exp2obd(sbi->ll_osc_exp), - &obd_osfs, max_age); + &obd_osfs, max_age, 0); if (rc) { CERROR("obd_statfs fails: rc = %d\n", rc); RETURN(rc); @@ -1953,7 +1953,7 @@ llu_fsswop_mount(const char *source, } sbi->ll_mdc_exp = class_conn2export(&mdc_conn); - err = obd_statfs(obd, &osfs, 100000000); + err = obd_statfs(obd, &osfs, 100000000, 0); if (err) GOTO(out_mdc, err); diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index b735d105b1144652a0a7a3309eb736c108dd9ad7..be76c003f40ac47aa90a9f3efb4da39f7af4664d 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -641,7 +641,7 @@ int ll_statfs(struct super_block *sb, struct kstatfs *sfs); int ll_statfs(struct dentry *de, struct kstatfs *sfs); #endif int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs, - __u64 max_age); + __u64 max_age, __u32 flags); void ll_update_inode(struct inode *inode, struct lustre_md *md); void ll_read_inode2(struct inode *inode, void *opaque); int ll_iocontrol(struct inode *inode, struct file *file, diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 988529a1e716544b78ce1036cd56d1237f07f6b2..3d97ad7d3cca12d3be7502f4a6d6f0439bcbfb2d 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -210,7 +210,7 @@ static int client_common_fill_super(struct super_block *sb, } sbi->ll_mdc_exp = class_conn2export(&mdc_conn); - err = obd_statfs(obd, &osfs, cfs_time_current_64() - HZ); + err = obd_statfs(obd, &osfs, cfs_time_current_64() - HZ, 0); if (err) GOTO(out_mdc, err); @@ -1539,14 +1539,14 @@ int ll_setattr(struct dentry *de, struct iattr *attr) } int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs, - __u64 max_age) + __u64 max_age, __u32 flags) { struct ll_sb_info *sbi = ll_s2sbi(sb); struct obd_statfs obd_osfs; int rc; ENTRY; - rc = obd_statfs(class_exp2obd(sbi->ll_mdc_exp), osfs, max_age); + rc = obd_statfs(class_exp2obd(sbi->ll_mdc_exp), osfs, max_age, flags); if (rc) { CERROR("mdc_statfs fails: rc = %d\n", rc); RETURN(rc); @@ -1558,7 +1558,7 @@ int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs, osfs->os_bavail, osfs->os_blocks, osfs->os_ffree,osfs->os_files); rc = obd_statfs_rqset(class_exp2obd(sbi->ll_osc_exp), - &obd_osfs, max_age); + &obd_osfs, max_age, flags); if (rc) { CERROR("obd_statfs fails: rc = %d\n", rc); RETURN(rc); @@ -1602,7 +1602,7 @@ int ll_statfs(struct dentry *de, struct kstatfs *sfs) /* For now we will always get up-to-date statfs values, but in the * future we may allow some amount of caching on the client (e.g. * from QOS or lprocfs updates). */ - rc = ll_statfs_internal(sb, &osfs, cfs_time_current_64() - 1); + rc = ll_statfs_internal(sb, &osfs, cfs_time_current_64() - 1, 0); if (rc) return rc; @@ -2143,7 +2143,7 @@ int ll_obd_statfs(struct inode *inode, void *arg) if (!client_obd) GOTO(out_statfs, rc = -EINVAL); - rc = obd_statfs(client_obd, &stat_buf, cfs_time_current_64() - 1); + rc = obd_statfs(client_obd, &stat_buf, cfs_time_current_64() - HZ, 1); if (rc) GOTO(out_statfs, rc); diff --git a/lustre/llite/lproc_llite.c b/lustre/llite/lproc_llite.c index 4e48ebcde8feb9ca867d3f3e0e8afb3cd70f5d63..a50453e7683f60cfd426fc1a81899bb3e49da74d 100644 --- a/lustre/llite/lproc_llite.c +++ b/lustre/llite/lproc_llite.c @@ -47,7 +47,8 @@ static int ll_rd_blksize(char *page, char **start, off_t off, int count, int rc; LASSERT(sb != NULL); - rc = ll_statfs_internal(sb, &osfs, cfs_time_current_64() - HZ); + rc = ll_statfs_internal(sb, &osfs, cfs_time_current_64() - HZ, + OBD_STATFS_NODELAY); if (!rc) { *eof = 1; rc = snprintf(page, count, "%u\n", osfs.os_bsize); @@ -64,7 +65,8 @@ static int ll_rd_kbytestotal(char *page, char **start, off_t off, int count, int rc; LASSERT(sb != NULL); - rc = ll_statfs_internal(sb, &osfs, cfs_time_current_64() - HZ); + rc = ll_statfs_internal(sb, &osfs, cfs_time_current_64() - HZ, + OBD_STATFS_NODELAY); if (!rc) { __u32 blk_size = osfs.os_bsize >> 10; __u64 result = osfs.os_blocks; @@ -87,7 +89,8 @@ static int ll_rd_kbytesfree(char *page, char **start, off_t off, int count, int rc; LASSERT(sb != NULL); - rc = ll_statfs_internal(sb, &osfs, cfs_time_current_64() - HZ); + rc = ll_statfs_internal(sb, &osfs, cfs_time_current_64() - HZ, + OBD_STATFS_NODELAY); if (!rc) { __u32 blk_size = osfs.os_bsize >> 10; __u64 result = osfs.os_bfree; @@ -109,7 +112,8 @@ static int ll_rd_kbytesavail(char *page, char **start, off_t off, int count, int rc; LASSERT(sb != NULL); - rc = ll_statfs_internal(sb, &osfs, cfs_time_current_64() - HZ); + rc = ll_statfs_internal(sb, &osfs, cfs_time_current_64() - HZ, + OBD_STATFS_NODELAY); if (!rc) { __u32 blk_size = osfs.os_bsize >> 10; __u64 result = osfs.os_bavail; @@ -131,7 +135,8 @@ static int ll_rd_filestotal(char *page, char **start, off_t off, int count, int rc; LASSERT(sb != NULL); - rc = ll_statfs_internal(sb, &osfs, cfs_time_current_64() - HZ); + rc = ll_statfs_internal(sb, &osfs, cfs_time_current_64() - HZ, + OBD_STATFS_NODELAY); if (!rc) { *eof = 1; rc = snprintf(page, count, LPU64"\n", osfs.os_files); @@ -147,7 +152,8 @@ static int ll_rd_filesfree(char *page, char **start, off_t off, int count, int rc; LASSERT(sb != NULL); - rc = ll_statfs_internal(sb, &osfs, cfs_time_current_64() - HZ); + rc = ll_statfs_internal(sb, &osfs, cfs_time_current_64() - HZ, + OBD_STATFS_NODELAY); if (!rc) { *eof = 1; rc = snprintf(page, count, LPU64"\n", osfs.os_ffree); diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index 50a9723e13612a34665f84ada7ba0465f0b95bc7..8885f8f6fc028b240c81c08ec38e5fd4e20f0f2b 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -1140,7 +1140,7 @@ static int lov_create(struct obd_export *exp, struct obdo *src_oa, } maxage = cfs_time_shift_64(-lov->desc.ld_qos_maxage); - obd_statfs_rqset(exp->exp_obd, &osfs, maxage); + obd_statfs_rqset(exp->exp_obd, &osfs, maxage, 0); rc = lov_prep_create_set(exp, &oinfo, ea, src_oa, oti, &set); if (rc) @@ -2308,38 +2308,27 @@ static int lov_statfs_async(struct obd_device *obd, struct obd_info *oinfo, } static int lov_statfs(struct obd_device *obd, struct obd_statfs *osfs, - __u64 max_age) + __u64 max_age, __u32 flags) { - struct lov_obd *lov = &obd->u.lov; - struct obd_statfs lov_sfs; - int set = 0; - int rc = 0, err; - int i; + struct ptlrpc_request_set *set = NULL; + struct obd_info oinfo = { { { 0 } } }; + int rc = 0; ENTRY; - /* We only get block data from the OBD */ - for (i = 0; i < lov->desc.ld_tgt_count; i++) { - if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active) { - CDEBUG(D_HA, "lov idx %d inactive\n", i); - continue; - } - - err = obd_statfs(class_exp2obd(lov->lov_tgts[i]->ltd_exp), - &lov_sfs, max_age); - if (err) { - if (lov->lov_tgts[i]->ltd_active && !rc) - rc = err; - continue; - } - lov_update_statfs(class_exp2obd(lov->lov_tgts[i]->ltd_exp), - osfs, &lov_sfs, set); - set++; - } + /* for obdclass we forbid using obd_statfs_rqset, but prefer using async + * statfs requests */ + set = ptlrpc_prep_set(); + if (set == NULL) + RETURN(-ENOMEM); - err = lov_fini_statfs(obd, osfs, set); - qos_update(lov); + oinfo.oi_osfs = osfs; + oinfo.oi_flags = flags; + rc = lov_statfs_async(obd, &oinfo, max_age, set); + if (rc == 0) + rc = ptlrpc_set_wait(set); + ptlrpc_set_destroy(set); - RETURN(rc ? rc : err); + RETURN(rc); } static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len, diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index bf1910f1be50a01f587f743e87ee108daf8e0b39..0d40904db96b54502a92918d9aaed741edf46f68 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -978,7 +978,7 @@ int mdc_get_info(struct obd_export *exp, __u32 keylen, void *key, } static int mdc_statfs(struct obd_device *obd, struct obd_statfs *osfs, - __u64 max_age) + __u64 max_age, __u32 flags) { struct ptlrpc_request *req; struct obd_statfs *msfs; @@ -998,6 +998,12 @@ static int mdc_statfs(struct obd_device *obd, struct obd_statfs *osfs, ptlrpc_req_set_repsize(req, 2, size); + if (flags & OBD_STATFS_NODELAY) { + /* procfs requests not want stay in wait for avoid deadlock */ + req->rq_no_resend = 1; + req->rq_no_delay = 1; + } + rc = ptlrpc_queue_wait(req); if (rc) diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 3761c95ea68973d4123d9a39c7aafd7f9729148b..7f4d30be8824b6cc18116ab4f3271b1bec860b7a 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -1102,7 +1102,7 @@ out_ucred: } static int mds_obd_statfs(struct obd_device *obd, struct obd_statfs *osfs, - __u64 max_age) + __u64 max_age, __u32 flags) { int rc; @@ -1138,7 +1138,7 @@ static int mds_statfs(struct ptlrpc_request *req) /* We call this so that we can cache a bit - 1 jiffie worth */ rc = mds_obd_statfs(obd, lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, size[REPLY_REC_OFF]), - cfs_time_current_64() - HZ); + cfs_time_current_64() - HZ, 0); if (rc) { CERROR("mds_obd_statfs failed: rc %d\n", rc); GOTO(out, rc); diff --git a/lustre/mds/lproc_mds.c b/lustre/mds/lproc_mds.c index 90468149191b8327f840e33f38757524b515347a..ba1562f43cc7dba8b2f62a7cf38fced1d23c25f7 100644 --- a/lustre/mds/lproc_mds.c +++ b/lustre/mds/lproc_mds.c @@ -106,13 +106,15 @@ static int lprocfs_mds_wr_evict_client(struct file *file, const char *buffer, obd_export_evict_by_nid(obd, tmpbuf+4); - LPROCFS_ENTRY(); - class_decref(obd); rc = ptlrpc_set_wait(set); if (rc) CERROR("Failed to evict nid %s from OSTs: rc %d\n", tmpbuf + 4, rc); + + LPROCFS_ENTRY(); + class_decref(obd); + ptlrpc_set_destroy(set); return count; } diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index 7f3cea3232d8627e7f7092a495bb63ebdd8cb6db..11ad764c84def7a603dd475bb625406f8f9d155d 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -59,13 +59,17 @@ struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head, if (head == NULL) return NULL; + LPROCFS_ENTRY(); temp = head->subdir; while (temp != NULL) { - if (strcmp(temp->name, name) == 0) + if (strcmp(temp->name, name) == 0) { + LPROCFS_EXIT(); return temp; + } temp = temp->next; } + LPROCFS_ENTRY(); return NULL; } @@ -200,6 +204,7 @@ int lprocfs_evict_client_release(struct inode *inode, struct file *f) atomic_dec(&obd->obd_evict_inprogress); wake_up(&obd->obd_evict_inprogress_waitq); + LPROCFS_EXIT(); return 0; } @@ -294,6 +299,7 @@ void lprocfs_remove(struct proc_dir_entry **rooth) parent = root->parent; LASSERT(parent != NULL); + LPROCFS_ENTRY(); /* search vs remove race */ while (1) { while (temp->subdir != NULL) @@ -310,13 +316,12 @@ void lprocfs_remove(struct proc_dir_entry **rooth) /* Now, the rm_entry->deleted flags is protected * by _lprocfs_lock. */ - down_write(&_lprocfs_lock); rm_entry->data = NULL; remove_proc_entry(rm_entry->name, temp); - up_write(&_lprocfs_lock); if (temp == parent) break; } + LPROCFS_EXIT(); } struct proc_dir_entry *lprocfs_register(const char *name, @@ -441,7 +446,8 @@ int lprocfs_rd_blksize(char *page, char **start, off_t off, int count, int *eof, void *data) { struct obd_statfs osfs; - int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ); + int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ, + OBD_STATFS_NODELAY); if (!rc) { *eof = 1; rc = snprintf(page, count, "%u\n", osfs.os_bsize); @@ -453,7 +459,8 @@ int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count, int *eof, void *data) { struct obd_statfs osfs; - int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ); + int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ, + OBD_STATFS_NODELAY); if (!rc) { __u32 blk_size = osfs.os_bsize >> 10; __u64 result = osfs.os_blocks; @@ -471,7 +478,8 @@ int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count, int *eof, void *data) { struct obd_statfs osfs; - int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ); + int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ, + OBD_STATFS_NODELAY); if (!rc) { __u32 blk_size = osfs.os_bsize >> 10; __u64 result = osfs.os_bfree; @@ -489,7 +497,8 @@ int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count, int *eof, void *data) { struct obd_statfs osfs; - int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ); + int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ, + OBD_STATFS_NODELAY); if (!rc) { __u32 blk_size = osfs.os_bsize >> 10; __u64 result = osfs.os_bavail; @@ -507,7 +516,8 @@ int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count, int *eof, void *data) { struct obd_statfs osfs; - int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ); + int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ, + OBD_STATFS_NODELAY); if (!rc) { *eof = 1; rc = snprintf(page, count, LPU64"\n", osfs.os_files); @@ -520,7 +530,8 @@ int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count, int *eof, void *data) { struct obd_statfs osfs; - int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ); + int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ, + OBD_STATFS_NODELAY); if (!rc) { *eof = 1; rc = snprintf(page, count, LPU64"\n", osfs.os_ffree); diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index 750069804b30aa103c6db3e7e0e4e8b2da0d3439..733b73ed38368f887016a8a1019cae542e05403c 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -2871,7 +2871,7 @@ out: } static int filter_statfs(struct obd_device *obd, struct obd_statfs *osfs, - __u64 max_age) + __u64 max_age, __u32 flags) { struct filter_obd *filter = &obd->u.filter; int blockbits = obd->u.obt.obt_sb->s_blocksize_bits; @@ -2968,7 +2968,7 @@ static int filter_precreate(struct obd_device *obd, struct obdo *oa, OBD_ALLOC(osfs, sizeof(*osfs)); if (osfs == NULL) RETURN(-ENOMEM); - rc = filter_statfs(obd, osfs, cfs_time_current_64() - HZ); + rc = filter_statfs(obd, osfs, cfs_time_current_64() - HZ, 0); if (rc == 0 && osfs->os_bavail < (osfs->os_blocks >> 10)) { CDEBUG(D_RPCTRACE,"%s: not enough space for create " LPU64"\n", obd->obd_name, osfs->os_bavail << diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 48da88286f8f4ea316f4b394c3762ddd98c9f3b7..eccf227c801fb0b20e2b55826026db0b10646632 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -3191,6 +3191,11 @@ static int osc_statfs_async(struct obd_device *obd, struct obd_info *oinfo, ptlrpc_req_set_repsize(req, 2, size); req->rq_request_portal = OST_CREATE_PORTAL; ptlrpc_at_set_req_timeout(req); + if (oinfo->oi_flags & OBD_STATFS_NODELAY) { + /* procfs requests not want stat in wait for avoid deadlock */ + req->rq_no_resend = 1; + req->rq_no_delay = 1; + } req->rq_interpret_reply = osc_statfs_interpret; CLASSERT(sizeof(*aa) <= sizeof(req->rq_async_args)); @@ -3202,7 +3207,7 @@ static int osc_statfs_async(struct obd_device *obd, struct obd_info *oinfo, } static int osc_statfs(struct obd_device *obd, struct obd_statfs *osfs, - __u64 max_age) + __u64 max_age, __u32 flags) { struct obd_statfs *msfs; struct ptlrpc_request *req; @@ -3224,6 +3229,12 @@ static int osc_statfs(struct obd_device *obd, struct obd_statfs *osfs, req->rq_request_portal = OST_CREATE_PORTAL; ptlrpc_at_set_req_timeout(req); + if (flags & OBD_STATFS_NODELAY) { + /* procfs requests not want stat in wait for avoid deadlock */ + req->rq_no_resend = 1; + req->rq_no_delay = 1; + } + rc = ptlrpc_queue_wait(req); if (rc) GOTO(out, rc); diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c index 8a6ccfbc4c4da42f1b3703fd28fa1480d54f0bc6..a032b829f81b74613485984d65edd1c600743af1 100644 --- a/lustre/ost/ost_handler.c +++ b/lustre/ost/ost_handler.c @@ -159,7 +159,7 @@ static int ost_statfs(struct ptlrpc_request *req) osfs = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*osfs)); req->rq_status = obd_statfs(req->rq_export->exp_obd, osfs, - cfs_time_current_64() - HZ); + cfs_time_current_64() - HZ, 0); if (OBD_FAIL_CHECK_ONCE(OBD_FAIL_OST_ENOSPC)) osfs->os_bfree = osfs->os_bavail = 64; if (req->rq_status != 0) diff --git a/lustre/ptlrpc/lproc_ptlrpc.c b/lustre/ptlrpc/lproc_ptlrpc.c index b9371956a49a13d97b0c86000743fa8d8db755da..8a2c3756a2242fbe55ca89406708616ee8e1c969 100644 --- a/lustre/ptlrpc/lproc_ptlrpc.c +++ b/lustre/ptlrpc/lproc_ptlrpc.c @@ -620,6 +620,7 @@ int lprocfs_wr_ping(struct file *file, const char *buffer, ptlrpc_req_set_repsize(req, 1, NULL); req->rq_send_state = LUSTRE_IMP_FULL; req->rq_no_resend = 1; + req->rq_no_delay = 1; rc = ptlrpc_queue_wait(req);