From: "Krzysztof Błaszkowski" <kb@sysmikro.com.pl>
To: xfs@oss.sgi.com
Subject: generating uevents by xfs
Date: Tue, 28 Apr 2009 18:18:31 +0200 [thread overview]
Message-ID: <200904281818.32127.kb@sysmikro.com.pl> (raw)
[-- Attachment #1: Type: text/plain, Size: 530 bytes --]
Hello,
once upon i was asked to think about such facility for notifying userspace
when some mount point is nearly full at some level let's say e.g. 90%
(threshold should be configurable).
here is a solution designed by me and i would like to see comments on this
idea and solution.
i verified these patches with 2.6.27.19 (SuSE) but there are also patches for
2.6.28.4 and 2.6.29.2 but i haven't given a try to latest two kernels.
to use it one may need to pick right *-1- patch and the *-2 patch.
Krzysztof Blaszkowski
[-- Attachment #2: xfs-sysfs-1-26292.diff --]
[-- Type: text/x-diff, Size: 2825 bytes --]
diff --git a/xfs/Makefile b/xfs/Makefile
index c3dc491..b0a1330 100644
--- a/xfs/Makefile
+++ b/xfs/Makefile
@@ -88,7 +88,8 @@ xfs-y += xfs_alloc.o \
xfs_vnodeops.o \
xfs_rw.o \
xfs_dmops.o \
- xfs_qmops.o
+ xfs_qmops.o \
+ xfs_sysfs.o
xfs-$(CONFIG_XFS_TRACE) += xfs_btree_trace.o \
xfs_dir2_trace.o
diff --git a/xfs/linux-2.6/xfs_super.c b/xfs/linux-2.6/xfs_super.c
index 32ae502..99ac6ed 100644
--- a/xfs/linux-2.6/xfs_super.c
+++ b/xfs/linux-2.6/xfs_super.c
@@ -1082,6 +1082,9 @@ xfs_fs_put_super(
xfs_close_devices(mp);
xfs_qmops_put(mp);
xfs_dmops_put(mp);
+#ifdef CONFIG_SYSFS
+ xfs_event_release(mp);
+#endif
xfs_free_fsname(mp);
kfree(mp);
}
@@ -1509,6 +1512,9 @@ xfs_fs_fill_super(
kfree(mtpt);
+#ifdef CONFIG_SYSFS
+ xfs_event_alloc(mp);
+#endif
xfs_itrace_exit(XFS_I(sb->s_root->d_inode));
return 0;
@@ -1873,6 +1879,10 @@ init_xfs_fs(void)
error = register_filesystem(&xfs_fs_type);
if (error)
goto out_sysctl_unregister;
+
+#ifdef CONFIG_SYSFS
+ xfs_sysfs_init();
+#endif
return 0;
out_sysctl_unregister:
@@ -1906,6 +1916,9 @@ exit_xfs_fs(void)
xfs_free_trace_bufs();
xfs_destroy_zones();
ktrace_uninit();
+#ifdef CONFIG_SYSFS
+ xfs_sysfs_done();
+#endif
}
module_init(init_xfs_fs);
diff --git a/xfs/xfs_mount.c b/xfs/xfs_mount.c
index 3530025..c19fc17 100644
--- a/xfs/xfs_mount.c
+++ b/xfs/xfs_mount.c
@@ -2413,3 +2413,25 @@ balance_counter:
}
#endif
+
+
+__uint64_t xfs_icsb_get_fdblocks_lazy(xfs_mount_t *mp)
+{
+ __uint64_t fdblocks = 0;
+#ifdef HAVE_PERCPU_SB
+ xfs_icsb_cnts_t *cntp;
+ int i;
+
+ for_each_online_cpu(i) {
+ cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
+ fdblocks += cntp->icsb_fdblocks;
+ }
+
+ if (xfs_icsb_counter_disabled(mp, XFS_SBS_FDBLOCKS))
+ fdblocks = mp->m_sb.sb_fdblocks;
+#else
+ fdblocks = mp->m_sb.sb_fdblocks;
+#endif
+ return fdblocks - XFS_ALLOC_SET_ASIDE(mp);
+}
+
diff --git a/xfs/xfs_mount.h b/xfs/xfs_mount.h
index f5e9937..45ef4cb 100644
--- a/xfs/xfs_mount.h
+++ b/xfs/xfs_mount.h
@@ -329,6 +329,9 @@ typedef struct xfs_mount {
wait_queue_head_t m_wait_single_sync_task;
__int64_t m_update_flags; /* sb flags we need to update
on the next remount,rw */
+#ifdef CONFIG_SYSFS
+ void *event_onlow;
+#endif
} xfs_mount_t;
/*
@@ -528,6 +531,13 @@ extern void xfs_qmops_put(struct xfs_mount *);
extern struct xfs_dmops xfs_dmcore_xfs;
+#ifdef CONFIG_SYSFS
+extern void xfs_sysfs_init(void);
+extern void xfs_sysfs_done(void);
+extern int xfs_event_alloc(struct xfs_mount *mnt);
+extern int xfs_event_release(struct xfs_mount *mnt);
+#endif
+
#endif /* __KERNEL__ */
extern void xfs_mod_sb(struct xfs_trans *, __int64_t);
[-- Attachment #3: xfs-sysfs-1-26284.diff --]
[-- Type: text/x-diff, Size: 2802 bytes --]
diff --git a/xfs/Makefile b/xfs/Makefile
index 737c9a4..1df5f4e 100644
--- a/xfs/Makefile
+++ b/xfs/Makefile
@@ -89,7 +89,8 @@ xfs-y += xfs_alloc.o \
xfs_vnodeops.o \
xfs_rw.o \
xfs_dmops.o \
- xfs_qmops.o
+ xfs_qmops.o \
+ xfs_sysfs.o
xfs-$(CONFIG_XFS_TRACE) += xfs_dir2_trace.o
diff --git a/xfs/linux-2.6/xfs_super.c b/xfs/linux-2.6/xfs_super.c
index 37ebe36..7cc0b6b 100644
--- a/xfs/linux-2.6/xfs_super.c
+++ b/xfs/linux-2.6/xfs_super.c
@@ -1152,6 +1152,9 @@ xfs_fs_put_super(
xfs_close_devices(mp);
xfs_qmops_put(mp);
xfs_dmops_put(mp);
+#ifdef CONFIG_SYSFS
+ xfs_event_release(mp);
+#endif
xfs_free_fsname(mp);
kfree(mp);
}
@@ -1783,6 +1786,9 @@ xfs_fs_fill_super(
xfs_itrace_exit(XFS_I(sb->s_root->d_inode));
kfree(args);
+#ifdef CONFIG_SYSFS
+ xfs_event_alloc(mp);
+#endif
return 0;
out_filestream_unmount:
@@ -2142,6 +2148,10 @@ init_xfs_fs(void)
error = register_filesystem(&xfs_fs_type);
if (error)
goto out_sysctl_unregister;
+
+#ifdef CONFIG_SYSFS
+ xfs_sysfs_init();
+#endif
return 0;
out_sysctl_unregister:
@@ -2175,6 +2185,9 @@ exit_xfs_fs(void)
xfs_free_trace_bufs();
xfs_destroy_zones();
ktrace_uninit();
+#ifdef CONFIG_SYSFS
+ xfs_sysfs_done();
+#endif
}
module_init(init_xfs_fs);
diff --git a/xfs/xfs_mount.c b/xfs/xfs_mount.c
index 15f5dd2..47e8202 100644
--- a/xfs/xfs_mount.c
+++ b/xfs/xfs_mount.c
@@ -2442,3 +2442,25 @@ balance_counter:
}
#endif
+
+
+__uint64_t xfs_icsb_get_fdblocks_lazy(xfs_mount_t *mp)
+{
+ __uint64_t fdblocks = 0;
+#ifdef HAVE_PERCPU_SB
+ xfs_icsb_cnts_t *cntp;
+ int i;
+
+ for_each_online_cpu(i) {
+ cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
+ fdblocks += cntp->icsb_fdblocks;
+ }
+
+ if (xfs_icsb_counter_disabled(mp, XFS_SBS_FDBLOCKS))
+ fdblocks = mp->m_sb.sb_fdblocks;
+#else
+ fdblocks = mp->m_sb.sb_fdblocks;
+#endif
+ return fdblocks - XFS_ALLOC_SET_ASIDE(mp);
+}
+
diff --git a/xfs/xfs_mount.h b/xfs/xfs_mount.h
index f3c1024..9a98c44 100644
--- a/xfs/xfs_mount.h
+++ b/xfs/xfs_mount.h
@@ -341,6 +341,9 @@ typedef struct xfs_mount {
spinlock_t m_sync_lock; /* work item list lock */
int m_sync_seq; /* sync thread generation no. */
wait_queue_head_t m_wait_single_sync_task;
+#ifdef CONFIG_SYSFS
+ void *event_onlow;
+#endif
} xfs_mount_t;
/*
@@ -539,6 +542,13 @@ extern void xfs_qmops_put(struct xfs_mou
extern struct xfs_dmops xfs_dmcore_xfs;
+#ifdef CONFIG_SYSFS
+extern void xfs_sysfs_init(void);
+extern void xfs_sysfs_done(void);
+extern int xfs_event_alloc(struct xfs_mount *mnt);
+extern int xfs_event_release(struct xfs_mount *mnt);
+#endif
+
#endif /* __KERNEL__ */
#endif /* __XFS_MOUNT_H__ */
[-- Attachment #4: xfs-sysfs-1-262719.diff --]
[-- Type: text/x-diff, Size: 2794 bytes --]
diff --git a/xfs/Makefile b/xfs/Makefile
index ba17121..904372b 100644
--- a/xfs/Makefile
+++ b/xfs/Makefile
@@ -91,7 +91,8 @@ xfs-y += xfs_alloc.o \
xfs_vnodeops.o \
xfs_rw.o \
xfs_dmops.o \
- xfs_qmops.o
+ xfs_qmops.o \
+ xfs_sysfs.o
xfs-$(CONFIG_XFS_TRACE) += xfs_dir2_trace.o
diff --git a/xfs/linux-2.6/xfs_super.c b/xfs/linux-2.6/xfs_super.c
index 9eaddb4..57f2558 100644
--- a/xfs/linux-2.6/xfs_super.c
+++ b/xfs/linux-2.6/xfs_super.c
@@ -1152,6 +1152,9 @@ xfs_fs_put_super(
xfs_close_devices(mp);
xfs_qmops_put(mp);
xfs_dmops_put(mp);
+#ifdef CONFIG_SYSFS
+ xfs_event_release(mp);
+#endif
xfs_free_fsname(mp);
kfree(mp);
}
@@ -1783,6 +1786,9 @@ xfs_fs_fill_super(
xfs_itrace_exit(XFS_I(sb->s_root->d_inode));
kfree(args);
+#ifdef CONFIG_SYSFS
+ xfs_event_alloc(mp);
+#endif
return 0;
out_filestream_unmount:
@@ -2151,6 +2157,10 @@ init_xfs_fs(void)
error = register_filesystem(&xfs_fs_type);
if (error)
goto out_sysctl_unregister;
+
+#ifdef CONFIG_SYSFS
+ xfs_sysfs_init();
+#endif
return 0;
out_sysctl_unregister:
@@ -2184,6 +2194,9 @@ exit_xfs_fs(void)
xfs_free_trace_bufs();
xfs_destroy_zones();
ktrace_uninit();
+#ifdef CONFIG_SYSFS
+ xfs_sysfs_done();
+#endif
}
module_init(init_xfs_fs);
diff --git a/xfs/xfs_mount.c b/xfs/xfs_mount.c
index a4503f5..2854b00 100644
--- a/xfs/xfs_mount.c
+++ b/xfs/xfs_mount.c
@@ -2441,3 +2441,25 @@ balance_counter:
}
#endif
+
+
+__uint64_t xfs_icsb_get_fdblocks_lazy(xfs_mount_t *mp)
+{
+ __uint64_t fdblocks = 0;
+#ifdef HAVE_PERCPU_SB
+ xfs_icsb_cnts_t *cntp;
+ int i;
+
+ for_each_online_cpu(i) {
+ cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
+ fdblocks += cntp->icsb_fdblocks;
+ }
+
+ if (xfs_icsb_counter_disabled(mp, XFS_SBS_FDBLOCKS))
+ fdblocks = mp->m_sb.sb_fdblocks;
+#else
+ fdblocks = mp->m_sb.sb_fdblocks;
+#endif
+ return fdblocks - XFS_ALLOC_SET_ASIDE(mp);
+}
+
diff --git a/xfs/xfs_mount.h b/xfs/xfs_mount.h
index b6b8be8..a7c17fe 100644
--- a/xfs/xfs_mount.h
+++ b/xfs/xfs_mount.h
@@ -342,6 +342,9 @@ typedef struct xfs_mount {
int m_sync_seq; /* sync thread generation no. */
wait_queue_head_t m_wait_single_sync_task;
struct vfsmount *m_vfsmount;
+#ifdef CONFIG_SYSFS
+ void *event_onlow;
+#endif
} xfs_mount_t;
/*
@@ -540,6 +543,13 @@ extern void xfs_qmops_put(struct xfs_mount *);
extern struct xfs_dmops xfs_dmcore_xfs;
+#ifdef CONFIG_SYSFS
+extern void xfs_sysfs_init(void);
+extern void xfs_sysfs_done(void);
+extern int xfs_event_alloc(struct xfs_mount *mnt);
+extern int xfs_event_release(struct xfs_mount *mnt);
+#endif
+
#endif /* __KERNEL__ */
#endif /* __XFS_MOUNT_H__ */
[-- Attachment #5: xfs-sysfs-2.diff --]
[-- Type: text/x-diff, Size: 9399 bytes --]
diff --git a/xfs/xfs_sysfs.c b/xfs/xfs_sysfs.c
new file mode 100644
index 0000000..cbb0ed2
--- /dev/null
+++ b/xfs/xfs_sysfs.c
@@ -0,0 +1,339 @@
+/*
+ * A sysfs interface for triggering events like "Nearly Out Of Space"
+ * Krzysztof Blaszkowski <kb@sysmikro.com.pl> 2009
+ *
+ *
+ * each mounted block device will be associted with a directory under
+ * /sys/fs/xfs-oos/ where there is a file "trigger" which sets
+ * a free space trigger point and if crossed over then there will be raised
+ * an uevent like this:
+ * UEVENT[1240929288.150050] change /fs/xfs-oos/dm-18 (xfs-oos)
+ * ACTION=change
+ * DEVPATH=/fs/xfs-oos/dm-18
+ * SUBSYSTEM=xfs-oos
+ * XFSDEV=dm-18
+ * XFSLEFT=191111168
+ *
+ * syntax:
+ * echo "1G" > /sys/fs/xfs-oos/ the_block_device_name /trigger
+ * echo "400M" > /sys/fs/xfs-oos/ some_other_bdev /trigger
+ * echo "20000000" > /sys/fs/xfs-oos/ yet_another_bdev /trigger
+ *
+ * the module polls each mount point every fixed time (5 sec)
+ * and if necessary raises events. it utilizes hysteresis loop of 1/8
+ * of trigger value to avoid sending excessive events on small change.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#ifdef CONFIG_SYSFS
+
+#include <linux/kobject.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+
+#include "xfs.h"
+#include "xfs_fs.h"
+#include "xfs_types.h"
+#include "xfs_bit.h"
+#include "xfs_log.h"
+#include "xfs_inum.h"
+#include "xfs_trans.h"
+#include "xfs_sb.h"
+#include "xfs_ag.h"
+#include "xfs_dir2.h"
+#include "xfs_dmapi.h"
+#include "xfs_mount.h"
+
+
+static struct xfs_event_ctrl {
+ struct kset *kset;
+ struct timer_list poll;
+ int poll_interval;
+ spinlock_t kset_lock;
+ /* because kset is acessed in different contextes then
+ kobject locking (kset->lock) is not appropriate this time */
+} xfs_event_ctrl;
+
+
+
+struct xfs_event_s {
+ struct kobject kobj;
+ __uint64_t trigger;
+ __uint64_t left_bytes;
+ struct xfs_mount *mp;
+ int triggered:1;
+ int fire_event:1;
+};
+
+struct xfs_event_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct xfs_event_s *, struct xfs_event_attribute *, char *);
+ ssize_t (*store)(struct xfs_event_s *, struct xfs_event_attribute *, const char *, ssize_t);
+};
+
+
+static ssize_t xfs_event_kobj_attr_show(struct kobject *_kobj,
+ struct attribute *a,
+ char *buf)
+{
+ struct xfs_event_attribute *attribute = container_of(a, struct xfs_event_attribute, attr);
+ struct xfs_event_s *event = container_of(_kobj, struct xfs_event_s, kobj);
+
+ if (!attribute->show)
+ return -EIO;
+
+ return attribute->show(event, attribute, buf);
+}
+
+static ssize_t xfs_event_kobj_attr_store(struct kobject *_kobj,
+ struct attribute *a,
+ const char *buf, size_t len)
+{
+ struct xfs_event_attribute *attribute = container_of(a, struct xfs_event_attribute, attr);
+ struct xfs_event_s *event = container_of(_kobj, struct xfs_event_s, kobj);
+
+ if (!attribute->store)
+ return -EIO;
+
+ return attribute->store(event, attribute, buf, len);
+}
+
+static void xfs_event_kobj_release(struct kobject *_kobj)
+{
+ struct xfs_event_s *event = container_of(_kobj, struct xfs_event_s, kobj);
+ kfree(event);
+}
+
+
+static const struct sysfs_ops xfs_event_sysfs_ops = {
+ .show = xfs_event_kobj_attr_show,
+ .store = xfs_event_kobj_attr_store,
+};
+
+static const struct attribute *xfs_events_attrs[];
+static const struct kobj_type xfs_event_ktype = {
+ .sysfs_ops = (void *)&xfs_event_sysfs_ops,
+ .release = xfs_event_kobj_release,
+ .default_attrs = (void *)xfs_events_attrs,
+};
+
+
+
+
+
+static ssize_t xfs_trigger_get(struct xfs_event_s *event,
+ struct xfs_event_attribute *obj_attr,
+ char *buf)
+{
+ __uint64_t bs = event->mp->m_sb.sb_blocksize;
+
+ return sprintf(buf, "%lld %lld %c", event->trigger * bs, event->left_bytes, event->triggered ? '1' : '0');
+}
+
+static ssize_t xfs_trigger_set(struct xfs_event_s *event,
+ struct xfs_event_attribute *obj_attr,
+ const char *buf, ssize_t count)
+{
+ int rc;
+ char unit;
+
+ spin_lock_bh(&xfs_event_ctrl.kset_lock);
+ rc = sscanf(buf, "%lld%c", &event->trigger, &unit);
+ if (rc == 2) {
+ switch(unit) {
+ case 'T':
+ case 't':
+ event->trigger <<= 10;
+ case 'G':
+ case 'g':
+ event->trigger <<= 10;
+ case 'M':
+ case 'm':
+ event->trigger <<= 20;
+ }
+ }
+ event->trigger /= event->mp->m_sb.sb_blocksize;
+ spin_unlock_bh(&xfs_event_ctrl.kset_lock);
+ return count;
+}
+
+
+static const struct xfs_event_attribute xfs_event_trigger =
+ __ATTR(trigger, S_IFREG | S_IRUGO | S_IWUSR,
+ xfs_trigger_get,
+ xfs_trigger_set);
+
+static const struct attribute *xfs_events_attrs[] = {
+ &xfs_event_trigger.attr,
+ NULL
+};
+
+
+extern __uint64_t xfs_icsb_get_fdblocks_lazy(xfs_mount_t *mp);
+
+static void xfs_event_fdblocks_poll(unsigned long arg)
+{
+ struct xfs_event_ctrl *ctrl = (struct xfs_event_ctrl *)arg;
+ struct kset *kset = ctrl->kset;
+ struct kobject *k, *tmp;
+
+ struct list_head events_to_fire;
+
+ INIT_LIST_HEAD(&events_to_fire);
+ mod_timer(&ctrl->poll, jiffies + ctrl->poll_interval);
+ spin_lock_bh(&ctrl->kset_lock);
+ /* no need to use kset->lock */
+ list_for_each_entry_safe(k, tmp, &kset->list, entry) {
+ struct xfs_event_s *event = container_of(k, struct xfs_event_s, kobj);
+ __uint64_t space_left = xfs_icsb_get_fdblocks_lazy(event->mp);
+
+ if (space_left < event->trigger && !event->triggered) {
+ event->triggered = 1;
+ kobject_get(&event->kobj);
+ event->left_bytes = space_left * event->mp->m_sb.sb_blocksize;
+ list_del(&event->kobj.entry);
+ list_add(&event->kobj.entry, &events_to_fire);
+ }
+
+ if (space_left > (event->trigger + (event->trigger >> 3))
+ && event->triggered) {
+ event->triggered = 0;
+ }
+
+ }
+ spin_unlock_bh(&ctrl->kset_lock);
+
+ if (!list_empty(&events_to_fire)) {
+ char buffer[256];
+ char *envp[3];
+
+ envp[0] = buffer;
+ envp[2] = NULL;
+ list_for_each_entry(k, &events_to_fire, entry) {
+ struct xfs_event_s *event = container_of(k, struct xfs_event_s, kobj);
+
+ envp[1] = envp[0] + snprintf(envp[0], 250, "XFSDEV=%s", k->name) + 1;
+ snprintf(envp[1], 250 - (envp[1] - envp[0]), "XFSLEFT=%lld", event->left_bytes);
+
+// printk("%s:%d firing [%s] [%s] [%s]\n", __FUNCTION__, __LINE__, k->name, envp[0], envp[1]);
+ kobject_uevent_env(k, KOBJ_CHANGE, envp);
+ }
+
+ spin_lock_bh(&ctrl->kset_lock);
+ list_for_each_entry_safe(k, tmp, &events_to_fire, entry) {
+ struct xfs_event_s *event = container_of(k, struct xfs_event_s, kobj);
+
+ list_del(&event->kobj.entry);
+ list_add(&event->kobj.entry, &kset->list);
+ kobject_put(&event->kobj);
+ }
+ spin_unlock_bh(&ctrl->kset_lock);
+ }
+}
+
+
+/* api */
+
+void xfs_sysfs_init(void)
+{
+ memset(&xfs_event_ctrl, 0, sizeof(struct xfs_event_ctrl));
+
+ xfs_event_ctrl.poll_interval = HZ * 5;
+ xfs_event_ctrl.kset = kset_create_and_add("xfs-oos", NULL, fs_kobj);
+ spin_lock_init(&xfs_event_ctrl.kset_lock);
+ if (!xfs_event_ctrl.kset) {
+ cmn_err(CE_ALERT, "kset_create failed");
+ return;
+ }
+}
+
+void xfs_sysfs_done(void)
+{
+ if (xfs_event_ctrl.kset) {
+ BUG_ON(!list_empty(&xfs_event_ctrl.kset->list));
+ kset_unregister(xfs_event_ctrl.kset);
+ xfs_event_ctrl.kset = NULL;
+ }
+}
+
+/* stuff for xfs_fs_fill_super, xfs_fs_put_super */
+
+int xfs_event_alloc(struct xfs_mount *mnt)
+{
+ struct xfs_event_s * ev;
+ int rc = -1;
+ int empty;
+
+ if (!xfs_event_ctrl.kset)
+ return rc;
+
+ ev = kzalloc(sizeof(struct xfs_event_s), GFP_KERNEL);
+
+ spin_lock_bh(&xfs_event_ctrl.kset_lock);
+ empty = list_empty(&xfs_event_ctrl.kset->list);
+
+ if (ev) {
+ ev->kobj.kset = xfs_event_ctrl.kset;
+ ev->mp = mnt;
+
+ rc = kobject_init_and_add(&ev->kobj, (void *)&xfs_event_ktype, NULL, "%s", mnt->m_fsname);
+ if (!rc) {
+ mnt->event_onlow = ev;
+ kobject_uevent(&ev->kobj, KOBJ_ADD);
+ } else {
+ kobject_put(&ev->kobj); // ev will be freed too.
+ }
+ }
+ spin_unlock_bh(&xfs_event_ctrl.kset_lock);
+
+ if (empty) {
+ init_timer(&xfs_event_ctrl.poll);
+ xfs_event_ctrl.poll.function = xfs_event_fdblocks_poll;
+ xfs_event_ctrl.poll.data = (unsigned long)&xfs_event_ctrl;
+ xfs_event_ctrl.poll.expires = jiffies + xfs_event_ctrl.poll_interval;
+ add_timer(&xfs_event_ctrl.poll);
+ }
+
+ return rc;
+}
+
+int xfs_event_release(struct xfs_mount *mnt)
+{
+ struct xfs_event_s * ev = (struct xfs_event_s *)mnt->event_onlow;
+ int empty;
+
+ if (!xfs_event_ctrl.kset)
+ return -1;
+
+ spin_lock_bh(&xfs_event_ctrl.kset_lock);
+ if (ev)
+ kobject_put(&ev->kobj);
+
+ empty = list_empty(&xfs_event_ctrl.kset->list);
+ spin_unlock_bh(&xfs_event_ctrl.kset_lock);
+
+ if (empty) {
+ del_timer_sync(&xfs_event_ctrl.poll);
+ }
+
+ return 0;
+}
+
+#endif
+
[-- Attachment #6: Type: text/plain, Size: 121 bytes --]
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next reply other threads:[~2009-04-28 16:18 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-04-28 16:18 Krzysztof Błaszkowski [this message]
2009-04-29 12:50 ` generating uevents by xfs Andi Kleen
2009-04-29 13:12 ` Krzysztof Błaszkowski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200904281818.32127.kb@sysmikro.com.pl \
--to=kb@sysmikro.com.pl \
--cc=xfs@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox