X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fofd%2Flproc_ofd.c;h=359b37365f1528889d484c678737abf2c789614f;hb=a66e12d6ede2afda3bb7a5b1f22b8c17c1176584;hp=435449785ef86825de1711861640d5d213cc6d3d;hpb=9761d5c52aeef31a8c3112c3fb3ec9e24b37c800;p=fs%2Flustre-release.git diff --git a/lustre/ofd/lproc_ofd.c b/lustre/ofd/lproc_ofd.c index 4354497..359b373 100644 --- a/lustre/ofd/lproc_ofd.c +++ b/lustre/ofd/lproc_ofd.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "ofd_internal.h" @@ -116,7 +117,8 @@ static int lprocfs_ofd_rd_grant_ratio(char *page, char **start, off_t off, (int) ofd_grant_reserved(ofd, 100)); } -static int lprocfs_ofd_wr_grant_ratio(struct file *file, const char *buffer, +static int lprocfs_ofd_wr_grant_ratio(struct file *file, + const char __user *buffer, unsigned long count, void *data) { struct obd_device *obd = (struct obd_device *)data; @@ -156,7 +158,8 @@ static int lprocfs_ofd_rd_precreate_batch(char *page, char **start, off_t off, return snprintf(page, count, "%d\n", ofd->ofd_precreate_batch); } -static int lprocfs_ofd_wr_precreate_batch(struct file *file, const char *buffer, +static int lprocfs_ofd_wr_precreate_batch(struct file *file, + const char __user *buffer, unsigned long count, void *data) { struct obd_device *obd = (struct obd_device *)data; @@ -223,7 +226,7 @@ int lprocfs_ofd_rd_fmd_max_num(char *page, char **start, off_t off, return rc; } -int lprocfs_ofd_wr_fmd_max_num(struct file *file, const char *buffer, +int lprocfs_ofd_wr_fmd_max_num(struct file *file, const char __user *buffer, unsigned long count, void *data) { struct obd_device *obd = data; @@ -253,7 +256,7 @@ int lprocfs_ofd_rd_fmd_max_age(char *page, char **start, off_t off, return rc; } -int lprocfs_ofd_wr_fmd_max_age(struct file *file, const char *buffer, +int lprocfs_ofd_wr_fmd_max_age(struct file *file, const char __user *buffer, unsigned long count, void *data) { struct obd_device *obd = data; @@ -283,7 +286,7 @@ static int lprocfs_ofd_rd_capa(char *page, char **start, off_t off, return rc; } -static int lprocfs_ofd_wr_capa(struct file *file, const char *buffer, +static int lprocfs_ofd_wr_capa(struct file *file, const char __user *buffer, unsigned long count, void *data) { struct obd_device *obd = data; @@ -323,7 +326,7 @@ int lprocfs_ofd_rd_degraded(char *page, char **start, off_t off, return snprintf(page, count, "%u\n", ofd->ofd_raid_degraded); } -int lprocfs_ofd_wr_degraded(struct file *file, const char *buffer, +int lprocfs_ofd_wr_degraded(struct file *file, const char __user *buffer, unsigned long count, void *data) { struct obd_device *obd = data; @@ -365,7 +368,7 @@ int lprocfs_ofd_rd_syncjournal(char *page, char **start, off_t off, return rc; } -int lprocfs_ofd_wr_syncjournal(struct file *file, const char *buffer, +int lprocfs_ofd_wr_syncjournal(struct file *file, const char __user *buffer, unsigned long count, void *data) { struct obd_device *obd = data; @@ -388,6 +391,8 @@ int lprocfs_ofd_wr_syncjournal(struct file *file, const char *buffer, return count; } +/* This must be longer than the longest string below */ +#define SYNC_STATES_MAXLEN 16 static char *sync_on_cancel_states[] = {"never", "blocking", "always" }; @@ -404,24 +409,39 @@ int lprocfs_ofd_rd_sync_lock_cancel(char *page, char **start, off_t off, return rc; } -int lprocfs_ofd_wr_sync_lock_cancel(struct file *file, const char *buffer, +int lprocfs_ofd_wr_sync_lock_cancel(struct file *file, + const char __user *buffer, unsigned long count, void *data) { struct obd_device *obd = data; struct lu_target *tgt = obd->u.obt.obt_lut; + char kernbuf[SYNC_STATES_MAXLEN]; int val = -1; int i; + if (count == 0 || count >= sizeof(kernbuf)) + return -EINVAL; + + if (copy_from_user(kernbuf, buffer, count)) + return -EFAULT; + kernbuf[count] = 0; + + if (kernbuf[count - 1] == '\n') + kernbuf[count - 1] = 0; + for (i = 0 ; i < NUM_SYNC_ON_CANCEL_STATES; i++) { - if (memcmp(buffer, sync_on_cancel_states[i], - strlen(sync_on_cancel_states[i])) == 0) { + if (strcmp(kernbuf, sync_on_cancel_states[i]) == 0) { val = i; break; } } + + /* Legacy numeric codes */ if (val == -1) { int rc; + /* Safe to use userspace buffer as lprocfs_write_helper will + * use copy from user for parsing */ rc = lprocfs_write_helper(buffer, count, &val); if (rc) return rc; @@ -447,7 +467,8 @@ int lprocfs_ofd_rd_grant_compat_disable(char *page, char **start, off_t off, return rc; } -int lprocfs_ofd_wr_grant_compat_disable(struct file *file, const char *buffer, +int lprocfs_ofd_wr_grant_compat_disable(struct file *file, + const char __user *buffer, unsigned long count, void *data) { struct obd_device *obd = data; @@ -479,7 +500,7 @@ int lprocfs_ofd_rd_soft_sync_limit(char *page, char **start, off_t off, &ofd->ofd_soft_sync_limit); } -int lprocfs_ofd_wr_soft_sync_limit(struct file *file, const char *buffer, +int lprocfs_ofd_wr_soft_sync_limit(struct file *file, const char __user *buffer, unsigned long count, void *data) { struct obd_device *obd = data; @@ -488,6 +509,79 @@ int lprocfs_ofd_wr_soft_sync_limit(struct file *file, const char *buffer, return lprocfs_wr_uint(file, buffer, count, &ofd->ofd_soft_sync_limit); } +static int lprocfs_rd_lfsck_speed_limit(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct obd_device *obd = data; + struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev); + + *eof = 1; + + return lfsck_get_speed(ofd->ofd_osd, page, count); +} + +static int lprocfs_wr_lfsck_speed_limit(struct file *file, + const char __user *buffer, + unsigned long count, void *data) +{ + struct obd_device *obd = data; + struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev); + __u32 val; + int rc; + + rc = lprocfs_write_helper(buffer, count, &val); + if (rc != 0) + return rc; + + rc = lfsck_set_speed(ofd->ofd_osd, val); + + return rc != 0 ? rc : count; +} + +static int lprocfs_rd_lfsck_layout(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct obd_device *obd = data; + struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev); + + *eof = 1; + + return lfsck_dump(ofd->ofd_osd, page, count, LT_LAYOUT); +} + +static int lprocfs_rd_lfsck_verify_pfid(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct obd_device *obd = data; + struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev); + + *eof = 1; + + return snprintf(page, count, + "switch: %s\ndetected: "LPU64"\nrepaired: "LPU64"\n", + ofd->ofd_lfsck_verify_pfid ? "on" : "off", + ofd->ofd_inconsistency_self_detected, + ofd->ofd_inconsistency_self_repaired); +} + +static int lprocfs_wr_lfsck_verify_pfid(struct file *file, + const char __user *buffer, + unsigned long count, void *data) +{ + struct obd_device *obd = data; + struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev); + __u32 val; + int rc; + + rc = lprocfs_write_helper(buffer, count, &val); + if (rc != 0) + return rc; + + ofd->ofd_lfsck_verify_pfid = !!val; + + return count; +} + static struct lprocfs_vars lprocfs_ofd_obd_vars[] = { { "uuid", lprocfs_rd_uuid, 0, 0 }, { "blocksize", lprocfs_rd_blksize, 0, 0 }, @@ -537,6 +631,11 @@ static struct lprocfs_vars lprocfs_ofd_obd_vars[] = { lprocfs_wr_job_interval, 0}, { "soft_sync_limit", lprocfs_ofd_rd_soft_sync_limit, lprocfs_ofd_wr_soft_sync_limit, 0}, + { "lfsck_speed_limit", lprocfs_rd_lfsck_speed_limit, + lprocfs_wr_lfsck_speed_limit, 0 }, + { "lfsck_layout", lprocfs_rd_lfsck_layout, 0, 0 }, + { "lfsck_verify_pfid", lprocfs_rd_lfsck_verify_pfid, + lprocfs_wr_lfsck_verify_pfid, 0 }, { 0 } };