diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 11:14:44 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 11:14:44 -0700 |
commit | 04bbc8e1f68cf4c1aac8024d6aea1a24757e8a5a (patch) | |
tree | 9eee2dd7cca805dc27490a624160ef6d9ddd7dd1 /fs | |
parent | e39dfe52f8f67061317e7108f62a2b33a3d06580 (diff) | |
parent | 0d838347f1325cebfe8b9341a4b4c1f407022231 (diff) | |
download | op-kernel-dev-04bbc8e1f68cf4c1aac8024d6aea1a24757e8a5a.zip op-kernel-dev-04bbc8e1f68cf4c1aac8024d6aea1a24757e8a5a.tar.gz |
Merge tag 'please-pull-pstore' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux
Pull pstore update from Tony Luck:
"Fixes for pstore for 3.11 merge window"
* tag 'please-pull-pstore' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux:
efivars: If pstore_register fails, free unneeded pstore buffer
acpi: Eliminate console msg if pstore.backend excludes ERST
pstore: Return unique error if backend registration excluded by kernel param
pstore: Fail to unlink if a driver has not defined pstore_erase
pstore/ram: remove the power of buffer size limitation
pstore/ram: avoid atomic accesses for ioremapped regions
efi, pstore: Cocci spatch "memdup.spatch"
Diffstat (limited to 'fs')
-rw-r--r-- | fs/pstore/inode.c | 2 | ||||
-rw-r--r-- | fs/pstore/platform.c | 11 | ||||
-rw-r--r-- | fs/pstore/ram.c | 2 | ||||
-rw-r--r-- | fs/pstore/ram_core.c | 54 |
4 files changed, 60 insertions, 9 deletions
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c index e4bcb2c..bfd95bf 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c @@ -178,6 +178,8 @@ static int pstore_unlink(struct inode *dir, struct dentry *dentry) if (p->psi->erase) p->psi->erase(p->type, p->id, p->count, dentry->d_inode->i_ctime, p->psi); + else + return -EPERM; return simple_unlink(dir, dentry); } diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 86d1038..b7ffe2b 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -239,17 +239,15 @@ int pstore_register(struct pstore_info *psi) { struct module *owner = psi->owner; + if (backend && strcmp(backend, psi->name)) + return -EPERM; + spin_lock(&pstore_lock); if (psinfo) { spin_unlock(&pstore_lock); return -EBUSY; } - if (backend && strcmp(backend, psi->name)) { - spin_unlock(&pstore_lock); - return -EINVAL; - } - if (!psi->write) psi->write = pstore_write_compat; psinfo = psi; @@ -274,6 +272,9 @@ int pstore_register(struct pstore_info *psi) add_timer(&pstore_timer); } + pr_info("pstore: Registered %s as persistent store backend\n", + psi->name); + return 0; } EXPORT_SYMBOL_GPL(pstore_register); diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 1376e5a..43abee2 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -399,8 +399,6 @@ static int ramoops_probe(struct platform_device *pdev) goto fail_out; } - if (!is_power_of_2(pdata->mem_size)) - pdata->mem_size = rounddown_pow_of_two(pdata->mem_size); if (!is_power_of_2(pdata->record_size)) pdata->record_size = rounddown_pow_of_two(pdata->record_size); if (!is_power_of_2(pdata->console_size)) diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 5933732..de272d4 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -46,7 +46,7 @@ static inline size_t buffer_start(struct persistent_ram_zone *prz) } /* increase and wrap the start pointer, returning the old value */ -static inline size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a) +static size_t buffer_start_add_atomic(struct persistent_ram_zone *prz, size_t a) { int old; int new; @@ -62,7 +62,7 @@ static inline size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a) } /* increase the size counter until it hits the max size */ -static inline void buffer_size_add(struct persistent_ram_zone *prz, size_t a) +static void buffer_size_add_atomic(struct persistent_ram_zone *prz, size_t a) { size_t old; size_t new; @@ -78,6 +78,53 @@ static inline void buffer_size_add(struct persistent_ram_zone *prz, size_t a) } while (atomic_cmpxchg(&prz->buffer->size, old, new) != old); } +static DEFINE_RAW_SPINLOCK(buffer_lock); + +/* increase and wrap the start pointer, returning the old value */ +static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a) +{ + int old; + int new; + unsigned long flags; + + raw_spin_lock_irqsave(&buffer_lock, flags); + + old = atomic_read(&prz->buffer->start); + new = old + a; + while (unlikely(new > prz->buffer_size)) + new -= prz->buffer_size; + atomic_set(&prz->buffer->start, new); + + raw_spin_unlock_irqrestore(&buffer_lock, flags); + + return old; +} + +/* increase the size counter until it hits the max size */ +static void buffer_size_add_locked(struct persistent_ram_zone *prz, size_t a) +{ + size_t old; + size_t new; + unsigned long flags; + + raw_spin_lock_irqsave(&buffer_lock, flags); + + old = atomic_read(&prz->buffer->size); + if (old == prz->buffer_size) + goto exit; + + new = old + a; + if (new > prz->buffer_size) + new = prz->buffer_size; + atomic_set(&prz->buffer->size, new); + +exit: + raw_spin_unlock_irqrestore(&buffer_lock, flags); +} + +static size_t (*buffer_start_add)(struct persistent_ram_zone *, size_t) = buffer_start_add_atomic; +static void (*buffer_size_add)(struct persistent_ram_zone *, size_t) = buffer_size_add_atomic; + static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz, uint8_t *data, size_t len, uint8_t *ecc) { @@ -372,6 +419,9 @@ static void *persistent_ram_iomap(phys_addr_t start, size_t size) return NULL; } + buffer_start_add = buffer_start_add_locked; + buffer_size_add = buffer_size_add_locked; + return ioremap(start, size); } |