#include "filter_internal.h"
+/*
+ * FIXME
+ * keep this as simple as possible. we suppose the blacklist usually
+ * be empry or very short (<5), since long term blacklist should be
+ * done on MDS side. A more sophisticated blacklist will be implemented
+ * later.
+ *
+ * note blacklist didn't take effect when OSS capability disabled. this
+ * looks reasonable to me.
+ */
+#define BLACKLIST_MAX (32)
+static int nblacklist = 0;
+static uid_t blacklist[BLACKLIST_MAX];
+static spinlock_t blacklist_lock = SPIN_LOCK_UNLOCKED;
+
+int blacklist_display(char *buf, int bufsize)
+{
+ char one[16];
+ int i;
+ LASSERT(buf);
+
+ buf[0] = '\0';
+ spin_lock(&blacklist_lock);
+ for (i = 0; i < nblacklist; i++) {
+ snprintf(one, 16, "%u\n", blacklist[i]);
+ strncat(buf, one, bufsize);
+ }
+ spin_unlock(&blacklist_lock);
+ return strnlen(buf, bufsize);
+}
+
+void blacklist_add(uid_t uid)
+{
+ int i;
+
+ spin_lock(&blacklist_lock);
+ if (nblacklist == BLACKLIST_MAX) {
+ CERROR("can't add more in blacklist\n");
+ spin_unlock(&blacklist_lock);
+ return;
+ }
+
+ for (i = 0; i < nblacklist; i++) {
+ if (blacklist[i] == uid) {
+ spin_unlock(&blacklist_lock);
+ return;
+ }
+ }
+
+ blacklist[nblacklist++] = uid;
+ spin_unlock(&blacklist_lock);
+}
+
+void blacklist_del(uid_t uid)
+{
+ int i;
+
+ spin_lock(&blacklist_lock);
+ for (i = 0; i < nblacklist; i++) {
+ if (blacklist[i] == uid) {
+ nblacklist--;
+ while (i < nblacklist) {
+ blacklist[i] = blacklist[i+1];
+ i++;
+ }
+ spin_unlock(&blacklist_lock);
+ return;
+ }
+ }
+ spin_unlock(&blacklist_lock);
+}
+
+int blacklist_check(uid_t uid)
+{
+ int i, rc = 0;
+
+ spin_lock(&blacklist_lock);
+ for (i = 0; i < nblacklist; i++) {
+ if (blacklist[i] == uid) {
+ rc = 1;
+ break;
+ }
+ }
+ spin_unlock(&blacklist_lock);
+ return rc;
+}
+
+
void filter_free_capa_keys(struct filter_obd *filter)
{
struct filter_capa_key *key, *n;
if (capa == NULL)
RETURN(-EACCES);
+ if (blacklist_check(capa->lc_uid))
+ RETURN(-EACCES);
+
if (cmd == OBD_BRW_WRITE && capa->lc_op != MAY_WRITE)
RETURN(-EACCES);
if (cmd == OBD_BRW_READ && !(capa->lc_op & (MAY_WRITE | MAY_READ)))
return count;
}
+static
+int lprocfs_filter_rd_blacklist(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ int rc;
+
+ rc = blacklist_display(page, count);
+ *eof = 1;
+ return rc;
+}
+
+static
+int lprocfs_filter_wr_blacklist(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ int add;
+ uid_t uid = -1;
+
+ if (count < 2)
+ return count;
+ if (buffer[0] == '+')
+ add = 1;
+ else if (buffer[0] == '-')
+ add = 0;
+ else
+ return count;
+
+ sscanf(buffer + 1, "%u", &uid);
+ if (add)
+ blacklist_add(uid);
+ else
+ blacklist_del(uid);
+ return count;
+}
+
static struct lprocfs_vars lprocfs_obd_vars[] = {
{ "uuid", lprocfs_rd_uuid, 0, 0 },
{ "blocksize", lprocfs_rd_blksize, 0, 0 },
{ "recovery_status", lprocfs_obd_rd_recovery_status, 0, 0 },
{ "capa", lprocfs_filter_rd_capa_stat,
lprocfs_filter_wr_capa_stat, 0 },
+ { "blacklist", lprocfs_filter_rd_blacklist,
+ lprocfs_filter_wr_blacklist, 0 },
{ 0 }
};