Re: [PATCH v2] Drivers: hv: kvp: fix IP Failover

2016-03-30 Thread Cathy Avery



On 03/29/2016 08:30 AM, Vitaly Kuznetsov wrote:

Hyper-V VMs can be replicated to another hosts and there is a feature to
set different IP for replicas, it is called 'Failover TCP/IP'. When
such guest starts Hyper-V host sends it KVP_OP_SET_IP_INFO message as soon
as we finish negotiation procedure. The problem is that it can happen (and
it actually happens) before userspace daemon connects and we reply with
HV_E_FAIL to the message. As there are no repetitions we fail to set the
requested IP.

Solve the issue by postponing our reply to the negotiation message till
userspace daemon is connected. We can't wait too long as there is a
host-side timeout (cca. 75 seconds) and if we fail to reply in this time
frame the whole KVP service will become inactive. The solution is not
ideal - if it takes userspace daemon more than 60 seconds to connect
IP Failover will still fail but I don't see a solution with our current
separation between kernel and userspace parts.

Other two modules (VSS and FCOPY) don't require such delay, leave them
untouched.

Signed-off-by: Vitaly Kuznetsov 
---
Changes since v1:
- Cancel handshake timeout work on module unload.
---
  drivers/hv/hv_kvp.c   | 31 +++
  drivers/hv/hyperv_vmbus.h |  5 +
  2 files changed, 36 insertions(+)

diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index 9b9b370..cb1a916 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -78,9 +78,11 @@ static void kvp_send_key(struct work_struct *dummy);
  
  static void kvp_respond_to_host(struct hv_kvp_msg *msg, int error);

  static void kvp_timeout_func(struct work_struct *dummy);
+static void kvp_host_handshake_func(struct work_struct *dummy);
  static void kvp_register(int);
  
  static DECLARE_DELAYED_WORK(kvp_timeout_work, kvp_timeout_func);

+static DECLARE_DELAYED_WORK(kvp_host_handshake_work, kvp_host_handshake_func);
  static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);
  
  static const char kvp_devname[] = "vmbus/hv_kvp";

@@ -130,6 +132,11 @@ static void kvp_timeout_func(struct work_struct *dummy)
hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper);
  }
  
+static void kvp_host_handshake_func(struct work_struct *dummy)

+{
+   hv_poll_channel(kvp_transaction.recv_channel, hv_kvp_onchannelcallback);
+}
+
  static int kvp_handle_handshake(struct hv_kvp_msg *msg)
  {
switch (msg->kvp_hdr.operation) {
@@ -154,6 +161,12 @@ static int kvp_handle_handshake(struct hv_kvp_msg *msg)
pr_debug("KVP: userspace daemon ver. %d registered\n",
 KVP_OP_REGISTER);
kvp_register(dm_reg_value);
+
+   /*
+* If we're still negotiating with the host cancel the timeout
+* work to not poll the channel twice.
+*/
+   cancel_delayed_work_sync(&kvp_host_handshake_work);
hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper);
  
  	return 0;

@@ -594,7 +607,22 @@ void hv_kvp_onchannelcallback(void *context)
struct icmsg_negotiate *negop = NULL;
int util_fw_version;
int kvp_srv_version;
+   static enum {NEGO_NOT_STARTED,
+NEGO_IN_PROGRESS,
+NEGO_FINISHED} host_negotiatied = NEGO_NOT_STARTED;
  
+	if (host_negotiatied == NEGO_NOT_STARTED &&

+   kvp_transaction.state < HVUTIL_READY) {
+   /*
+* If userspace daemon is not connected and host is asking
+* us to negotiate we need to delay to not lose messages.
+* This is important for Failover IP setting.
+*/
+   host_negotiatied = NEGO_IN_PROGRESS;
+   schedule_delayed_work(&kvp_host_handshake_work,
+ HV_UTIL_NEGO_TIMEOUT * HZ);
+   return;
+   }
if (kvp_transaction.state > HVUTIL_READY)
return;
  
@@ -672,6 +700,8 @@ void hv_kvp_onchannelcallback(void *context)

vmbus_sendpacket(channel, recv_buffer,
   recvlen, requestid,
   VM_PKT_DATA_INBAND, 0);
+
+   host_negotiatied = NEGO_FINISHED;
}
  
  }

@@ -708,6 +738,7 @@ hv_kvp_init(struct hv_util_service *srv)
  void hv_kvp_deinit(void)
  {
kvp_transaction.state = HVUTIL_DEVICE_DYING;
+   cancel_delayed_work_sync(&kvp_host_handshake_work);
cancel_delayed_work_sync(&kvp_timeout_work);
cancel_work_sync(&kvp_sendkey_work);
hvutil_transport_destroy(hvt);
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 12321b9..8b07f9c 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -36,6 +36,11 @@
  #define HV_UTIL_TIMEOUT 30
  
  /*

+ * Timeout for guest-host handshake for services.
+ */
+#define HV_UTIL_NEGO_TIMEOUT 60
+
+/*
   * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
   * is set by CPUID(HVCPUID_VERSION_FEATURES).
   */


Re: [PATCH v2] Drivers: hv: kvp: fix IP Failover

2016-03-30 Thread Cathy Avery

Sorry acking wrong email.

Thanks,

Cathy

On 03/30/2016 08:21 AM, Cathy Avery wrote:



On 03/29/2016 08:30 AM, Vitaly Kuznetsov wrote:

Hyper-V VMs can be replicated to another hosts and there is a feature to
set different IP for replicas, it is called 'Failover TCP/IP'. When
such guest starts Hyper-V host sends it KVP_OP_SET_IP_INFO message as 
soon
as we finish negotiation procedure. The problem is that it can happen 
(and

it actually happens) before userspace daemon connects and we reply with
HV_E_FAIL to the message. As there are no repetitions we fail to set the
requested IP.

Solve the issue by postponing our reply to the negotiation message till
userspace daemon is connected. We can't wait too long as there is a
host-side timeout (cca. 75 seconds) and if we fail to reply in this time
frame the whole KVP service will become inactive. The solution is not
ideal - if it takes userspace daemon more than 60 seconds to connect
IP Failover will still fail but I don't see a solution with our current
separation between kernel and userspace parts.

Other two modules (VSS and FCOPY) don't require such delay, leave them
untouched.

Signed-off-by: Vitaly Kuznetsov 
---
Changes since v1:
- Cancel handshake timeout work on module unload.
---
  drivers/hv/hv_kvp.c   | 31 +++
  drivers/hv/hyperv_vmbus.h |  5 +
  2 files changed, 36 insertions(+)

diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index 9b9b370..cb1a916 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -78,9 +78,11 @@ static void kvp_send_key(struct work_struct *dummy);
static void kvp_respond_to_host(struct hv_kvp_msg *msg, int error);
  static void kvp_timeout_func(struct work_struct *dummy);
+static void kvp_host_handshake_func(struct work_struct *dummy);
  static void kvp_register(int);
static DECLARE_DELAYED_WORK(kvp_timeout_work, kvp_timeout_func);
+static DECLARE_DELAYED_WORK(kvp_host_handshake_work, 
kvp_host_handshake_func);

  static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);
static const char kvp_devname[] = "vmbus/hv_kvp";
@@ -130,6 +132,11 @@ static void kvp_timeout_func(struct work_struct 
*dummy)

  hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper);
  }
  +static void kvp_host_handshake_func(struct work_struct *dummy)
+{
+hv_poll_channel(kvp_transaction.recv_channel, 
hv_kvp_onchannelcallback);

+}
+
  static int kvp_handle_handshake(struct hv_kvp_msg *msg)
  {
  switch (msg->kvp_hdr.operation) {
@@ -154,6 +161,12 @@ static int kvp_handle_handshake(struct 
hv_kvp_msg *msg)

  pr_debug("KVP: userspace daemon ver. %d registered\n",
   KVP_OP_REGISTER);
  kvp_register(dm_reg_value);
+
+/*
+ * If we're still negotiating with the host cancel the timeout
+ * work to not poll the channel twice.
+ */
+cancel_delayed_work_sync(&kvp_host_handshake_work);
  hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper);
return 0;
@@ -594,7 +607,22 @@ void hv_kvp_onchannelcallback(void *context)
  struct icmsg_negotiate *negop = NULL;
  int util_fw_version;
  int kvp_srv_version;
+static enum {NEGO_NOT_STARTED,
+ NEGO_IN_PROGRESS,
+ NEGO_FINISHED} host_negotiatied = NEGO_NOT_STARTED;
  +if (host_negotiatied == NEGO_NOT_STARTED &&
+kvp_transaction.state < HVUTIL_READY) {
+/*
+ * If userspace daemon is not connected and host is asking
+ * us to negotiate we need to delay to not lose messages.
+ * This is important for Failover IP setting.
+ */
+host_negotiatied = NEGO_IN_PROGRESS;
+schedule_delayed_work(&kvp_host_handshake_work,
+  HV_UTIL_NEGO_TIMEOUT * HZ);
+return;
+}
  if (kvp_transaction.state > HVUTIL_READY)
  return;
  @@ -672,6 +700,8 @@ void hv_kvp_onchannelcallback(void *context)
  vmbus_sendpacket(channel, recv_buffer,
 recvlen, requestid,
 VM_PKT_DATA_INBAND, 0);
+
+host_negotiatied = NEGO_FINISHED;
  }
}
@@ -708,6 +738,7 @@ hv_kvp_init(struct hv_util_service *srv)
  void hv_kvp_deinit(void)
  {
  kvp_transaction.state = HVUTIL_DEVICE_DYING;
+cancel_delayed_work_sync(&kvp_host_handshake_work);
  cancel_delayed_work_sync(&kvp_timeout_work);
  cancel_work_sync(&kvp_sendkey_work);
  hvutil_transport_destroy(hvt);
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 12321b9..8b07f9c 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -36,6 +36,11 @@
  #define HV_UTIL_TIMEOUT 30
/*
+ * Timeout for guest-host handshake for services.
+ */
+#define HV_UTIL_NEGO_TIMEOUT 60
+
+/*
   * The below CPUID leaves are present if 
VersionAndFeatures.HypervisorPresent

   * is set by CPUID(HVCPUID_VERSION_FEATURES).
   */

Acked-by: Cathy Avery 


___
devel mailing list
de...@linuxdrive

[PATCH 1/5] staging: unisys: removed unused switch/port info from visorbus.h

2016-03-30 Thread David Kershner
From: Alexander Curtin 

The fields 'switch_no' and 'internal_port_no' were originally added to the
visor_device struct in preparation of removing the 'device_info' struct
in the now removed 'uislib' library. After the refactoring was complete,
these attributes are not referenced anywhere, and there are no plans to
use them.

Signed-off-by: Alexander Curtin 
Signed-off-by: David Kershner 
---
 drivers/staging/unisys/include/visorbus.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/staging/unisys/include/visorbus.h 
b/drivers/staging/unisys/include/visorbus.h
index 9c47a13..25ffdc0 100644
--- a/drivers/staging/unisys/include/visorbus.h
+++ b/drivers/staging/unisys/include/visorbus.h
@@ -155,8 +155,6 @@ struct visor_device {
u8 *description;
struct controlvm_message_header *pending_msg_hdr;
void *vbus_hdr_info;
-   u32 switch_no;
-   u32 internal_port_no;
uuid_le partition_uuid;
 };
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 4/5] staging: unisys: removed 'visor_device.devnodes' field

2016-03-30 Thread David Kershner
From: Alexander Curtin 

The 'visor_device.devnodes' field was used for displaying driver version
information through the devmajorminor sysfs attribute, which has recently
been removed, rendering the field unnecessary.

Signed-off-by: Alexander Curtin 
Signed-off-by: David Kershner 
---
 drivers/staging/unisys/include/visorbus.h | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/staging/unisys/include/visorbus.h 
b/drivers/staging/unisys/include/visorbus.h
index 729ca7e..cbc6d8f 100644
--- a/drivers/staging/unisys/include/visorbus.h
+++ b/drivers/staging/unisys/include/visorbus.h
@@ -136,12 +136,6 @@ struct visor_device {
struct periodic_work *periodic_work;
bool being_removed;
bool responded_to_device_create;
-   struct {
-   int major, minor;
-   void *attr; /* private use by devmajorminor_attr.c you can
-* change this constant to whatever you want
-*/
-   } devnodes[5];
/* the code will detect and behave appropriately) */
struct semaphore visordriver_callback_lock;
bool pausing;
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 3/5] staging: unisys: removed unused visor_device.type field

2016-03-30 Thread David Kershner
From: Alexander Curtin 

The visor_device.type field was included when preparing to remove
the device_info struct. However, it's not used at all, and was already
redundant by the existence of the 'visor_device.channel_type_guid'
field.

Signed-off-by: Alexander Curtin 
Signed-off-by: David Kershner 
---
 drivers/staging/unisys/include/visorbus.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/staging/unisys/include/visorbus.h 
b/drivers/staging/unisys/include/visorbus.h
index f7e753f..729ca7e 100644
--- a/drivers/staging/unisys/include/visorbus.h
+++ b/drivers/staging/unisys/include/visorbus.h
@@ -149,7 +149,6 @@ struct visor_device {
u32 chipset_bus_no;
u32 chipset_dev_no;
struct visorchipset_state state;
-   uuid_le type;
uuid_le inst;
u8 *name;
struct controlvm_message_header *pending_msg_hdr;
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 5/5] staging: unisys: removed unused channel_bytes attribute

2016-03-30 Thread David Kershner
From: Alexander Curtin 

The channel_bytes attribute in the visor_device struct was meant to keep
track of the number of bytes in the associated channel of the device.
Not only is the variable never set nor used, but the information can
already be accessed by referencing visor_device->visorchannel->nbytes.

Signed-off-by: Alexander Curtin 
Signed-off-by: David Kershner 
---
 drivers/staging/unisys/include/visorbus.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/staging/unisys/include/visorbus.h 
b/drivers/staging/unisys/include/visorbus.h
index cbc6d8f..3788d16 100644
--- a/drivers/staging/unisys/include/visorbus.h
+++ b/drivers/staging/unisys/include/visorbus.h
@@ -124,7 +124,6 @@ struct visor_device {
 */
struct visorchannel *visorchannel;
uuid_le channel_type_guid;
-   u64 channel_bytes;
 
/** These fields are for private use by the bus driver only.
 *  A notable exception is that the visor driver can use
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/5] staging: unisys: remove unused fields in visor_device

2016-03-30 Thread David Kershner
Several fields in visor_device are no longer used due to the rework that has
been done on them. This series removes those fields.

Alexander Curtin (5):
  staging: unisys: removed unused switch/port info from visorbus.h
  staging: unisys: include: removed unused 'visor_device.description'
  staging: unisys: removed unused visor_device.type field
  staging: unisys: removed 'visor_device.devnodes' field
  staging: unisys: removed unused channel_bytes attribute

 drivers/staging/unisys/include/visorbus.h | 11 ---
 1 file changed, 11 deletions(-)

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/5] staging: unisys: include: removed unused 'visor_device.description'

2016-03-30 Thread David Kershner
From: Alexander Curtin 

The 'description' variable in visor_device was added in preparation for
removing the 'device_info' struct when the uislib files were removed.

That attribute is never accessed nor set, and the 'name' attribute
provides enough information to correctly identify the driver, it is not
needed.

Signed-off-by: Alexander Curtin 
Signed-off-by: David Kershner 
---
 drivers/staging/unisys/include/visorbus.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/staging/unisys/include/visorbus.h 
b/drivers/staging/unisys/include/visorbus.h
index 25ffdc0..f7e753f 100644
--- a/drivers/staging/unisys/include/visorbus.h
+++ b/drivers/staging/unisys/include/visorbus.h
@@ -152,7 +152,6 @@ struct visor_device {
uuid_le type;
uuid_le inst;
u8 *name;
-   u8 *description;
struct controlvm_message_header *pending_msg_hdr;
void *vbus_hdr_info;
uuid_le partition_uuid;
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 03/50] mtd: nand: core: use mtd_ooblayout_xxx() helpers where appropriate

2016-03-30 Thread Boris Brezillon
The mtd_ooblayout_xxx() helper functions have been added to avoid direct
accesses to the ecclayout field, and thus ease for future reworks.
Use these helpers in all places where the oobfree[] and eccpos[] arrays
where directly accessed.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/nand_base.c | 201 +++
 drivers/mtd/nand/nand_bch.c  |   3 +-
 2 files changed, 91 insertions(+), 113 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index c3733a1..36a58a0 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1292,13 +1292,12 @@ static int nand_read_page_raw_syndrome(struct mtd_info 
*mtd,
 static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
uint8_t *buf, int oob_required, int page)
 {
-   int i, eccsize = chip->ecc.size;
+   int i, eccsize = chip->ecc.size, ret;
int eccbytes = chip->ecc.bytes;
int eccsteps = chip->ecc.steps;
uint8_t *p = buf;
uint8_t *ecc_calc = chip->buffers->ecccalc;
uint8_t *ecc_code = chip->buffers->ecccode;
-   uint32_t *eccpos = chip->ecc.layout->eccpos;
unsigned int max_bitflips = 0;
 
chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
@@ -1306,8 +1305,10 @@ static int nand_read_page_swecc(struct mtd_info *mtd, 
struct nand_chip *chip,
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 
-   for (i = 0; i < chip->ecc.total; i++)
-   ecc_code[i] = chip->oob_poi[eccpos[i]];
+   ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
+chip->ecc.total);
+   if (ret)
+   return ret;
 
eccsteps = chip->ecc.steps;
p = buf;
@@ -1339,14 +1340,14 @@ static int nand_read_subpage(struct mtd_info *mtd, 
struct nand_chip *chip,
uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi,
int page)
 {
-   int start_step, end_step, num_steps;
-   uint32_t *eccpos = chip->ecc.layout->eccpos;
+   int start_step, end_step, num_steps, ret;
uint8_t *p;
int data_col_addr, i, gaps = 0;
int datafrag_len, eccfrag_len, aligned_len, aligned_pos;
int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1;
-   int index;
+   int index, section = 0;
unsigned int max_bitflips = 0;
+   struct mtd_oob_region oobregion = { };
 
/* Column address within the page aligned to ECC size (256bytes) */
start_step = data_offs / chip->ecc.size;
@@ -1374,12 +1375,13 @@ static int nand_read_subpage(struct mtd_info *mtd, 
struct nand_chip *chip,
 * The performance is faster if we position offsets according to
 * ecc.pos. Let's make sure that there are no gaps in ECC positions.
 */
-   for (i = 0; i < eccfrag_len - 1; i++) {
-   if (eccpos[i + index] + 1 != eccpos[i + index + 1]) {
-   gaps = 1;
-   break;
-   }
-   }
+   ret = mtd_ooblayout_find_eccregion(mtd, index, §ion, &oobregion);
+   if (ret)
+   return ret;
+
+   if (oobregion.length < eccfrag_len)
+   gaps = 1;
+
if (gaps) {
chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -1388,20 +1390,23 @@ static int nand_read_subpage(struct mtd_info *mtd, 
struct nand_chip *chip,
 * Send the command to read the particular ECC bytes take care
 * about buswidth alignment in read_buf.
 */
-   aligned_pos = eccpos[index] & ~(busw - 1);
+   aligned_pos = oobregion.offset & ~(busw - 1);
aligned_len = eccfrag_len;
-   if (eccpos[index] & (busw - 1))
+   if (oobregion.offset & (busw - 1))
aligned_len++;
-   if (eccpos[index + (num_steps * chip->ecc.bytes)] & (busw - 1))
+   if ((oobregion.offset + (num_steps * chip->ecc.bytes)) &
+   (busw - 1))
aligned_len++;
 
chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
-   mtd->writesize + aligned_pos, -1);
+ mtd->writesize + aligned_pos, -1);
chip->read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len);
}
 
-   for (i = 0; i < eccfrag_len; i++)
-   chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + index]];
+   ret = mtd_ooblayout_get_eccbytes(mtd, chip->buffers->ecccode,
+chip->oob_poi, index, eccfrag_len);
+   if (ret)
+   return ret;
 
p = bufpoi + data_col_addr;
for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p

[PATCH v5 00/52] mtd: rework ECC layout definition

2016-03-30 Thread Boris Brezillon
Hello,

Hopefully the last version of this patchset (but don't be sad, I'm not
done bothering you with NAND related patches :-)).

If possible, I'd like to have as much Tested/Reviewed/Acked-by tags as
possible, particularly on the changes done in arch/arm and arch/mips
(since the last set of commits depends on those changes, I'd like to
take them in my nand/next branch, even if this imply creating an
immutable branch for the ARM and MIPS maintainers).

If nobody complains about this version, I'll merge it in 4.7.

Here comes the usual description:

This patchset aims at getting rid of the nand_ecclayout limitations.
struct nand_ecclayout is defining fixed eccpos and oobfree arrays which
can only be increased by modifying the MTD_MAX_ECCPOS_ENTRIES_LARGE and
MTD_MAX_OOBFREE_ENTRIES_LARGE macros.
This approach forces us to modify the macro values each time we add a
new NAND chip with a bigger OOB area, and increasing these arrays also
penalize all platforms, even those who only support small NAND devices
(with small OOB area).

The idea to overcome this limitation, is to define the ECC/OOB layout
by the mean of two functions: ->ecc() and ->free(), which will
basically return the same information has those stored in the
nand_ecclayout struct.

Another advantage of this solution is that ECC layouts are usually
following a repetitive pattern (i.e. leave X bytes free and put Y bytes
of ECC per ECC chunk), which allows one to implement the ->ecc()
and ->free() functions with a simple logic that can be applied
to any size of OOB.

Patches 1 to 4 are just cleanups or trivial fixes that can be taken
independently.

Also note that the last two commits are removing the nand_ecclayout
definition, thus preventing any new driver to use this structure.
Of course, this step can be delayed if some of the previous patches
are not accepted.

All those changes are available here [1].

Best Regards,

Boris

[1]https://github.com/bbrezillon/linux-0day/tree/nand/ecclayout

Changes since v4:
- dropped already applied patches
- patch the recently merged qcom driver

Changes since v3:
- fixed two bugs in mtd_ooblayout core implementation
- use ecc->total instead of (ecc->steps * ecc->bytes) in NAND drivers

Changes since v2:
- fixed a few bugs in the core and driver implementations

Changes since v1:
- unified the way of defining ECC and free bytes
- fixed a few bugs in some ->ecc()/->free() implementations

Boris Brezillon (50):
  mtd: add mtd_ooblayout_xxx() helper functions
  mtd: use mtd_ooblayout_xxx() helpers where appropriate
  mtd: nand: core: use mtd_ooblayout_xxx() helpers where appropriate
  mtd: nand: atmel: use mtd_ooblayout_xxx() helpers where appropriate
  mtd: nand: fsl_ifc: use mtd_ooblayout_xxx() helpers where appropriate
  mtd: nand: gpmi: use mtd_ooblayout_xxx() helpers where appropriate
  mtd: nand: lpc32xx: use mtd_ooblayout_xxx() helpers where appropriate
  mtd: nand: omap2: use mtd_ooblayout_xxx() helpers where appropriate
  mtd: nand: qcom: use mtd_ooblayout_xxx() helpers where appropriate
  mtd: onenand: use mtd_ooblayout_xxx() helpers where appropriate
  mtd: add mtd_set_ecclayout() helper function
  mtd: use mtd_set_ecclayout() where appropriate
  mtd: nand: use mtd_set_ecclayout() where appropriate
  mtd: onenand: use mtd_set_ecclayout() where appropriate
  mtd: docg3: use mtd_set_ecclayout() where appropriate
  mtd: create an mtd_ooblayout_ops struct to ease ECC layout definition
  mtd: docg3: switch to mtd_ooblayout_ops
  mtd: nand: implement the default mtd_ooblayout_ops
  mtd: nand: bch: switch to mtd_ooblayout_ops
  mtd: nand: sharpsl: switch to mtd_ooblayout_ops
  mtd: nand: jz4740: switch to mtd_ooblayout_ops
  mtd: nand: atmel: switch to mtd_ooblayout_ops
  mtd: nand: bf5xx: switch to mtd_ooblayout_ops
  mtd: nand: brcm: switch to mtd_ooblayout_ops
  mtd: nand: cafe: switch to mtd_ooblayout_ops
  mtd: nand: davinci: switch to mtd_ooblayout_ops
  mtd: nand: denali: switch to mtd_ooblayout_ops
  mtd: nand: diskonchip: switch to mtd_ooblayout_ops
  mtd: nand: docg4: switch to mtd_ooblayout_ops
  mtd: nand: fsl_elbc: switch to mtd_ooblayout_ops
  mtd: nand: fsl_ifc: switch to mtd_ooblayout_ops
  mtd: nand: fsmc: switch to mtd_ooblayout_ops
  mtd: nand: fsmc: get rid of the fsmc_nand_eccplace struct
  mtd: nand: gpmi: switch to mtd_ooblayout_ops
  mtd: nand: hisi504: switch to mtd_ooblayout_ops
  mtd: nand: jz4780: switch to mtd_ooblayout_ops
  mtd: nand: lpc32xx: switch to mtd_ooblayout_ops
  mtd: nand: mxc: switch to mtd_ooblayout_ops
  mtd: nand: omap2: switch to mtd_ooblayout_ops
  mtd: nand: pxa3xx: switch to mtd_ooblayout_ops
  mtd: nand: s3c2410: switch to mtd_ooblayout_ops
  mtd: nand: sh_flctl: switch to mtd_ooblayout_ops
  mtd: nand: sm_common: switch to mtd_ooblayout_ops
  mtd: nand: sunxi: switch to mtd_ooblayout_ops
  mtd: nand: vf610: switch to mtd_ooblayout_ops
  mtd: nand: qcom: switch to mtd_ooblayout_ops
  mtd: onenand: switch to mtd_ooblayout_ops
  staging: mt29f_spinand: switch to

[PATCH v5 01/50] mtd: add mtd_ooblayout_xxx() helper functions

2016-03-30 Thread Boris Brezillon
In order to make the ecclayout definition completely dynamic we need to
rework the way the OOB layout are defined and iterated.

Create a few mtd_ooblayout_xxx() helpers to ease OOB bytes manipulation
and hide ecclayout internals to their users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/mtdcore.c   | 400 
 include/linux/mtd/mtd.h |  33 
 2 files changed, 433 insertions(+)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 3096251..9fc278a 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -997,6 +997,406 @@ int mtd_read_oob(struct mtd_info *mtd, loff_t from, 
struct mtd_oob_ops *ops)
 }
 EXPORT_SYMBOL_GPL(mtd_read_oob);
 
+/**
+ * mtd_ooblayout_ecc - Get the OOB region definition of a specific ECC section
+ * @mtd: MTD device structure
+ * @section: ECC section. Depending on the layout you may have all the ECC
+ *  bytes stored in a single contiguous section, or one section
+ *  per ECC chunk (and sometime several sections for a single ECC
+ *  ECC chunk)
+ * @oobecc: OOB region struct filled with the appropriate ECC position
+ * information
+ *
+ * This functions return ECC section information in the OOB area. I you want
+ * to get all the ECC bytes information, then you should call
+ * mtd_ooblayout_ecc(mtd, section++, oobecc) until it returns -ERANGE.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ */
+int mtd_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobecc)
+{
+   int eccbyte = 0, cursection = 0, length = 0, eccpos = 0;
+
+   memset(oobecc, 0, sizeof(*oobecc));
+
+   if (!mtd || section < 0)
+   return -EINVAL;
+
+   if (!mtd->ecclayout)
+   return -ENOTSUPP;
+
+   /*
+* This logic allows us to reuse the ->ecclayout information and
+* expose them as ECC regions (as done for the OOB free regions).
+*
+* TODO: this should be dropped as soon as we get rid of the
+* ->ecclayout field.
+*/
+   for (eccbyte = 0; eccbyte < mtd->ecclayout->eccbytes; eccbyte++) {
+   eccpos = mtd->ecclayout->eccpos[eccbyte];
+
+   if (eccbyte < mtd->ecclayout->eccbytes - 1) {
+   int neccpos = mtd->ecclayout->eccpos[eccbyte + 1];
+
+   if (eccpos + 1 == neccpos) {
+   length++;
+   continue;
+   }
+   }
+
+   if (section == cursection)
+   break;
+
+   length = 0;
+   cursection++;
+   }
+
+   if (cursection != section || eccbyte >= mtd->ecclayout->eccbytes)
+   return -ERANGE;
+
+   oobecc->length = length + 1;
+   oobecc->offset = eccpos - length;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(mtd_ooblayout_ecc);
+
+/**
+ * mtd_ooblayout_free - Get the OOB region definition of a specific free
+ * section
+ * @mtd: MTD device structure
+ * @section: Free section you are interested in. Depending on the layout
+ *  you may have all the free bytes stored in a single contiguous
+ *  section, or one section per ECC chunk plus an extra section
+ *  for the remaining bytes (or other funky layout).
+ * @oobfree: OOB region struct filled with the appropriate free position
+ *  information
+ *
+ * This functions return free bytes position in the OOB area. I you want
+ * to get all the free bytes information, then you should call
+ * mtd_ooblayout_free(mtd, section++, oobfree) until it returns -ERANGE.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ */
+int mtd_ooblayout_free(struct mtd_info *mtd, int section,
+  struct mtd_oob_region *oobfree)
+{
+   memset(oobfree, 0, sizeof(*oobfree));
+
+   if (!mtd || section < 0)
+   return -EINVAL;
+
+   if (!mtd->ecclayout)
+   return -ENOTSUPP;
+
+   if (section >= MTD_MAX_OOBFREE_ENTRIES_LARGE)
+   return -ERANGE;
+
+   oobfree->offset = mtd->ecclayout->oobfree[section].offset;
+   oobfree->length = mtd->ecclayout->oobfree[section].length;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(mtd_ooblayout_free);
+
+/**
+ * mtd_ooblayout_find_region - Find the region attached to a specific byte
+ * @mtd: mtd info structure
+ * @byte: the byte we are searching for
+ * @sectionp: pointer where the section id will be stored
+ * @oobregion: used to retrieve the ECC position
+ * @iter: iterator function. Should be either mtd_ooblayout_free or
+ *   mtd_ooblayout_ecc depending on the region type you're searching for
+ *
+ * This functions returns the section id and oobregion information of a
+ * specific byte. For example, say you want to know where the 4th ECC byte is
+ * stored, you'll use:
+ *
+ * mtd_ooblayout_find_region(mtd, 3, §ion, &oobreg

[PATCH v5 09/50] mtd: nand: qcom: use mtd_ooblayout_xxx() helpers where appropriate

2016-03-30 Thread Boris Brezillon
The mtd_ooblayout_xxx() helper functions have been added to avoid direct
accesses to ecclayout fields, and thus ease for future reworks.
Use these helpers in all places where the oobfree[] and eccpos[] arrays
where directly accessed.

Signed-off-by: Boris Brezillon 
Tested-by: Archit Taneja 
---
 drivers/mtd/nand/qcom_nandc.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index f550a57..012c202 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -1437,7 +1437,6 @@ static int qcom_nandc_write_oob(struct mtd_info *mtd, 
struct nand_chip *chip,
struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
struct nand_ecc_ctrl *ecc = &chip->ecc;
u8 *oob = chip->oob_poi;
-   int free_boff;
int data_size, oob_size;
int ret, status = 0;
 
@@ -1451,12 +1450,11 @@ static int qcom_nandc_write_oob(struct mtd_info *mtd, 
struct nand_chip *chip,
 
/* calculate the data and oob size for the last codeword/step */
data_size = ecc->size - ((ecc->steps - 1) << 2);
-   oob_size = ecc->steps << 2;
-
-   free_boff = ecc->layout->oobfree[0].offset;
+   oob_size = mtd->oobavail;
 
/* override new oob content to last codeword */
-   memcpy(nandc->data_buffer + data_size, oob + free_boff, oob_size);
+   mtd_ooblayout_get_databytes(mtd, nandc->data_buffer + data_size, oob,
+   0, mtd->oobavail);
 
set_address(host, host->cw_size * (ecc->steps - 1), page);
update_rw_regs(host, 1, false);
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 07/50] mtd: nand: lpc32xx: use mtd_ooblayout_xxx() helpers where appropriate

2016-03-30 Thread Boris Brezillon
The mtd_ooblayout_xxx() helper functions have been added to avoid direct
accesses to the ecclayout field, and thus ease for future reworks.
Use these helpers in all places where the oobfree[] and eccpos[] arrays
where directly accessed.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/lpc32xx_slc.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c
index 3b8f373..10cf8e62 100644
--- a/drivers/mtd/nand/lpc32xx_slc.c
+++ b/drivers/mtd/nand/lpc32xx_slc.c
@@ -604,7 +604,8 @@ static int lpc32xx_nand_read_page_syndrome(struct mtd_info 
*mtd,
   int oob_required, int page)
 {
struct lpc32xx_nand_host *host = nand_get_controller_data(chip);
-   int stat, i, status;
+   struct mtd_oob_region oobregion = { };
+   int stat, i, status, error;
uint8_t *oobecc, tmpecc[LPC32XX_ECC_SAVE_SIZE];
 
/* Issue read command */
@@ -620,7 +621,11 @@ static int lpc32xx_nand_read_page_syndrome(struct mtd_info 
*mtd,
lpc32xx_slc_ecc_copy(tmpecc, (uint32_t *) host->ecc_buf, 
chip->ecc.steps);
 
/* Pointer to ECC data retrieved from NAND spare area */
-   oobecc = chip->oob_poi + chip->ecc.layout->eccpos[0];
+   error = mtd_ooblayout_ecc(mtd, 0, &oobregion);
+   if (error)
+   return error;
+
+   oobecc = chip->oob_poi + oobregion.offset;
 
for (i = 0; i < chip->ecc.steps; i++) {
stat = chip->ecc.correct(mtd, buf, oobecc,
@@ -666,7 +671,8 @@ static int lpc32xx_nand_write_page_syndrome(struct mtd_info 
*mtd,
int oob_required, int page)
 {
struct lpc32xx_nand_host *host = nand_get_controller_data(chip);
-   uint8_t *pb = chip->oob_poi + chip->ecc.layout->eccpos[0];
+   struct mtd_oob_region oobregion = { };
+   uint8_t *pb;
int error;
 
/* Write data, calculate ECC on outbound data */
@@ -678,6 +684,11 @@ static int lpc32xx_nand_write_page_syndrome(struct 
mtd_info *mtd,
 * The calculated ECC needs some manual work done to it before
 * committing it to NAND. Process the calculated ECC and place
 * the resultant values directly into the OOB buffer. */
+   error = mtd_ooblayout_ecc(mtd, 0, &oobregion);
+   if (error)
+   return error;
+
+   pb = chip->oob_poi + oobregion.offset;
lpc32xx_slc_ecc_copy(pb, (uint32_t *)host->ecc_buf, chip->ecc.steps);
 
/* Write ECC data to device */
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 04/50] mtd: nand: atmel: use mtd_ooblayout_xxx() helpers where appropriate

2016-03-30 Thread Boris Brezillon
The mtd_ooblayout_xxx() helper functions have been added to avoid direct
accesses to the ecclayout field, and thus ease for future reworks.
Use these helpers in all places where the oobfree[] and eccpos[] arrays
where directly accessed.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/atmel_nand.c | 48 ++-
 1 file changed, 29 insertions(+), 19 deletions(-)

diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 0b5da72..321d331 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -836,13 +836,16 @@ static void pmecc_correct_data(struct mtd_info *mtd, 
uint8_t *buf, uint8_t *ecc,
dev_dbg(host->dev, "Bit flip in data area, byte_pos: 
%d, bit_pos: %d, 0x%02x -> 0x%02x\n",
pos, bit_pos, err_byte, *(buf + byte_pos));
} else {
+   struct mtd_oob_region oobregion;
+
/* Bit flip in OOB area */
tmp = sector_num * nand_chip->ecc.bytes
+ (byte_pos - sector_size);
err_byte = ecc[tmp];
ecc[tmp] ^= (1 << bit_pos);
 
-   pos = tmp + nand_chip->ecc.layout->eccpos[0];
+   mtd_ooblayout_ecc(mtd, 0, &oobregion);
+   pos = tmp + oobregion.offset;
dev_dbg(host->dev, "Bit flip in OOB, oob_byte_pos: %d, 
bit_pos: %d, 0x%02x -> 0x%02x\n",
pos, bit_pos, err_byte, ecc[tmp]);
}
@@ -934,7 +937,6 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
struct atmel_nand_host *host = nand_get_controller_data(chip);
int eccsize = chip->ecc.size * chip->ecc.steps;
uint8_t *oob = chip->oob_poi;
-   uint32_t *eccpos = chip->ecc.layout->eccpos;
uint32_t stat;
unsigned long end_time;
int bitflips = 0;
@@ -956,7 +958,11 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
 
stat = pmecc_readl_relaxed(host->ecc, ISR);
if (stat != 0) {
-   bitflips = pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]);
+   struct mtd_oob_region oobregion;
+
+   mtd_ooblayout_ecc(mtd, 0, &oobregion);
+   bitflips = pmecc_correction(mtd, stat, buf,
+   &oob[oobregion.offset]);
if (bitflips < 0)
/* uncorrectable errors */
return 0;
@@ -970,8 +976,8 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
int page)
 {
struct atmel_nand_host *host = nand_get_controller_data(chip);
-   uint32_t *eccpos = chip->ecc.layout->eccpos;
-   int i, j;
+   struct mtd_oob_region oobregion = { };
+   int i, j, section = 0;
unsigned long end_time;
 
if (!host->nfc || !host->nfc->write_by_sram) {
@@ -990,11 +996,12 @@ static int atmel_nand_pmecc_write_page(struct mtd_info 
*mtd,
 
for (i = 0; i < chip->ecc.steps; i++) {
for (j = 0; j < chip->ecc.bytes; j++) {
-   int pos;
+   if (!oobregion.length)
+   mtd_ooblayout_ecc(mtd, section++, &oobregion);
 
-   pos = i * chip->ecc.bytes + j;
-   chip->oob_poi[eccpos[pos]] =
+   chip->oob_poi[oobregion.offset++] =
pmecc_readb_ecc_relaxed(host->ecc, i, j);
+   oobregion.length--;
}
}
chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -1008,6 +1015,7 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
struct atmel_nand_host *host = nand_get_controller_data(nand_chip);
uint32_t val = 0;
struct nand_ecclayout *ecc_layout;
+   struct mtd_oob_region oobregion;
 
pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST);
pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
@@ -1059,9 +1067,10 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
 
ecc_layout = nand_chip->ecc.layout;
pmecc_writel(host->ecc, SAREA, mtd->oobsize - 1);
-   pmecc_writel(host->ecc, SADDR, ecc_layout->eccpos[0]);
+   mtd_ooblayout_ecc(mtd, 0, &oobregion);
+   pmecc_writel(host->ecc, SADDR, oobregion.offset);
pmecc_writel(host->ecc, EADDR,
-   ecc_layout->eccpos[ecc_layout->eccbytes - 1]);
+oobregion.offset + ecc_layout->eccbytes - 1);
/* See datasheet about PMECC Clock Control Register */
pmecc_writel(host->ecc, CLK, 2);
pmecc_writel(host->ecc, IDR, 0xff);
@@ -1362,12 +1371,12 @@ static int atmel_nand_read_page(struct mtd_info *mtd, 
struct nand_chip *chip,
 {
int eccsize = chip->ecc.size;
int eccbytes = chip->ecc.bytes;
-   uint32

[PATCH v5 05/50] mtd: nand: fsl_ifc: use mtd_ooblayout_xxx() helpers where appropriate

2016-03-30 Thread Boris Brezillon
The mtd_ooblayout_xxx() helper functions have been added to avoid direct
accesses to the ecclayout field, and thus ease for future reworks.
Use these helpers in all places where the oobfree[] and eccpos[] arrays
where directly accessed.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/fsl_ifc_nand.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index 43f5a3a..2e970ac 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -257,18 +257,22 @@ static int is_blank(struct mtd_info *mtd, unsigned int 
bufnum)
u8 __iomem *addr = priv->vbase + bufnum * (mtd->writesize * 2);
u32 __iomem *mainarea = (u32 __iomem *)addr;
u8 __iomem *oob = addr + mtd->writesize;
-   int i;
+   struct mtd_oob_region oobregion = { };
+   int i, section = 0;
 
for (i = 0; i < mtd->writesize / 4; i++) {
if (__raw_readl(&mainarea[i]) != 0x)
return 0;
}
 
-   for (i = 0; i < chip->ecc.layout->eccbytes; i++) {
-   int pos = chip->ecc.layout->eccpos[i];
+   mtd_ooblayout_ecc(mtd, section++, &oobregion);
+   while (oobregion.length) {
+   for (i = 0; i < oobregion.length; i++) {
+   if (__raw_readb(&oob[oobregion.offset + i]) != 0xff)
+   return 0;
+   }
 
-   if (__raw_readb(&oob[pos]) != 0xff)
-   return 0;
+   mtd_ooblayout_ecc(mtd, section++, &oobregion);
}
 
return 1;
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 02/50] mtd: use mtd_ooblayout_xxx() helpers where appropriate

2016-03-30 Thread Boris Brezillon
The mtd_ooblayout_xxx() helper functions have been added to avoid direct
accesses to the ecclayout field, and thus ease for future reworks.
Use these helpers in all places where the oobfree[] and eccpos[] arrays
where directly accessed.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/mtdchar.c | 107 +-
 1 file changed, 88 insertions(+), 19 deletions(-)

diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 6d19835..cd64ab7 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -472,28 +472,101 @@ static int mtdchar_readoob(struct file *file, struct 
mtd_info *mtd,
  * nand_ecclayout flexibly (i.e. the struct may change size in new
  * releases without requiring major rewrites).
  */
-static int shrink_ecclayout(const struct nand_ecclayout *from,
-   struct nand_ecclayout_user *to)
+static int shrink_ecclayout(struct mtd_info *mtd,
+   struct nand_ecclayout_user *to)
 {
-   int i;
+   struct mtd_oob_region oobregion;
+   int i, section = 0, ret;
 
-   if (!from || !to)
+   if (!mtd || !to)
return -EINVAL;
 
memset(to, 0, sizeof(*to));
 
-   to->eccbytes = min((int)from->eccbytes, MTD_MAX_ECCPOS_ENTRIES);
-   for (i = 0; i < to->eccbytes; i++)
-   to->eccpos[i] = from->eccpos[i];
+   to->eccbytes = 0;
+   for (i = 0; i < MTD_MAX_ECCPOS_ENTRIES;) {
+   u32 eccpos;
+
+   ret = mtd_ooblayout_ecc(mtd, section, &oobregion);
+   if (ret < 0) {
+   if (ret != -ERANGE)
+   return ret;
+
+   break;
+   }
+
+   eccpos = oobregion.offset;
+   for (; i < MTD_MAX_ECCPOS_ENTRIES &&
+  eccpos < oobregion.offset + oobregion.length; i++) {
+   to->eccpos[i] = eccpos++;
+   to->eccbytes++;
+   }
+   }
 
for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++) {
-   if (from->oobfree[i].length == 0 &&
-   from->oobfree[i].offset == 0)
+   ret = mtd_ooblayout_free(mtd, i, &oobregion);
+   if (ret < 0) {
+   if (ret != -ERANGE)
+   return ret;
+
+   break;
+   }
+
+   to->oobfree[i].offset = oobregion.offset;
+   to->oobfree[i].length = oobregion.length;
+   to->oobavail += to->oobfree[i].length;
+   }
+
+   return 0;
+}
+
+static int get_oobinfo(struct mtd_info *mtd, struct nand_oobinfo *to)
+{
+   struct mtd_oob_region oobregion;
+   int i, section = 0, ret;
+
+   if (!mtd || !to)
+   return -EINVAL;
+
+   memset(to, 0, sizeof(*to));
+
+   to->eccbytes = 0;
+   for (i = 0; i < ARRAY_SIZE(to->eccpos);) {
+   u32 eccpos;
+
+   ret = mtd_ooblayout_ecc(mtd, section, &oobregion);
+   if (ret < 0) {
+   if (ret != -ERANGE)
+   return ret;
+
break;
-   to->oobavail += from->oobfree[i].length;
-   to->oobfree[i] = from->oobfree[i];
+   }
+
+   if (oobregion.length + i > ARRAY_SIZE(to->eccpos))
+   return -EINVAL;
+
+   eccpos = oobregion.offset;
+   for (; eccpos < oobregion.offset + oobregion.length; i++) {
+   to->eccpos[i] = eccpos++;
+   to->eccbytes++;
+   }
}
 
+   for (i = 0; i < 8; i++) {
+   ret = mtd_ooblayout_free(mtd, i, &oobregion);
+   if (ret < 0) {
+   if (ret != -ERANGE)
+   return ret;
+
+   break;
+   }
+
+   to->oobfree[i][0] = oobregion.offset;
+   to->oobfree[i][1] = oobregion.length;
+   }
+
+   to->useecc = MTD_NANDECC_AUTOPLACE;
+
return 0;
 }
 
@@ -817,14 +890,10 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, 
u_long arg)
 
if (!mtd->ecclayout)
return -EOPNOTSUPP;
-   if (mtd->ecclayout->eccbytes > ARRAY_SIZE(oi.eccpos))
-   return -EINVAL;
 
-   oi.useecc = MTD_NANDECC_AUTOPLACE;
-   memcpy(&oi.eccpos, mtd->ecclayout->eccpos, sizeof(oi.eccpos));
-   memcpy(&oi.oobfree, mtd->ecclayout->oobfree,
-  sizeof(oi.oobfree));
-   oi.eccbytes = mtd->ecclayout->eccbytes;
+   ret = get_oobinfo(mtd, &oi);
+   if (ret)
+   return ret;
 
if (copy_to_user(argp, &oi, sizeof(struct nand_oobinfo)))
return -EFAULT;
@@ -920,7 +989,7 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, 
u_

[PATCH v5 08/50] mtd: nand: omap2: use mtd_ooblayout_xxx() helpers where appropriate

2016-03-30 Thread Boris Brezillon
The mtd_ooblayout_xxx() helper functions have been added to avoid direct
accesses to the ecclayout field, and thus ease for future reworks.
Use these helpers in all places where the oobfree[] and eccpos[] arrays
where directly accessed.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/omap2.c | 23 ---
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 0749ca1..4ebf16b 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1495,9 +1495,8 @@ static int omap_elm_correct_data(struct mtd_info *mtd, 
u_char *data,
 static int omap_write_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
   const uint8_t *buf, int oob_required, int page)
 {
-   int i;
+   int ret;
uint8_t *ecc_calc = chip->buffers->ecccalc;
-   uint32_t *eccpos = chip->ecc.layout->eccpos;
 
/* Enable GPMC ecc engine */
chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
@@ -1508,8 +1507,10 @@ static int omap_write_page_bch(struct mtd_info *mtd, 
struct nand_chip *chip,
/* Update ecc vector from GPMC result registers */
chip->ecc.calculate(mtd, buf, &ecc_calc[0]);
 
-   for (i = 0; i < chip->ecc.total; i++)
-   chip->oob_poi[eccpos[i]] = ecc_calc[i];
+   ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0,
+chip->ecc.total);
+   if (ret)
+   return ret;
 
/* Write ecc vector to OOB area */
chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -1536,10 +1537,7 @@ static int omap_read_page_bch(struct mtd_info *mtd, 
struct nand_chip *chip,
 {
uint8_t *ecc_calc = chip->buffers->ecccalc;
uint8_t *ecc_code = chip->buffers->ecccode;
-   uint32_t *eccpos = chip->ecc.layout->eccpos;
-   uint8_t *oob = &chip->oob_poi[eccpos[0]];
-   uint32_t oob_pos = mtd->writesize + chip->ecc.layout->eccpos[0];
-   int stat;
+   int stat, ret;
unsigned int max_bitflips = 0;
 
/* Enable GPMC ecc engine */
@@ -1549,13 +1547,16 @@ static int omap_read_page_bch(struct mtd_info *mtd, 
struct nand_chip *chip,
chip->read_buf(mtd, buf, mtd->writesize);
 
/* Read oob bytes */
-   chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, -1);
-   chip->read_buf(mtd, oob, chip->ecc.total);
+   chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
+   chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
 
/* Calculate ecc bytes */
chip->ecc.calculate(mtd, buf, ecc_calc);
 
-   memcpy(ecc_code, &chip->oob_poi[eccpos[0]], chip->ecc.total);
+   ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
+chip->ecc.total);
+   if (ret)
+   return ret;
 
stat = chip->ecc.correct(mtd, buf, ecc_code, ecc_calc);
 
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 15/50] mtd: docg3: use mtd_set_ecclayout() where appropriate

2016-03-30 Thread Boris Brezillon
Use the mtd_set_ecclayout() helper instead of directly assigning the
mtd->ecclayout field.

Signed-off-by: Boris Brezillon 
Acked-by: Robert Jarzmik 
---
 drivers/mtd/devices/docg3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index e7b2e43..6b516e1 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -1857,7 +1857,7 @@ static int __init doc_set_driver_info(int chip_id, struct 
mtd_info *mtd)
mtd->_read_oob = doc_read_oob;
mtd->_write_oob = doc_write_oob;
mtd->_block_isbad = doc_block_isbad;
-   mtd->ecclayout = &docg3_oobinfo;
+   mtd_set_ecclayout(mtd, &docg3_oobinfo);
mtd->oobavail = 8;
mtd->ecc_strength = DOC_ECC_BCH_T;
 
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 06/50] mtd: nand: gpmi: use mtd_ooblayout_xxx() helpers where appropriate

2016-03-30 Thread Boris Brezillon
The mtd_ooblayout_xxx() helper functions have been added to avoid direct
accesses to the ecclayout field, and thus ease for future reworks.
Use these helpers in all places where the oobfree[] and eccpos[] arrays
where directly accessed.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c 
b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 8122c69..3a29b65 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -1327,18 +1327,19 @@ static int gpmi_ecc_read_oob(struct mtd_info *mtd, 
struct nand_chip *chip,
 static int
 gpmi_ecc_write_oob(struct mtd_info *mtd, struct nand_chip *chip, int page)
 {
-   struct nand_oobfree *of = mtd->ecclayout->oobfree;
+   struct mtd_oob_region of = { };
int status = 0;
 
/* Do we have available oob area? */
-   if (!of->length)
+   mtd_ooblayout_free(mtd, 0, &of);
+   if (!of.length)
return -EPERM;
 
if (!nand_is_slc(chip))
return -EPERM;
 
-   chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize + of->offset, page);
-   chip->write_buf(mtd, chip->oob_poi + of->offset, of->length);
+   chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize + of.offset, page);
+   chip->write_buf(mtd, chip->oob_poi + of.offset, of.length);
chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
 
status = chip->waitfunc(mtd, chip);
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 12/50] mtd: use mtd_set_ecclayout() where appropriate

2016-03-30 Thread Boris Brezillon
Use the mtd_set_ecclayout() helper instead of directly assigning the
mtd->ecclayout field.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/mtdconcat.c | 2 +-
 drivers/mtd/mtdpart.c   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 239a8c8..481565e 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -777,7 +777,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info 
*subdev[],   /* subdevices to c
 
}
 
-   concat->mtd.ecclayout = subdev[0]->ecclayout;
+   mtd_set_ecclayout(&concat->mtd, subdev[0]->ecclayout);
 
concat->num_subdev = num_devs;
concat->mtd.name = name;
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 08de4b2..f53d9d7 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -533,7 +533,7 @@ static struct mtd_part *allocate_partition(struct mtd_info 
*master,
part->name);
}
 
-   slave->mtd.ecclayout = master->ecclayout;
+   mtd_set_ecclayout(&slave->mtd, master->ecclayout);
slave->mtd.ecc_step_size = master->ecc_step_size;
slave->mtd.ecc_strength = master->ecc_strength;
slave->mtd.bitflip_threshold = master->bitflip_threshold;
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 10/50] mtd: onenand: use mtd_ooblayout_xxx() helpers where appropriate

2016-03-30 Thread Boris Brezillon
The mtd_ooblayout_xxx() helper functions have been added to avoid direct
accesses to the ecclayout field, and thus ease for future reworks.
Use these helpers in all places where the oobfree[] and eccpos[] arrays
where directly accessed.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/onenand/onenand_base.c | 75 --
 1 file changed, 15 insertions(+), 60 deletions(-)

diff --git a/drivers/mtd/onenand/onenand_base.c 
b/drivers/mtd/onenand/onenand_base.c
index af28bb3..20fdf8c 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1024,34 +1024,15 @@ static int onenand_transfer_auto_oob(struct mtd_info 
*mtd, uint8_t *buf, int col
int thislen)
 {
struct onenand_chip *this = mtd->priv;
-   struct nand_oobfree *free;
-   int readcol = column;
-   int readend = column + thislen;
-   int lastgap = 0;
-   unsigned int i;
-   uint8_t *oob_buf = this->oob_buf;
-
-   free = this->ecclayout->oobfree;
-   for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
-   if (readcol >= lastgap)
-   readcol += free->offset - lastgap;
-   if (readend >= lastgap)
-   readend += free->offset - lastgap;
-   lastgap = free->offset + free->length;
-   }
-   this->read_bufferram(mtd, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
-   free = this->ecclayout->oobfree;
-   for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
-   int free_end = free->offset + free->length;
-   if (free->offset < readend && free_end > readcol) {
-   int st = max_t(int,free->offset,readcol);
-   int ed = min_t(int,free_end,readend);
-   int n = ed - st;
-   memcpy(buf, oob_buf + st, n);
-   buf += n;
-   } else if (column == 0)
-   break;
-   }
+   int ret;
+
+   this->read_bufferram(mtd, ONENAND_SPARERAM, this->oob_buf, 0,
+mtd->oobsize);
+   ret = mtd_ooblayout_get_databytes(mtd, buf, this->oob_buf,
+ column, thislen);
+   if (ret)
+   return ret;
+
return 0;
 }
 
@@ -1808,34 +1789,7 @@ static int onenand_panic_write(struct mtd_info *mtd, 
loff_t to, size_t len,
 static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
  const u_char *buf, int column, int thislen)
 {
-   struct onenand_chip *this = mtd->priv;
-   struct nand_oobfree *free;
-   int writecol = column;
-   int writeend = column + thislen;
-   int lastgap = 0;
-   unsigned int i;
-
-   free = this->ecclayout->oobfree;
-   for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
-   if (writecol >= lastgap)
-   writecol += free->offset - lastgap;
-   if (writeend >= lastgap)
-   writeend += free->offset - lastgap;
-   lastgap = free->offset + free->length;
-   }
-   free = this->ecclayout->oobfree;
-   for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
-   int free_end = free->offset + free->length;
-   if (free->offset < writeend && free_end > writecol) {
-   int st = max_t(int,free->offset,writecol);
-   int ed = min_t(int,free_end,writeend);
-   int n = ed - st;
-   memcpy(oob_buf + st, buf, n);
-   buf += n;
-   } else if (column == 0)
-   break;
-   }
-   return 0;
+   return mtd_ooblayout_set_databytes(mtd, buf, oob_buf, column, thislen);
 }
 
 /**
@@ -4037,10 +3991,11 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
 * The number of bytes available for a client to place data into
 * the out of band area
 */
-   mtd->oobavail = 0;
-   for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES &&
-   this->ecclayout->oobfree[i].length; i++)
-   mtd->oobavail += this->ecclayout->oobfree[i].length;
+   ret = mtd_ooblayout_count_freebytes(mtd);
+   if (ret < 0)
+   ret = 0;
+
+   mtd->oobavail = ret;
 
mtd->ecclayout = this->ecclayout;
mtd->ecc_strength = 1;
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 11/50] mtd: add mtd_set_ecclayout() helper function

2016-03-30 Thread Boris Brezillon
Add an mtd_set_ecclayout() helper function to avoid direct accesses to the
mtd->ecclayout field. This will ease future reworks of ECC layout
definition.

Signed-off-by: Boris Brezillon 
---
 include/linux/mtd/mtd.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index b141f26..6250dd8 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -286,6 +286,12 @@ int mtd_ooblayout_set_databytes(struct mtd_info *mtd, 
const u8 *databuf,
 int mtd_ooblayout_count_freebytes(struct mtd_info *mtd);
 int mtd_ooblayout_count_eccbytes(struct mtd_info *mtd);
 
+static inline void mtd_set_ecclayout(struct mtd_info *mtd,
+struct nand_ecclayout *ecclayout)
+{
+   mtd->ecclayout = ecclayout;
+}
+
 static inline void mtd_set_of_node(struct mtd_info *mtd,
   struct device_node *np)
 {
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 22/50] mtd: nand: atmel: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/atmel_nand.c | 84 ---
 1 file changed, 38 insertions(+), 46 deletions(-)

diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 321d331..46a601e 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -72,30 +72,44 @@ struct atmel_nand_nfc_caps {
uint32_t rb_mask;
 };
 
-/* oob layout for large page size
+/*
+ * oob layout for large page size
  * bad block info is on bytes 0 and 1
  * the bytes have to be consecutives to avoid
  * several NAND_CMD_RNDOUT during read
- */
-static struct nand_ecclayout atmel_oobinfo_large = {
-   .eccbytes = 4,
-   .eccpos = {60, 61, 62, 63},
-   .oobfree = {
-   {2, 58}
-   },
-};
-
-/* oob layout for small page size
+ *
+ * oob layout for small page size
  * bad block info is on bytes 4 and 5
  * the bytes have to be consecutives to avoid
  * several NAND_CMD_RNDOUT during read
  */
-static struct nand_ecclayout atmel_oobinfo_small = {
-   .eccbytes = 4,
-   .eccpos = {0, 1, 2, 3},
-   .oobfree = {
-   {6, 10}
-   },
+static int atmel_ooblayout_ecc_sp(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   if (section)
+   return -ERANGE;
+
+   oobregion->length = 4;
+   oobregion->offset = 0;
+
+   return 0;
+}
+
+static int atmel_ooblayout_free_sp(struct mtd_info *mtd, int section,
+  struct mtd_oob_region *oobregion)
+{
+   if (section)
+   return -ERANGE;
+
+   oobregion->offset = 6;
+   oobregion->length = mtd->oobsize - oobregion->offset;
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops atmel_ooblayout_sp_ops = {
+   .ecc = atmel_ooblayout_ecc_sp,
+   .free = atmel_ooblayout_free_sp,
 };
 
 struct atmel_nfc {
@@ -163,8 +177,6 @@ struct atmel_nand_host {
int *pmecc_delta;
 };
 
-static struct nand_ecclayout atmel_pmecc_oobinfo;
-
 /*
  * Enable NAND.
  */
@@ -483,22 +495,6 @@ static int pmecc_get_ecc_bytes(int cap, int sector_size)
return (m * cap + 7) / 8;
 }
 
-static void pmecc_config_ecc_layout(struct nand_ecclayout *layout,
-   int oobsize, int ecc_len)
-{
-   int i;
-
-   layout->eccbytes = ecc_len;
-
-   /* ECC will occupy the last ecc_len bytes continuously */
-   for (i = 0; i < ecc_len; i++)
-   layout->eccpos[i] = oobsize - ecc_len + i;
-
-   layout->oobfree[0].offset = PMECC_OOB_RESERVED_BYTES;
-   layout->oobfree[0].length =
-   oobsize - ecc_len - layout->oobfree[0].offset;
-}
-
 static void __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host)
 {
int table_size;
@@ -1013,8 +1009,8 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
 {
struct nand_chip *nand_chip = mtd_to_nand(mtd);
struct atmel_nand_host *host = nand_get_controller_data(nand_chip);
+   int eccbytes = mtd_ooblayout_count_eccbytes(mtd);
uint32_t val = 0;
-   struct nand_ecclayout *ecc_layout;
struct mtd_oob_region oobregion;
 
pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST);
@@ -1065,12 +1061,11 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
| PMECC_CFG_AUTO_DISABLE);
pmecc_writel(host->ecc, CFG, val);
 
-   ecc_layout = nand_chip->ecc.layout;
pmecc_writel(host->ecc, SAREA, mtd->oobsize - 1);
mtd_ooblayout_ecc(mtd, 0, &oobregion);
pmecc_writel(host->ecc, SADDR, oobregion.offset);
pmecc_writel(host->ecc, EADDR,
-oobregion.offset + ecc_layout->eccbytes - 1);
+oobregion.offset + eccbytes - 1);
/* See datasheet about PMECC Clock Control Register */
pmecc_writel(host->ecc, CLK, 2);
pmecc_writel(host->ecc, IDR, 0xff);
@@ -1292,11 +1287,8 @@ static int atmel_pmecc_nand_init_params(struct 
platform_device *pdev,
err_no = -EINVAL;
goto err;
}
-   pmecc_config_ecc_layout(&atmel_pmecc_oobinfo,
-   mtd->oobsize,
-   nand_chip->ecc.total);
 
-   nand_chip->ecc.layout = &atmel_pmecc_oobinfo;
+   mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops);
break;
default:
dev_warn(host->dev,
@@ -1644,19 +1636,19 @@ static int atmel_hw_nand_init_params(struct 
platform_device *pdev,
/* set ECC page size and oob layout */
switch (mtd->writesize) {
case 512:
-   nand_chip->ecc.layout = &atmel_oobinfo_small;
+   mtd_set_ooblayout(mtd, &atmel_ooblayout_sp_ops);
ecc_writel(ho

[PATCH v5 23/50] mtd: nand: bf5xx: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/bf5xx_nand.c | 51 ---
 1 file changed, 28 insertions(+), 23 deletions(-)

diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c
index 7f6b30e..b38f414 100644
--- a/drivers/mtd/nand/bf5xx_nand.c
+++ b/drivers/mtd/nand/bf5xx_nand.c
@@ -109,28 +109,33 @@ static const unsigned short bfin_nfc_pin_req[] =
 0};
 
 #ifdef CONFIG_MTD_NAND_BF5XX_BOOTROM_ECC
-static struct nand_ecclayout bootrom_ecclayout = {
-   .eccbytes = 24,
-   .eccpos = {
-   0x8 * 0, 0x8 * 0 + 1, 0x8 * 0 + 2,
-   0x8 * 1, 0x8 * 1 + 1, 0x8 * 1 + 2,
-   0x8 * 2, 0x8 * 2 + 1, 0x8 * 2 + 2,
-   0x8 * 3, 0x8 * 3 + 1, 0x8 * 3 + 2,
-   0x8 * 4, 0x8 * 4 + 1, 0x8 * 4 + 2,
-   0x8 * 5, 0x8 * 5 + 1, 0x8 * 5 + 2,
-   0x8 * 6, 0x8 * 6 + 1, 0x8 * 6 + 2,
-   0x8 * 7, 0x8 * 7 + 1, 0x8 * 7 + 2
-   },
-   .oobfree = {
-   { 0x8 * 0 + 3, 5 },
-   { 0x8 * 1 + 3, 5 },
-   { 0x8 * 2 + 3, 5 },
-   { 0x8 * 3 + 3, 5 },
-   { 0x8 * 4 + 3, 5 },
-   { 0x8 * 5 + 3, 5 },
-   { 0x8 * 6 + 3, 5 },
-   { 0x8 * 7 + 3, 5 },
-   }
+static int bootrom_ooblayout_ecc(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   if (section > 7)
+   return -ERANGE;
+
+   oobregion->offset = section * 8;
+   oobregion->length = 3;
+
+   return 0;
+}
+
+static int bootrom_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   if (section > 7)
+   return -ERANGE;
+
+   oobregion->offset = (section * 8) + 3;
+   oobregion->length = 5;
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops bootrom_ooblayout_ops = {
+   .ecc = bootrom_ooblayout_ecc,
+   .free = bootrom_ooblayout_free,
 };
 #endif
 
@@ -800,7 +805,7 @@ static int bf5xx_nand_probe(struct platform_device *pdev)
/* setup hardware ECC data struct */
if (hardware_ecc) {
 #ifdef CONFIG_MTD_NAND_BF5XX_BOOTROM_ECC
-   chip->ecc.layout = &bootrom_ecclayout;
+   mtd_set_ooblayout(mtd, &bootrom_ooblayout_ops);
 #endif
chip->read_buf  = bf5xx_nand_dma_read_buf;
chip->write_buf = bf5xx_nand_dma_write_buf;
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 18/50] mtd: nand: implement the default mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Replace the default nand_ecclayout definitions for large and small page
devices with the equivalent mtd_ooblayout_ops.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/nand_base.c | 148 ---
 include/linux/mtd/nand.h |   3 +
 2 files changed, 99 insertions(+), 52 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 295af79..3d6985e 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -48,50 +48,6 @@
 #include 
 #include 
 
-/* Define default oob placement schemes for large and small page devices */
-static struct nand_ecclayout nand_oob_8 = {
-   .eccbytes = 3,
-   .eccpos = {0, 1, 2},
-   .oobfree = {
-   {.offset = 3,
-.length = 2},
-   {.offset = 6,
-.length = 2} }
-};
-
-static struct nand_ecclayout nand_oob_16 = {
-   .eccbytes = 6,
-   .eccpos = {0, 1, 2, 3, 6, 7},
-   .oobfree = {
-   {.offset = 8,
-. length = 8} }
-};
-
-static struct nand_ecclayout nand_oob_64 = {
-   .eccbytes = 24,
-   .eccpos = {
-  40, 41, 42, 43, 44, 45, 46, 47,
-  48, 49, 50, 51, 52, 53, 54, 55,
-  56, 57, 58, 59, 60, 61, 62, 63},
-   .oobfree = {
-   {.offset = 2,
-.length = 38} }
-};
-
-static struct nand_ecclayout nand_oob_128 = {
-   .eccbytes = 48,
-   .eccpos = {
-  80, 81, 82, 83, 84, 85, 86, 87,
-  88, 89, 90, 91, 92, 93, 94, 95,
-  96, 97, 98, 99, 100, 101, 102, 103,
-  104, 105, 106, 107, 108, 109, 110, 111,
-  112, 113, 114, 115, 116, 117, 118, 119,
-  120, 121, 122, 123, 124, 125, 126, 127},
-   .oobfree = {
-   {.offset = 2,
-.length = 78} }
-};
-
 static int nand_get_device(struct mtd_info *mtd, int new_state);
 
 static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
@@ -103,6 +59,92 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t 
to,
  */
 DEFINE_LED_TRIGGER(nand_led_trigger);
 
+/* Define default oob placement schemes for large and small page devices */
+static int nand_ooblayout_ecc_sp(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   struct nand_ecc_ctrl *ecc = &chip->ecc;
+
+   if (section > 1)
+   return -ERANGE;
+
+   if (!section) {
+   oobregion->offset = 0;
+   oobregion->length = 4;
+   } else {
+   oobregion->offset = 6;
+   oobregion->length = ecc->total - 4;
+   }
+
+   return 0;
+}
+
+static int nand_ooblayout_free_sp(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   if (section > 1)
+   return -ERANGE;
+
+   if (mtd->oobsize == 16) {
+   if (section)
+   return -ERANGE;
+
+   oobregion->length = 8;
+   oobregion->offset = 8;
+   } else {
+   oobregion->length = 2;
+   if (!section)
+   oobregion->offset = 3;
+   else
+   oobregion->offset = 6;
+   }
+
+   return 0;
+}
+
+const struct mtd_ooblayout_ops nand_ooblayout_sp_ops = {
+   .ecc = nand_ooblayout_ecc_sp,
+   .free = nand_ooblayout_free_sp,
+};
+EXPORT_SYMBOL_GPL(nand_ooblayout_sp_ops);
+
+static int nand_ooblayout_ecc_lp(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   struct nand_ecc_ctrl *ecc = &chip->ecc;
+
+   if (section)
+   return -ERANGE;
+
+   oobregion->length = ecc->total;
+   oobregion->offset = mtd->oobsize - oobregion->length;
+
+   return 0;
+}
+
+static int nand_ooblayout_free_lp(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   struct nand_ecc_ctrl *ecc = &chip->ecc;
+
+   if (section)
+   return -ERANGE;
+
+   oobregion->length = mtd->oobsize - ecc->total - 2;
+   oobregion->offset = 2;
+
+   return 0;
+}
+
+const struct mtd_ooblayout_ops nand_ooblayout_lp_ops = {
+   .ecc = nand_ooblayout_ecc_lp,
+   .free = nand_ooblayout_free_lp,
+};
+EXPORT_SYMBOL_GPL(nand_ooblayout_lp_ops);
+
 static int check_offs_len(struct mtd_info *mtd,
loff_t ofs, uint64_t len)
 {
@@ -4120,21 +4162,24 @@ int nand_scan_tail(struct mtd_info *mtd)
chip->oob_poi = chip->buffers->databuf + mtd->writesize;
 
/*
+* Set the provided ECC layout. If ecc->layout is NULL, the MTD core
+* will just leave mtd->ooblayout t

[PATCH v5 21/50] mtd: nand: jz4740: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 arch/mips/include/asm/mach-jz4740/jz4740_nand.h |  2 +-
 arch/mips/jz4740/board-qi_lb60.c| 87 +++--
 drivers/mtd/nand/jz4740_nand.c  |  2 +-
 3 files changed, 53 insertions(+), 38 deletions(-)

diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h 
b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h
index 398733e..7f7b0fc 100644
--- a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h
+++ b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h
@@ -27,7 +27,7 @@ struct jz_nand_platform_data {
 
unsigned char banks[JZ_NAND_NUM_BANKS];
 
-   void (*ident_callback)(struct platform_device *, struct nand_chip *,
+   void (*ident_callback)(struct platform_device *, struct mtd_info *,
struct mtd_partition **, int *num_partitions);
 };
 
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
index 934b15b..a1c1afb 100644
--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -50,20 +50,6 @@ static bool is_avt2;
 #define QI_LB60_GPIO_KEYIN8JZ_GPIO_PORTD(26)
 
 /* NAND */
-static struct nand_ecclayout qi_lb60_ecclayout_1gb = {
-   .eccbytes = 36,
-   .eccpos = {
-   6,  7,  8,  9,  10, 11, 12, 13,
-   14, 15, 16, 17, 18, 19, 20, 21,
-   22, 23, 24, 25, 26, 27, 28, 29,
-   30, 31, 32, 33, 34, 35, 36, 37,
-   38, 39, 40, 41
-   },
-   .oobfree = {
-   { .offset = 2, .length = 4 },
-   { .offset = 42, .length = 22 }
-   },
-};
 
 /* Early prototypes of the QI LB60 had only 1GB of NAND.
  * In order to support these devices as well the partition and ecc layout is
@@ -86,25 +72,6 @@ static struct mtd_partition qi_lb60_partitions_1gb[] = {
},
 };
 
-static struct nand_ecclayout qi_lb60_ecclayout_2gb = {
-   .eccbytes = 72,
-   .eccpos = {
-   12, 13, 14, 15, 16, 17, 18, 19,
-   20, 21, 22, 23, 24, 25, 26, 27,
-   28, 29, 30, 31, 32, 33, 34, 35,
-   36, 37, 38, 39, 40, 41, 42, 43,
-   44, 45, 46, 47, 48, 49, 50, 51,
-   52, 53, 54, 55, 56, 57, 58, 59,
-   60, 61, 62, 63, 64, 65, 66, 67,
-   68, 69, 70, 71, 72, 73, 74, 75,
-   76, 77, 78, 79, 80, 81, 82, 83
-   },
-   .oobfree = {
-   { .offset = 2, .length = 10 },
-   { .offset = 84, .length = 44 },
-   },
-};
-
 static struct mtd_partition qi_lb60_partitions_2gb[] = {
{
.name = "NAND BOOT partition",
@@ -123,19 +90,67 @@ static struct mtd_partition qi_lb60_partitions_2gb[] = {
},
 };
 
+static int qi_lb60_ooblayout_ecc(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   if (section)
+   return -ERANGE;
+
+   oobregion->length = 36;
+   oobregion->offset = 6;
+
+   if (mtd->oobsize == 128) {
+   oobregion->length *= 2;
+   oobregion->offset *= 2;
+   }
+
+   return 0;
+}
+
+static int qi_lb60_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   int eccbytes = 36, eccoff = 6;
+
+   if (section > 1)
+   return -ERANGE;
+
+   if (mtd->oobsize == 128) {
+   eccbytes *= 2;
+   eccoff *= 2;
+   }
+
+   if (!section) {
+   oobregion->offset = 2;
+   oobregion->length = eccoff - 2;
+   } else {
+   oobregion->offset = eccoff + eccbytes;
+   oobregion->length = mtd->oobsize - oobregion->offset;
+   }
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops qi_lb60_ooblayout_ops = {
+   .ecc = qi_lb60_ooblayout_ecc,
+   .free = qi_lb60_ooblayout_free,
+};
+
 static void qi_lb60_nand_ident(struct platform_device *pdev,
-   struct nand_chip *chip, struct mtd_partition **partitions,
+   struct mtd_info *mtd, struct mtd_partition **partitions,
int *num_partitions)
 {
+   struct nand_chip *chip = mtd_to_nand(mtd);
+
if (chip->page_shift == 12) {
-   chip->ecc.layout = &qi_lb60_ecclayout_2gb;
*partitions = qi_lb60_partitions_2gb;
*num_partitions = ARRAY_SIZE(qi_lb60_partitions_2gb);
} else {
-   chip->ecc.layout = &qi_lb60_ecclayout_1gb;
*partitions = qi_lb60_partitions_1gb;
*num_partitions = ARRAY_SIZE(qi_lb60_partitions_1gb);
}
+
+   mtd_set_ooblayout(mtd, &qi_lb60_ooblayout_ops);
 }
 
 static struct jz_nand_platform_data qi_lb60_nand_pdata = {
diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c
index 673ceb2..df

[PATCH v5 17/50] mtd: docg3: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Replace the nand_ecclayout definition by the equivalent mtd_ooblayout_ops
definition.

Signed-off-by: Boris Brezillon 
Acked-by: Robert Jarzmik 
---
 drivers/mtd/devices/docg3.c | 46 ++---
 1 file changed, 35 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index 6b516e1..b833e6c 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -67,16 +67,40 @@ module_param(reliable_mode, uint, 0);
 MODULE_PARM_DESC(reliable_mode, "Set the docg3 mode (0=normal MLC, 1=fast, "
 "2=reliable) : MLC normal operations are in normal mode");
 
-/**
- * struct docg3_oobinfo - DiskOnChip G3 OOB layout
- * @eccbytes: 8 bytes are used (1 for Hamming ECC, 7 for BCH ECC)
- * @eccpos: ecc positions (byte 7 is Hamming ECC, byte 8-14 are BCH ECC)
- * @oobfree: free pageinfo bytes (byte 0 until byte 6, byte 15
- */
-static struct nand_ecclayout docg3_oobinfo = {
-   .eccbytes = 8,
-   .eccpos = {7, 8, 9, 10, 11, 12, 13, 14},
-   .oobfree = {{0, 7}, {15, 1} },
+static int docg3_ooblayout_ecc(struct mtd_info *mtd, int section,
+  struct mtd_oob_region *oobregion)
+{
+   if (section)
+   return -ERANGE;
+
+   /* byte 7 is Hamming ECC, byte 8-14 are BCH ECC */
+   oobregion->offset = 7;
+   oobregion->length = 8;
+
+   return 0;
+}
+
+static int docg3_ooblayout_free(struct mtd_info *mtd, int section,
+   struct mtd_oob_region *oobregion)
+{
+   if (section > 1)
+   return -ERANGE;
+
+   /* free bytes: byte 0 until byte 6, byte 15 */
+   if (!section) {
+   oobregion->offset = 0;
+   oobregion->length = 7;
+   } else {
+   oobregion->offset = 15;
+   oobregion->length = 1;
+   }
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops nand_ooblayout_docg3_ops = {
+   .ecc = docg3_ooblayout_ecc,
+   .free = docg3_ooblayout_free,
 };
 
 static inline u8 doc_readb(struct docg3 *docg3, u16 reg)
@@ -1857,7 +1881,7 @@ static int __init doc_set_driver_info(int chip_id, struct 
mtd_info *mtd)
mtd->_read_oob = doc_read_oob;
mtd->_write_oob = doc_write_oob;
mtd->_block_isbad = doc_block_isbad;
-   mtd_set_ecclayout(mtd, &docg3_oobinfo);
+   mtd_set_ooblayout(mtd, &nand_ooblayout_docg3_ops);
mtd->oobavail = 8;
mtd->ecc_strength = DOC_ECC_BCH_T;
 
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 26/50] mtd: nand: davinci: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/davinci_nand.c | 118 +++-
 1 file changed, 44 insertions(+), 74 deletions(-)

diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 8cb821b..fe3fd29 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -54,7 +54,6 @@
  */
 struct davinci_nand_info {
struct nand_chipchip;
-   struct nand_ecclayout   ecclayout;
 
struct device   *dev;
struct clk  *clk;
@@ -480,63 +479,46 @@ static int nand_davinci_dev_ready(struct mtd_info *mtd)
  * ten ECC bytes plus the manufacturer's bad block marker byte, and
  * and not overlapping the default BBT markers.
  */
-static struct nand_ecclayout hwecc4_small = {
-   .eccbytes = 10,
-   .eccpos = { 0, 1, 2, 3, 4,
-   /* offset 5 holds the badblock marker */
-   6, 7,
-   13, 14, 15, },
-   .oobfree = {
-   {.offset = 8, .length = 5, },
-   {.offset = 16, },
-   },
-};
+static int hwecc4_ooblayout_small_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   if (section > 2)
+   return -ERANGE;
+
+   if (!section) {
+   oobregion->offset = 0;
+   oobregion->length = 5;
+   } else if (section == 1) {
+   oobregion->offset = 6;
+   oobregion->length = 2;
+   } else {
+   oobregion->offset = 13;
+   oobregion->length = 3;
+   }
 
-/* An ECC layout for using 4-bit ECC with large-page (2048bytes) flash,
- * storing ten ECC bytes plus the manufacturer's bad block marker byte,
- * and not overlapping the default BBT markers.
- */
-static struct nand_ecclayout hwecc4_2048 = {
-   .eccbytes = 40,
-   .eccpos = {
-   /* at the end of spare sector */
-   24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
-   34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
-   44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
-   54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-   },
-   .oobfree = {
-   /* 2 bytes at offset 0 hold manufacturer badblock markers */
-   {.offset = 2, .length = 22, },
-   /* 5 bytes at offset 8 hold BBT markers */
-   /* 8 bytes at offset 16 hold JFFS2 clean markers */
-   },
-};
+   return 0;
+}
 
-/*
- * An ECC layout for using 4-bit ECC with large-page (4096bytes) flash,
- * storing ten ECC bytes plus the manufacturer's bad block marker byte,
- * and not overlapping the default BBT markers.
- */
-static struct nand_ecclayout hwecc4_4096 = {
-   .eccbytes = 80,
-   .eccpos = {
-   /* at the end of spare sector */
-   48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
-   58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
-   68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
-   78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
-   88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
-   98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
-   108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
-   118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-   },
-   .oobfree = {
-   /* 2 bytes at offset 0 hold manufacturer badblock markers */
-   {.offset = 2, .length = 46, },
-   /* 5 bytes at offset 8 hold BBT markers */
-   /* 8 bytes at offset 16 hold JFFS2 clean markers */
-   },
+static int hwecc4_ooblayout_small_free(struct mtd_info *mtd, int section,
+  struct mtd_oob_region *oobregion)
+{
+   if (section > 1)
+   return -ERANGE;
+
+   if (!section) {
+   oobregion->offset = 8;
+   oobregion->length = 5;
+   } else {
+   oobregion->offset = 16;
+   oobregion->length = mtd->oobsize - 16;
+   }
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops hwecc4_small_ooblayout_ops = {
+   .ecc = hwecc4_ooblayout_small_ecc,
+   .free = hwecc4_ooblayout_small_free,
 };
 
 #if defined(CONFIG_OF)
@@ -805,26 +787,14 @@ static int nand_davinci_probe(struct platform_device 
*pdev)
 * table marker fits in the free bytes.
 */
if (chunks == 1) {
-   info->ecclayout = hwecc4_small;
-   info->ecclayout.oobfree[1].length = mtd->oobsize - 16;
-   goto syndrome_done;
-   }
-   if (chunks == 4) {
-   info->ecclayout = hwecc4_2048;
+   mtd_set_ooblayout(mtd, &hwecc4_small_ooblayout_ops);
+   } else if (chunks == 4 || chunks == 8) {
+  

[PATCH v5 13/50] mtd: nand: use mtd_set_ecclayout() where appropriate

2016-03-30 Thread Boris Brezillon
Use the mtd_set_ecclayout() helper instead of directly assigning the
mtd->ecclayout field.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/nand_base.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 36a58a0..295af79 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -4288,7 +4288,7 @@ int nand_scan_tail(struct mtd_info *mtd)
ecc->write_oob_raw = ecc->write_oob;
 
/* propagate ecc info to mtd_info */
-   mtd->ecclayout = ecc->layout;
+   mtd_set_ecclayout(mtd, ecc->layout);
mtd->ecc_strength = ecc->strength;
mtd->ecc_step_size = ecc->size;
 
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 25/50] mtd: nand: cafe: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/cafe_nand.c | 44 
 1 file changed, 32 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c
index e553aff..0b0c937 100644
--- a/drivers/mtd/nand/cafe_nand.c
+++ b/drivers/mtd/nand/cafe_nand.c
@@ -459,10 +459,37 @@ static int cafe_nand_read_page(struct mtd_info *mtd, 
struct nand_chip *chip,
return max_bitflips;
 }
 
-static struct nand_ecclayout cafe_oobinfo_2048 = {
-   .eccbytes = 14,
-   .eccpos = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13},
-   .oobfree = {{14, 50}}
+static int cafe_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+
+   if (section)
+   return -ERANGE;
+
+   oobregion->offset = 0;
+   oobregion->length = chip->ecc.total;
+
+   return 0;
+}
+
+static int cafe_ooblayout_free(struct mtd_info *mtd, int section,
+  struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+
+   if (section)
+   return -ERANGE;
+
+   oobregion->offset = chip->ecc.total;
+   oobregion->length = mtd->oobsize - chip->ecc.total;
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops cafe_ooblayout_ops = {
+   .ecc = cafe_ooblayout_ecc,
+   .free = cafe_ooblayout_free,
 };
 
 /* Ick. The BBT code really ought to be able to work this bit out
@@ -494,12 +521,6 @@ static struct nand_bbt_descr cafe_bbt_mirror_descr_2048 = {
.pattern = cafe_mirror_pattern_2048
 };
 
-static struct nand_ecclayout cafe_oobinfo_512 = {
-   .eccbytes = 14,
-   .eccpos = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13},
-   .oobfree = {{14, 2}}
-};
-
 static struct nand_bbt_descr cafe_bbt_main_descr_512 = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
| NAND_BBT_2BIT | NAND_BBT_VERSION,
@@ -743,12 +764,11 @@ static int cafe_nand_probe(struct pci_dev *pdev,
cafe->ctl2 |= 1<<29; /* 2KiB page size */
 
/* Set up ECC according to the type of chip we found */
+   mtd_set_ooblayout(mtd, &cafe_ooblayout_ops);
if (mtd->writesize == 2048) {
-   cafe->nand.ecc.layout = &cafe_oobinfo_2048;
cafe->nand.bbt_td = &cafe_bbt_main_descr_2048;
cafe->nand.bbt_md = &cafe_bbt_mirror_descr_2048;
} else if (mtd->writesize == 512) {
-   cafe->nand.ecc.layout = &cafe_oobinfo_512;
cafe->nand.bbt_td = &cafe_bbt_main_descr_512;
cafe->nand.bbt_md = &cafe_bbt_mirror_descr_512;
} else {
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 32/50] mtd: nand: fsmc: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/fsmc_nand.c | 298 ---
 1 file changed, 82 insertions(+), 216 deletions(-)

diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index 1bdcd4f..275a98c 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -39,212 +39,6 @@
 #include 
 #include 
 
-static struct nand_ecclayout fsmc_ecc1_128_layout = {
-   .eccbytes = 24,
-   .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52,
-   66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116},
-   .oobfree = {
-   {.offset = 8, .length = 8},
-   {.offset = 24, .length = 8},
-   {.offset = 40, .length = 8},
-   {.offset = 56, .length = 8},
-   {.offset = 72, .length = 8},
-   {.offset = 88, .length = 8},
-   {.offset = 104, .length = 8},
-   {.offset = 120, .length = 8}
-   }
-};
-
-static struct nand_ecclayout fsmc_ecc1_64_layout = {
-   .eccbytes = 12,
-   .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52},
-   .oobfree = {
-   {.offset = 8, .length = 8},
-   {.offset = 24, .length = 8},
-   {.offset = 40, .length = 8},
-   {.offset = 56, .length = 8},
-   }
-};
-
-static struct nand_ecclayout fsmc_ecc1_16_layout = {
-   .eccbytes = 3,
-   .eccpos = {2, 3, 4},
-   .oobfree = {
-   {.offset = 8, .length = 8},
-   }
-};
-
-/*
- * ECC4 layout for NAND of pagesize 8192 bytes & OOBsize 256 bytes. 13*16 bytes
- * of OB size is reserved for ECC, Byte no. 0 & 1 reserved for bad block and 46
- * bytes are free for use.
- */
-static struct nand_ecclayout fsmc_ecc4_256_layout = {
-   .eccbytes = 208,
-   .eccpos = {  2,   3,   4,   5,   6,   7,   8,
-   9,  10,  11,  12,  13,  14,
-   18,  19,  20,  21,  22,  23,  24,
-   25,  26,  27,  28,  29,  30,
-   34,  35,  36,  37,  38,  39,  40,
-   41,  42,  43,  44,  45,  46,
-   50,  51,  52,  53,  54,  55,  56,
-   57,  58,  59,  60,  61,  62,
-   66,  67,  68,  69,  70,  71,  72,
-   73,  74,  75,  76,  77,  78,
-   82,  83,  84,  85,  86,  87,  88,
-   89,  90,  91,  92,  93,  94,
-   98,  99, 100, 101, 102, 103, 104,
-   105, 106, 107, 108, 109, 110,
-   114, 115, 116, 117, 118, 119, 120,
-   121, 122, 123, 124, 125, 126,
-   130, 131, 132, 133, 134, 135, 136,
-   137, 138, 139, 140, 141, 142,
-   146, 147, 148, 149, 150, 151, 152,
-   153, 154, 155, 156, 157, 158,
-   162, 163, 164, 165, 166, 167, 168,
-   169, 170, 171, 172, 173, 174,
-   178, 179, 180, 181, 182, 183, 184,
-   185, 186, 187, 188, 189, 190,
-   194, 195, 196, 197, 198, 199, 200,
-   201, 202, 203, 204, 205, 206,
-   210, 211, 212, 213, 214, 215, 216,
-   217, 218, 219, 220, 221, 222,
-   226, 227, 228, 229, 230, 231, 232,
-   233, 234, 235, 236, 237, 238,
-   242, 243, 244, 245, 246, 247, 248,
-   249, 250, 251, 252, 253, 254
-   },
-   .oobfree = {
-   {.offset = 15, .length = 3},
-   {.offset = 31, .length = 3},
-   {.offset = 47, .length = 3},
-   {.offset = 63, .length = 3},
-   {.offset = 79, .length = 3},
-   {.offset = 95, .length = 3},
-   {.offset = 111, .length = 3},
-   {.offset = 127, .length = 3},
-   {.offset = 143, .length = 3},
-   {.offset = 159, .length = 3},
-   {.offset = 175, .length = 3},
-   {.offset = 191, .length = 3},
-   {.offset = 207, .length = 3},
-   {.offset = 223, .length = 3},
-   {.offset = 239, .length = 3},
-   {.offset = 255, .length = 1}
-   }
-};
-
-/*
- * ECC4 layout for NAND of pagesize 4096 bytes & OOBsize 224 bytes. 13*8 bytes
- * of OOB size is reserved for ECC, Byte no. 0 & 1 reserved for bad block & 118
- * bytes are free for use.
- */
-static struct nand_ecclayout fsmc_ecc4_224_layout = {
-   .eccbytes = 104,
-   .eccpos = {  2,   3,   4,   5,   6,   7,   8,
-   9,  10,  11,  12,  13,  14,
-   18,  19,  20,  21,  22,  23,  24,
-   25,  26,  27,  28,  29,  30,
-   34,  35,  36,  37,  38,  39,  40,
-   41,  42,  43,  44,  45,  46,
-   50,  51,  52,  53,  54,  55,  56,
-   57,  58,  59,  60,  61,  62,
-   66,  67,  68,  69,  70,  71,  72,
-   73,  74,  75,  76,  77,  78,
-  

[PATCH v5 24/50] mtd: nand: brcm: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/brcmnand/brcmnand.c | 258 +--
 1 file changed, 157 insertions(+), 101 deletions(-)

diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c 
b/drivers/mtd/nand/brcmnand/brcmnand.c
index e052839..4c3c0a9 100644
--- a/drivers/mtd/nand/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/brcmnand/brcmnand.c
@@ -781,127 +781,183 @@ static inline bool is_hamming_ecc(struct brcmnand_cfg 
*cfg)
 }
 
 /*
- * Returns a nand_ecclayout strucutre for the given layout/configuration.
- * Returns NULL on failure.
+ * Set mtd->ooblayout to the appropriate mtd_ooblayout_ops given
+ * the layout/configuration.
+ * Returns -ERRCODE on failure.
  */
-static struct nand_ecclayout *brcmnand_create_layout(int ecc_level,
-struct brcmnand_host *host)
+static int brcmnand_hamming_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
 {
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   struct brcmnand_host *host = nand_get_controller_data(chip);
struct brcmnand_cfg *cfg = &host->hwcfg;
-   int i, j;
-   struct nand_ecclayout *layout;
-   int req;
-   int sectors;
-   int sas;
-   int idx1, idx2;
-
-   layout = devm_kzalloc(&host->pdev->dev, sizeof(*layout), GFP_KERNEL);
-   if (!layout)
-   return NULL;
-
-   sectors = cfg->page_size / (512 << cfg->sector_size_1k);
-   sas = cfg->spare_area_size << cfg->sector_size_1k;
-
-   /* Hamming */
-   if (is_hamming_ecc(cfg)) {
-   for (i = 0, idx1 = 0, idx2 = 0; i < sectors; i++) {
-   /* First sector of each page may have BBI */
-   if (i == 0) {
-   layout->oobfree[idx2].offset = i * sas + 1;
-   /* Small-page NAND use byte 6 for BBI */
-   if (cfg->page_size == 512)
-   layout->oobfree[idx2].offset--;
-   layout->oobfree[idx2].length = 5;
-   } else {
-   layout->oobfree[idx2].offset = i * sas;
-   layout->oobfree[idx2].length = 6;
-   }
-   idx2++;
-   layout->eccpos[idx1++] = i * sas + 6;
-   layout->eccpos[idx1++] = i * sas + 7;
-   layout->eccpos[idx1++] = i * sas + 8;
-   layout->oobfree[idx2].offset = i * sas + 9;
-   layout->oobfree[idx2].length = 7;
-   idx2++;
-   /* Leave zero-terminated entry for OOBFREE */
-   if (idx1 >= MTD_MAX_ECCPOS_ENTRIES_LARGE ||
-   idx2 >= MTD_MAX_OOBFREE_ENTRIES_LARGE - 1)
-   break;
-   }
+   int sas = cfg->spare_area_size << cfg->sector_size_1k;
+   int sectors = cfg->page_size / (512 << cfg->sector_size_1k);
 
-   return layout;
-   }
+   if (section >= sectors)
+   return -ERANGE;
 
-   /*
-* CONTROLLER_VERSION:
-*   < v5.0: ECC_REQ = ceil(BCH_T * 13/8)
-*  >= v5.0: ECC_REQ = ceil(BCH_T * 14/8)
-* But we will just be conservative.
-*/
-   req = DIV_ROUND_UP(ecc_level * 14, 8);
-   if (req >= sas) {
-   dev_err(&host->pdev->dev,
-   "error: ECC too large for OOB (ECC bytes %d, spare 
sector %d)\n",
-   req, sas);
-   return NULL;
-   }
+   oobregion->offset = (section * sas) + 6;
+   oobregion->length = 3;
+
+   return 0;
+}
+
+static int brcmnand_hamming_ooblayout_free(struct mtd_info *mtd, int section,
+  struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   struct brcmnand_host *host = nand_get_controller_data(chip);
+   struct brcmnand_cfg *cfg = &host->hwcfg;
+   int sas = cfg->spare_area_size << cfg->sector_size_1k;
+   int sectors = cfg->page_size / (512 << cfg->sector_size_1k);
+
+   if (section >= sectors * 2)
+   return -ERANGE;
 
-   layout->eccbytes = req * sectors;
-   for (i = 0, idx1 = 0, idx2 = 0; i < sectors; i++) {
-   for (j = sas - req; j < sas && idx1 <
-   MTD_MAX_ECCPOS_ENTRIES_LARGE; j++, idx1++)
-   layout->eccpos[idx1] = i * sas + j;
+   oobregion->offset = (section / 2) * sas;
+
+   if (section & 1) {
+   oobregion->offset += 9;
+   oobregion->length = 7;
+   } else {
+   oobregion->length = 6;
 
/* First sector

[PATCH v5 14/50] mtd: onenand: use mtd_set_ecclayout() where appropriate

2016-03-30 Thread Boris Brezillon
Use the mtd_set_ecclayout() helper instead of directly assigning the
mtd->ecclayout field.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/onenand/onenand_base.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/onenand/onenand_base.c 
b/drivers/mtd/onenand/onenand_base.c
index 20fdf8c..d0fa505 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -3997,7 +3997,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
 
mtd->oobavail = ret;
 
-   mtd->ecclayout = this->ecclayout;
+   mtd_set_ecclayout(mtd, this->ecclayout);
mtd->ecc_strength = 1;
 
/* Fill in remaining MTD driver data */
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 30/50] mtd: nand: fsl_elbc: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/fsl_elbc_nand.c | 83 +++-
 1 file changed, 47 insertions(+), 36 deletions(-)

diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 059d5f7..487eae0 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -79,32 +79,53 @@ struct fsl_elbc_fcm_ctrl {
 
 /* These map to the positions used by the FCM hardware ECC generator */
 
-/* Small Page FLASH with FMR[ECCM] = 0 */
-static struct nand_ecclayout fsl_elbc_oob_sp_eccm0 = {
-   .eccbytes = 3,
-   .eccpos = {6, 7, 8},
-   .oobfree = { {0, 5}, {9, 7} },
-};
+static int fsl_elbc_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   struct fsl_elbc_mtd *priv = nand_get_controller_data(chip);
 
-/* Small Page FLASH with FMR[ECCM] = 1 */
-static struct nand_ecclayout fsl_elbc_oob_sp_eccm1 = {
-   .eccbytes = 3,
-   .eccpos = {8, 9, 10},
-   .oobfree = { {0, 5}, {6, 2}, {11, 5} },
-};
+   if (section >= chip->ecc.steps)
+   return -ERANGE;
 
-/* Large Page FLASH with FMR[ECCM] = 0 */
-static struct nand_ecclayout fsl_elbc_oob_lp_eccm0 = {
-   .eccbytes = 12,
-   .eccpos = {6, 7, 8, 22, 23, 24, 38, 39, 40, 54, 55, 56},
-   .oobfree = { {1, 5}, {9, 13}, {25, 13}, {41, 13}, {57, 7} },
-};
+   oobregion->offset = (16 * section) + 6;
+   if (priv->fmr & FMR_ECCM)
+   oobregion->offset += 2;
 
-/* Large Page FLASH with FMR[ECCM] = 1 */
-static struct nand_ecclayout fsl_elbc_oob_lp_eccm1 = {
-   .eccbytes = 12,
-   .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58},
-   .oobfree = { {1, 7}, {11, 13}, {27, 13}, {43, 13}, {59, 5} },
+   oobregion->length = chip->ecc.bytes;
+
+   return 0;
+}
+
+static int fsl_elbc_ooblayout_free(struct mtd_info *mtd, int section,
+  struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   struct fsl_elbc_mtd *priv = nand_get_controller_data(chip);
+
+   if (section > chip->ecc.steps)
+   return -ERANGE;
+
+   if (!section) {
+   oobregion->offset = 0;
+   if (mtd->writesize > 512)
+   oobregion->offset++;
+   oobregion->length = (priv->fmr & FMR_ECCM) ? 7 : 5;
+   } else {
+   oobregion->offset = (16 * section) -
+   ((priv->fmr & FMR_ECCM) ? 5 : 7);
+   if (section < chip->ecc.steps)
+   oobregion->length = 13;
+   else
+   oobregion->length = mtd->oobsize - oobregion->offset;
+   }
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops fsl_elbc_ooblayout_ops = {
+   .ecc = fsl_elbc_ooblayout_ecc,
+   .free = fsl_elbc_ooblayout_free,
 };
 
 /*
@@ -657,8 +678,8 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
chip->ecc.bytes);
dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.total = %d\n",
chip->ecc.total);
-   dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.layout = %p\n",
-   chip->ecc.layout);
+   dev_dbg(priv->dev, "fsl_elbc_init: mtd->ooblayout = %p\n",
+   mtd->ooblayout);
dev_dbg(priv->dev, "fsl_elbc_init: mtd->flags = %08x\n", mtd->flags);
dev_dbg(priv->dev, "fsl_elbc_init: mtd->size = %lld\n", mtd->size);
dev_dbg(priv->dev, "fsl_elbc_init: mtd->erasesize = %d\n",
@@ -675,14 +696,6 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
} else if (mtd->writesize == 2048) {
priv->page_size = 1;
setbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS);
-   /* adjust ecc setup if needed */
-   if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) ==
-   BR_DECC_CHK_GEN) {
-   chip->ecc.size = 512;
-   chip->ecc.layout = (priv->fmr & FMR_ECCM) ?
-  &fsl_elbc_oob_lp_eccm1 :
-  &fsl_elbc_oob_lp_eccm0;
-   }
} else {
dev_err(priv->dev,
"fsl_elbc_init: page size %d is not supported\n",
@@ -780,9 +793,7 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) ==
BR_DECC_CHK_GEN) {
chip->ecc.mode = NAND_ECC_HW;
-   /* put in small page settings and adjust later if needed */
-   chip->ecc.layout = (priv->fmr & FMR_ECCM) ?
-   &fsl_elbc_oob_sp_eccm1 : &fsl_elbc_oob_sp_eccm0;
+   mtd_set_ooblayout(mtd, &

[PATCH v5 19/50] mtd: nand: bch: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Replace the nand_ecclayout definition by the equivalent mtd_ooblayout_ops
definition.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/nand_bch.c | 33 +++--
 1 file changed, 11 insertions(+), 22 deletions(-)

diff --git a/drivers/mtd/nand/nand_bch.c b/drivers/mtd/nand/nand_bch.c
index b3039de..e29e75f 100644
--- a/drivers/mtd/nand/nand_bch.c
+++ b/drivers/mtd/nand/nand_bch.c
@@ -32,13 +32,11 @@
 /**
  * struct nand_bch_control - private NAND BCH control structure
  * @bch:   BCH control structure
- * @ecclayout: private ecc layout for this BCH configuration
  * @errloc:error location array
  * @eccmask:   XOR ecc mask, allows erased pages to be decoded as valid
  */
 struct nand_bch_control {
struct bch_control   *bch;
-   struct nand_ecclayout ecclayout;
unsigned int *errloc;
unsigned char*eccmask;
 };
@@ -124,7 +122,6 @@ struct nand_bch_control *nand_bch_init(struct mtd_info *mtd)
 {
struct nand_chip *nand = mtd_to_nand(mtd);
unsigned int m, t, eccsteps, i;
-   struct nand_ecclayout *layout = nand->ecc.layout;
struct nand_bch_control *nbc = NULL;
unsigned char *erased_page;
unsigned int eccsize = nand->ecc.size;
@@ -161,8 +158,17 @@ struct nand_bch_control *nand_bch_init(struct mtd_info 
*mtd)
 
eccsteps = mtd->writesize/eccsize;
 
+   /*
+* Rely on the default ecclayout to ooblayout wrapper provided by MTD
+* core if ecc.layout is not NULL.
+* FIXME: this should be removed when all callers have moved to the
+* mtd_ooblayout_ops approach.
+*/
+   if (nand->ecc.layout)
+   mtd_set_ecclayout(mtd, nand->ecc.layout);
+
/* if no ecc placement scheme was provided, build one */
-   if (!layout) {
+   if (!mtd->ooblayout) {
 
/* handle large page devices only */
if (mtd->oobsize < 64) {
@@ -171,24 +177,7 @@ struct nand_bch_control *nand_bch_init(struct mtd_info 
*mtd)
goto fail;
}
 
-   layout = &nbc->ecclayout;
-   layout->eccbytes = eccsteps*eccbytes;
-
-   /* reserve 2 bytes for bad block marker */
-   if (layout->eccbytes+2 > mtd->oobsize) {
-   printk(KERN_WARNING "no suitable oob scheme available "
-  "for oobsize %d eccbytes %u\n", mtd->oobsize,
-  eccbytes);
-   goto fail;
-   }
-   /* put ecc bytes at oob tail */
-   for (i = 0; i < layout->eccbytes; i++)
-   layout->eccpos[i] = mtd->oobsize-layout->eccbytes+i;
-
-   layout->oobfree[0].offset = 2;
-   layout->oobfree[0].length = mtd->oobsize-2-layout->eccbytes;
-
-   nand->ecc.layout = layout;
+   mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops);
}
 
/* sanity checks */
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 34/50] mtd: nand: gpmi: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 52 ++
 1 file changed, 40 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c 
b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 3a29b65..316b5ac 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -47,10 +47,44 @@ static struct nand_bbt_descr gpmi_bbt_descr = {
  * We may change the layout if we can get the ECC info from the datasheet,
  * else we will use all the (page + OOB).
  */
-static struct nand_ecclayout gpmi_hw_ecclayout = {
-   .eccbytes = 0,
-   .eccpos = { 0, },
-   .oobfree = { {.offset = 0, .length = 0} }
+static int gpmi_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   struct gpmi_nand_data *this = nand_get_controller_data(chip);
+   struct bch_geometry *geo = &this->bch_geometry;
+
+   if (section)
+   return -ERANGE;
+
+   oobregion->offset = 0;
+   oobregion->length = geo->page_size - mtd->writesize;
+
+   return 0;
+}
+
+static int gpmi_ooblayout_free(struct mtd_info *mtd, int section,
+  struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   struct gpmi_nand_data *this = nand_get_controller_data(chip);
+   struct bch_geometry *geo = &this->bch_geometry;
+
+   if (section)
+   return -ERANGE;
+
+   /* The available oob size we have. */
+   if (geo->page_size < mtd->writesize + mtd->oobsize) {
+   oobregion->offset = geo->page_size - mtd->writesize;
+   oobregion->length = mtd->oobsize - oobregion->offset;
+   }
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops gpmi_ooblayout_ops = {
+   .ecc = gpmi_ooblayout_ecc,
+   .free = gpmi_ooblayout_free,
 };
 
 static const struct gpmi_devdata gpmi_devdata_imx23 = {
@@ -141,7 +175,6 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data 
*this)
struct bch_geometry *geo = &this->bch_geometry;
struct nand_chip *chip = &this->nand;
struct mtd_info *mtd = nand_to_mtd(chip);
-   struct nand_oobfree *of = gpmi_hw_ecclayout.oobfree;
unsigned int block_mark_bit_offset;
 
if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0))
@@ -229,12 +262,6 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data 
*this)
geo->page_size = mtd->writesize + geo->metadata_size +
(geo->gf_len * geo->ecc_strength * geo->ecc_chunk_count) / 8;
 
-   /* The available oob size we have. */
-   if (geo->page_size < mtd->writesize + mtd->oobsize) {
-   of->offset = geo->page_size - mtd->writesize;
-   of->length = mtd->oobsize - of->offset;
-   }
-
geo->payload_size = mtd->writesize;
 
geo->auxiliary_status_offset = ALIGN(geo->metadata_size, 4);
@@ -1841,6 +1868,7 @@ static void gpmi_nand_exit(struct gpmi_nand_data *this)
 static int gpmi_init_last(struct gpmi_nand_data *this)
 {
struct nand_chip *chip = &this->nand;
+   struct mtd_info *mtd = nand_to_mtd(chip);
struct nand_ecc_ctrl *ecc = &chip->ecc;
struct bch_geometry *bch_geo = &this->bch_geometry;
int ret;
@@ -1862,7 +1890,7 @@ static int gpmi_init_last(struct gpmi_nand_data *this)
ecc->mode   = NAND_ECC_HW;
ecc->size   = bch_geo->ecc_chunk_size;
ecc->strength   = bch_geo->ecc_strength;
-   ecc->layout = &gpmi_hw_ecclayout;
+   mtd_set_ooblayout(mtd, &gpmi_ooblayout_ops);
 
/*
 * We only enable the subpage read when:
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 38/50] mtd: nand: mxc: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/mxc_nand.c | 212 ++--
 1 file changed, 105 insertions(+), 107 deletions(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 854c832..628f834 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -149,7 +149,7 @@ struct mxc_nand_devtype_data {
int (*check_int)(struct mxc_nand_host *);
void (*irq_control)(struct mxc_nand_host *, int);
u32 (*get_ecc_status)(struct mxc_nand_host *);
-   struct nand_ecclayout *ecclayout_512, *ecclayout_2k, *ecclayout_4k;
+   const struct mtd_ooblayout_ops *ooblayout;
void (*select_chip)(struct mtd_info *mtd, int chip);
int (*correct_data)(struct mtd_info *mtd, u_char *dat,
u_char *read_ecc, u_char *calc_ecc);
@@ -200,73 +200,6 @@ struct mxc_nand_host {
struct mxc_nand_platform_data pdata;
 };
 
-/* OOB placement block for use with hardware ecc generation */
-static struct nand_ecclayout nandv1_hw_eccoob_smallpage = {
-   .eccbytes = 5,
-   .eccpos = {6, 7, 8, 9, 10},
-   .oobfree = {{0, 5}, {12, 4}, }
-};
-
-static struct nand_ecclayout nandv1_hw_eccoob_largepage = {
-   .eccbytes = 20,
-   .eccpos = {6, 7, 8, 9, 10, 22, 23, 24, 25, 26,
-  38, 39, 40, 41, 42, 54, 55, 56, 57, 58},
-   .oobfree = {{2, 4}, {11, 10}, {27, 10}, {43, 10}, {59, 5}, }
-};
-
-/* OOB description for 512 byte pages with 16 byte OOB */
-static struct nand_ecclayout nandv2_hw_eccoob_smallpage = {
-   .eccbytes = 1 * 9,
-   .eccpos = {
-7,  8,  9, 10, 11, 12, 13, 14, 15
-   },
-   .oobfree = {
-   {.offset = 0, .length = 5}
-   }
-};
-
-/* OOB description for 2048 byte pages with 64 byte OOB */
-static struct nand_ecclayout nandv2_hw_eccoob_largepage = {
-   .eccbytes = 4 * 9,
-   .eccpos = {
-7,  8,  9, 10, 11, 12, 13, 14, 15,
-   23, 24, 25, 26, 27, 28, 29, 30, 31,
-   39, 40, 41, 42, 43, 44, 45, 46, 47,
-   55, 56, 57, 58, 59, 60, 61, 62, 63
-   },
-   .oobfree = {
-   {.offset = 2, .length = 4},
-   {.offset = 16, .length = 7},
-   {.offset = 32, .length = 7},
-   {.offset = 48, .length = 7}
-   }
-};
-
-/* OOB description for 4096 byte pages with 128 byte OOB */
-static struct nand_ecclayout nandv2_hw_eccoob_4k = {
-   .eccbytes = 8 * 9,
-   .eccpos = {
-   7,  8,  9, 10, 11, 12, 13, 14, 15,
-   23, 24, 25, 26, 27, 28, 29, 30, 31,
-   39, 40, 41, 42, 43, 44, 45, 46, 47,
-   55, 56, 57, 58, 59, 60, 61, 62, 63,
-   71, 72, 73, 74, 75, 76, 77, 78, 79,
-   87, 88, 89, 90, 91, 92, 93, 94, 95,
-   103, 104, 105, 106, 107, 108, 109, 110, 111,
-   119, 120, 121, 122, 123, 124, 125, 126, 127,
-   },
-   .oobfree = {
-   {.offset = 2, .length = 4},
-   {.offset = 16, .length = 7},
-   {.offset = 32, .length = 7},
-   {.offset = 48, .length = 7},
-   {.offset = 64, .length = 7},
-   {.offset = 80, .length = 7},
-   {.offset = 96, .length = 7},
-   {.offset = 112, .length = 7},
-   }
-};
-
 static const char * const part_probes[] = {
"cmdlinepart", "RedBoot", "ofpart", NULL };
 
@@ -942,6 +875,99 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int 
column, int page_addr)
}
 }
 
+static int mxc_v1_ooblayout_ecc(struct mtd_info *mtd, int section,
+   struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *nand_chip = mtd_to_nand(mtd);
+
+   if (section >= nand_chip->ecc.steps)
+   return -ERANGE;
+
+   oobregion->offset = (section * 16) + 6;
+   oobregion->length = nand_chip->ecc.bytes;
+
+   return 0;
+}
+
+static int mxc_v1_ooblayout_free(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *nand_chip = mtd_to_nand(mtd);
+
+   if (section > nand_chip->ecc.steps)
+   return -ERANGE;
+
+   if (!section) {
+   if (mtd->writesize <= 512) {
+   oobregion->offset = 0;
+   oobregion->length = 5;
+   } else {
+   oobregion->offset = 2;
+   oobregion->length = 4;
+   }
+   } else {
+   oobregion->offset = ((section - 1) * 16) +
+   nand_chip->ecc.bytes + 6;
+   if (section < nand_chip->ecc.steps)
+   oobregion->length = (section * 16) + 6 -
+   oobregion->offset;
+  

[PATCH v5 16/50] mtd: create an mtd_ooblayout_ops struct to ease ECC layout definition

2016-03-30 Thread Boris Brezillon
ECC layout definitions are currently exposed using the nand_ecclayout
struct which embeds oobfree and eccpos arrays with predefined size.
This approach was acceptable when NAND chips were providing relatively
small OOB regions, but MLC and TLC now provide OOB regions of several
hundreds of bytes, which implies a non negligible overhead for everybody
even those who only need to support legacy NANDs.

Create an mtd_ooblayout_ops interface providing the same functionality
(expose the ECC and oobfree layout) without the need for this huge
structure.

The mtd->ecclayout is now deprecated and should be replaced by the
equivalent mtd_ooblayout_ops. In the meantime we provide a wrapper around
the ->ecclayout field to ease migration to this new model.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/mtdchar.c   |   4 +-
 drivers/mtd/mtdconcat.c |   2 +-
 drivers/mtd/mtdcore.c   | 165 +++-
 drivers/mtd/mtdpart.c   |  23 ++-
 include/linux/mtd/mtd.h |  32 --
 5 files changed, 174 insertions(+), 52 deletions(-)

diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index cd64ab7..3fad2c7 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -888,7 +888,7 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, 
u_long arg)
{
struct nand_oobinfo oi;
 
-   if (!mtd->ecclayout)
+   if (!mtd->ooblayout)
return -EOPNOTSUPP;
 
ret = get_oobinfo(mtd, &oi);
@@ -982,7 +982,7 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, 
u_long arg)
{
struct nand_ecclayout_user *usrlay;
 
-   if (!mtd->ecclayout)
+   if (!mtd->ooblayout)
return -EOPNOTSUPP;
 
usrlay = kmalloc(sizeof(*usrlay), GFP_KERNEL);
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 481565e..d573606 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -777,7 +777,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info 
*subdev[],   /* subdevices to c
 
}
 
-   mtd_set_ecclayout(&concat->mtd, subdev[0]->ecclayout);
+   mtd_set_ooblayout(&concat->mtd, subdev[0]->ooblayout);
 
concat->num_subdev = num_devs;
concat->mtd.name = name;
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 9fc278a..bebca51 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1016,49 +1016,15 @@ EXPORT_SYMBOL_GPL(mtd_read_oob);
 int mtd_ooblayout_ecc(struct mtd_info *mtd, int section,
  struct mtd_oob_region *oobecc)
 {
-   int eccbyte = 0, cursection = 0, length = 0, eccpos = 0;
-
memset(oobecc, 0, sizeof(*oobecc));
 
if (!mtd || section < 0)
return -EINVAL;
 
-   if (!mtd->ecclayout)
+   if (!mtd->ooblayout || !mtd->ooblayout->ecc)
return -ENOTSUPP;
 
-   /*
-* This logic allows us to reuse the ->ecclayout information and
-* expose them as ECC regions (as done for the OOB free regions).
-*
-* TODO: this should be dropped as soon as we get rid of the
-* ->ecclayout field.
-*/
-   for (eccbyte = 0; eccbyte < mtd->ecclayout->eccbytes; eccbyte++) {
-   eccpos = mtd->ecclayout->eccpos[eccbyte];
-
-   if (eccbyte < mtd->ecclayout->eccbytes - 1) {
-   int neccpos = mtd->ecclayout->eccpos[eccbyte + 1];
-
-   if (eccpos + 1 == neccpos) {
-   length++;
-   continue;
-   }
-   }
-
-   if (section == cursection)
-   break;
-
-   length = 0;
-   cursection++;
-   }
-
-   if (cursection != section || eccbyte >= mtd->ecclayout->eccbytes)
-   return -ERANGE;
-
-   oobecc->length = length + 1;
-   oobecc->offset = eccpos - length;
-
-   return 0;
+   return mtd->ooblayout->ecc(mtd, section, oobecc);
 }
 EXPORT_SYMBOL_GPL(mtd_ooblayout_ecc);
 
@@ -1087,16 +1053,10 @@ int mtd_ooblayout_free(struct mtd_info *mtd, int 
section,
if (!mtd || section < 0)
return -EINVAL;
 
-   if (!mtd->ecclayout)
+   if (!mtd->ooblayout || !mtd->ooblayout->free)
return -ENOTSUPP;
 
-   if (section >= MTD_MAX_OOBFREE_ENTRIES_LARGE)
-   return -ERANGE;
-
-   oobfree->offset = mtd->ecclayout->oobfree[section].offset;
-   oobfree->length = mtd->ecclayout->oobfree[section].length;
-
-   return 0;
+   return mtd->ooblayout->free(mtd, section, oobfree);
 }
 EXPORT_SYMBOL_GPL(mtd_ooblayout_free);
 
@@ -1397,6 +1357,123 @@ int mtd_ooblayout_count_eccbytes(struct mtd_info *mtd)
 }
 EXPORT_SYMBOL_GPL(mtd_ooblayout_count_eccbytes);
 
+/**
+ * mtd_ecclayout_ecc - Default ooblayout_ecc iterator implementation
+ * @mtd: MTD device structure
+ * 

[PATCH v5 20/50] mtd: nand: sharpsl: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 arch/arm/mach-pxa/spitz.c   | 55 -
 drivers/mtd/nand/sharpsl.c  |  2 +-
 include/linux/mtd/sharpsl.h |  2 +-
 3 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index d9578bc..bd7cd8b 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -763,14 +763,49 @@ static struct nand_bbt_descr spitz_nand_bbt = {
.pattern= scan_ff_pattern
 };
 
-static struct nand_ecclayout akita_oobinfo = {
-   .oobfree= { {0x08, 0x09} },
-   .eccbytes   = 24,
-   .eccpos = {
-   0x05, 0x01, 0x02, 0x03, 0x06, 0x07, 0x15, 0x11,
-   0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
-   0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37,
-   },
+static int akita_ooblayout_ecc(struct mtd_info *mtd, int section,
+  struct mtd_oob_region *oobregion)
+{
+   if (section > 12)
+   return -ERANGE;
+
+   switch (section % 3) {
+   case 0:
+   oobregion->offset = 5;
+   oobregion->length = 1;
+   break;
+
+   case 1:
+   oobregion->offset = 1;
+   oobregion->length = 3;
+   break;
+
+   case 2:
+   oobregion->offset = 6;
+   oobregion->length = 2;
+   break;
+   }
+
+   oobregion->offset += (section / 3) * 0x10;
+
+   return 0;
+}
+
+static int akita_ooblayout_free(struct mtd_info *mtd, int section,
+   struct mtd_oob_region *oobregion)
+{
+   if (section)
+   return -ERANGE;
+
+   oobregion->offset = 8;
+   oobregion->length = 9;
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops akita_ooblayout_ops = {
+   .ecc = akita_ooblayout_ecc,
+   .free = akita_ooblayout_free,
 };
 
 static struct sharpsl_nand_platform_data spitz_nand_pdata = {
@@ -804,11 +839,11 @@ static void __init spitz_nand_init(void)
} else if (machine_is_akita()) {
spitz_nand_partitions[1].size = 58 * 1024 * 1024;
spitz_nand_bbt.len = 1;
-   spitz_nand_pdata.ecc_layout = &akita_oobinfo;
+   spitz_nand_pdata.ecc_layout = &akita_ooblayout_ops;
} else if (machine_is_borzoi()) {
spitz_nand_partitions[1].size = 32 * 1024 * 1024;
spitz_nand_bbt.len = 1;
-   spitz_nand_pdata.ecc_layout = &akita_oobinfo;
+   spitz_nand_pdata.ecc_layout = &akita_ooblayout_ops;
}
 
platform_device_register(&spitz_nand_device);
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c
index b7d1b55..064ca17 100644
--- a/drivers/mtd/nand/sharpsl.c
+++ b/drivers/mtd/nand/sharpsl.c
@@ -148,6 +148,7 @@ static int sharpsl_nand_probe(struct platform_device *pdev)
/* Link the private data with the MTD structure */
mtd = nand_to_mtd(this);
mtd->dev.parent = &pdev->dev;
+   mtd_set_ooblayout(mtd, data->ecc_layout);
 
platform_set_drvdata(pdev, sharpsl);
 
@@ -170,7 +171,6 @@ static int sharpsl_nand_probe(struct platform_device *pdev)
this->ecc.bytes = 3;
this->ecc.strength = 1;
this->badblock_pattern = data->badblock_pattern;
-   this->ecc.layout = data->ecc_layout;
this->ecc.hwctl = sharpsl_nand_enable_hwecc;
this->ecc.calculate = sharpsl_nand_calculate_ecc;
this->ecc.correct = nand_correct_data;
diff --git a/include/linux/mtd/sharpsl.h b/include/linux/mtd/sharpsl.h
index 25f4d2a..65e91d0 100644
--- a/include/linux/mtd/sharpsl.h
+++ b/include/linux/mtd/sharpsl.h
@@ -14,7 +14,7 @@
 
 struct sharpsl_nand_platform_data {
struct nand_bbt_descr   *badblock_pattern;
-   struct nand_ecclayout   *ecc_layout;
+   const struct mtd_ooblayout_ops *ecc_layout;
struct mtd_partition*partitions;
unsigned intnr_partitions;
 };
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 41/50] mtd: nand: s3c2410: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/s3c2410.c | 32 +++-
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index 9c9397b..700c097 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -84,11 +84,33 @@
 
 /* new oob placement block for use with hardware ecc generation
  */
+static int s3c2410_ooblayout_ecc(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   if (section)
+   return -ERANGE;
+
+   oobregion->offset = 0;
+   oobregion->length = 3;
+
+   return 0;
+}
+
+static int s3c2410_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   if (section)
+   return -ERANGE;
+
+   oobregion->offset = 8;
+   oobregion->length = 8;
+
+   return 0;
+}
 
-static struct nand_ecclayout nand_hw_eccoob = {
-   .eccbytes = 3,
-   .eccpos = {0, 1, 2},
-   .oobfree = {{8, 8}}
+static const struct mtd_ooblayout_ops s3c2410_ooblayout_ops = {
+   .ecc = s3c2410_ooblayout_ecc,
+   .free = s3c2410_ooblayout_free,
 };
 
 /* controller and mtd information */
@@ -919,7 +941,7 @@ static void s3c2410_nand_update_chip(struct 
s3c2410_nand_info *info,
} else {
chip->ecc.size  = 512;
chip->ecc.bytes = 3;
-   chip->ecc.layout= &nand_hw_eccoob;
+   mtd_set_ooblayout(nand_to_mtd(chip), &s3c2410_ooblayout_ops);
}
 }
 
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 42/50] mtd: nand: sh_flctl: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/sh_flctl.c | 87 ++---
 1 file changed, 67 insertions(+), 20 deletions(-)

diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 4814402..fa46610 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -43,26 +43,73 @@
 #include 
 #include 
 
-static struct nand_ecclayout flctl_4secc_oob_16 = {
-   .eccbytes = 10,
-   .eccpos = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
-   .oobfree = {
-   {.offset = 12,
-   . length = 4} },
+static int flctl_4secc_ooblayout_sp_ecc(struct mtd_info *mtd, int section,
+   struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+
+   if (section)
+   return -ERANGE;
+
+   oobregion->offset = 0;
+   oobregion->length = chip->ecc.bytes;
+
+   return 0;
+}
+
+static int flctl_4secc_ooblayout_sp_free(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   if (section)
+   return -ERANGE;
+
+   oobregion->offset = 12;
+   oobregion->length = 4;
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops flctl_4secc_oob_smallpage_ops = {
+   .ecc = flctl_4secc_ooblayout_sp_ecc,
+   .free = flctl_4secc_ooblayout_sp_free,
 };
 
-static struct nand_ecclayout flctl_4secc_oob_64 = {
-   .eccbytes = 4 * 10,
-   .eccpos = {
-6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
-   22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
-   38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
-   54, 55, 56, 57, 58, 59, 60, 61, 62, 63 },
-   .oobfree = {
-   {.offset =  2, .length = 4},
-   {.offset = 16, .length = 6},
-   {.offset = 32, .length = 6},
-   {.offset = 48, .length = 6} },
+static int flctl_4secc_ooblayout_lp_ecc(struct mtd_info *mtd, int section,
+   struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+
+   if (section >= chip->ecc.steps)
+   return -ERANGE;
+
+   oobregion->offset = (section * 16) + 6;
+   oobregion->length = chip->ecc.bytes;
+
+   return 0;
+}
+
+static int flctl_4secc_ooblayout_lp_free(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+
+   if (section >= chip->ecc.steps)
+   return -ERANGE;
+
+   oobregion->offset = section * 16;
+   oobregion->length = 6;
+
+   if (!section) {
+   oobregion->offset += 2;
+   oobregion->length -= 2;
+   }
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops flctl_4secc_oob_largepage_ops = {
+   .ecc = flctl_4secc_ooblayout_lp_ecc,
+   .free = flctl_4secc_ooblayout_lp_free,
 };
 
 static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
@@ -987,10 +1034,10 @@ static int flctl_chip_init_tail(struct mtd_info *mtd)
 
if (flctl->hwecc) {
if (mtd->writesize == 512) {
-   chip->ecc.layout = &flctl_4secc_oob_16;
+   mtd_set_ooblayout(mtd, &flctl_4secc_oob_smallpage_ops);
chip->badblock_pattern = &flctl_4secc_smallpage;
} else {
-   chip->ecc.layout = &flctl_4secc_oob_64;
+   mtd_set_ooblayout(mtd, &flctl_4secc_oob_largepage_ops);
chip->badblock_pattern = &flctl_4secc_largepage;
}
 
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 27/50] mtd: nand: denali: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/denali.c | 50 +--
 1 file changed, 35 insertions(+), 15 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 30bf5f6..0476ae8 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -1374,13 +1374,41 @@ static void denali_hw_init(struct denali_nand_info 
*denali)
  * correction
  */
 #define ECC_8BITS  14
-static struct nand_ecclayout nand_8bit_oob = {
-   .eccbytes = 14,
-};
-
 #define ECC_15BITS 26
-static struct nand_ecclayout nand_15bit_oob = {
-   .eccbytes = 26,
+
+static int denali_ooblayout_ecc(struct mtd_info *mtd, int section,
+   struct mtd_oob_region *oobregion)
+{
+   struct denali_nand_info *denali = mtd_to_denali(mtd);
+   struct nand_chip *chip = mtd_to_nand(mtd);
+
+   if (section)
+   return -ERANGE;
+
+   oobregion->offset = denali->bbtskipbytes;
+   oobregion->length = chip->ecc.total;
+
+   return 0;
+}
+
+static int denali_ooblayout_free(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   struct denali_nand_info *denali = mtd_to_denali(mtd);
+   struct nand_chip *chip = mtd_to_nand(mtd);
+
+   if (section)
+   return -ERANGE;
+
+   oobregion->offset = chip->ecc.total + denali->bbtskipbytes;
+   oobregion->length = mtd->oobsize - oobregion->offset;
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops denali_ooblayout_ops = {
+   .ecc = denali_ooblayout_ecc,
+   .free = denali_ooblayout_free,
 };
 
 static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
@@ -1561,7 +1589,6 @@ int denali_init(struct denali_nand_info *denali)
ECC_SECTOR_SIZE {
/* if MLC OOB size is large enough, use 15bit ECC*/
denali->nand.ecc.strength = 15;
-   denali->nand.ecc.layout = &nand_15bit_oob;
denali->nand.ecc.bytes = ECC_15BITS;
iowrite32(15, denali->flash_reg + ECC_CORRECTION);
} else if (mtd->oobsize < (denali->bbtskipbytes +
@@ -1571,20 +1598,13 @@ int denali_init(struct denali_nand_info *denali)
goto failed_req_irq;
} else {
denali->nand.ecc.strength = 8;
-   denali->nand.ecc.layout = &nand_8bit_oob;
denali->nand.ecc.bytes = ECC_8BITS;
iowrite32(8, denali->flash_reg + ECC_CORRECTION);
}
 
+   mtd_set_ooblayout(mtd, &denali_ooblayout_ops);
denali->nand.ecc.bytes *= denali->devnum;
denali->nand.ecc.strength *= denali->devnum;
-   denali->nand.ecc.layout->eccbytes *=
-   mtd->writesize / ECC_SECTOR_SIZE;
-   denali->nand.ecc.layout->oobfree[0].offset =
-   denali->bbtskipbytes + denali->nand.ecc.layout->eccbytes;
-   denali->nand.ecc.layout->oobfree[0].length =
-   mtd->oobsize - denali->nand.ecc.layout->eccbytes -
-   denali->bbtskipbytes;
 
/*
 * Let driver know the total blocks number and how many blocks
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 36/50] mtd: nand: jz4780: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
Tested-by: Harvey Hunt 
---
 drivers/mtd/nand/jz4780_nand.c | 19 +--
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/nand/jz4780_nand.c b/drivers/mtd/nand/jz4780_nand.c
index e1c016c..b86a579 100644
--- a/drivers/mtd/nand/jz4780_nand.c
+++ b/drivers/mtd/nand/jz4780_nand.c
@@ -56,8 +56,6 @@ struct jz4780_nand_chip {
struct nand_chip chip;
struct list_head chip_list;
 
-   struct nand_ecclayout ecclayout;
-
struct gpio_desc *busy_gpio;
struct gpio_desc *wp_gpio;
unsigned int reading: 1;
@@ -165,8 +163,7 @@ static int jz4780_nand_init_ecc(struct jz4780_nand_chip 
*nand, struct device *de
struct nand_chip *chip = &nand->chip;
struct mtd_info *mtd = nand_to_mtd(chip);
struct jz4780_nand_controller *nfc = 
to_jz4780_nand_controller(chip->controller);
-   struct nand_ecclayout *layout = &nand->ecclayout;
-   u32 start, i;
+   int eccbytes;
 
chip->ecc.bytes = fls((1 + 8) * chip->ecc.size) *
(chip->ecc.strength / 8);
@@ -201,23 +198,17 @@ static int jz4780_nand_init_ecc(struct jz4780_nand_chip 
*nand, struct device *de
return 0;
 
/* Generate ECC layout. ECC codes are right aligned in the OOB area. */
-   layout->eccbytes = mtd->writesize / chip->ecc.size * chip->ecc.bytes;
+   eccbytes = mtd->writesize / chip->ecc.size * chip->ecc.bytes;
 
-   if (layout->eccbytes > mtd->oobsize - 2) {
+   if (eccbytes > mtd->oobsize - 2) {
dev_err(dev,
"invalid ECC config: required %d ECC bytes, but only %d 
are available",
-   layout->eccbytes, mtd->oobsize - 2);
+   eccbytes, mtd->oobsize - 2);
return -EINVAL;
}
 
-   start = mtd->oobsize - layout->eccbytes;
-   for (i = 0; i < layout->eccbytes; i++)
-   layout->eccpos[i] = start + i;
-
-   layout->oobfree[0].offset = 2;
-   layout->oobfree[0].length = mtd->oobsize - layout->eccbytes - 2;
+   mtd->ooblayout = &nand_ooblayout_lp_ops;
 
-   chip->ecc.layout = layout;
return 0;
 }
 
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 35/50] mtd: nand: hisi504: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/hisi504_nand.c | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/hisi504_nand.c b/drivers/mtd/nand/hisi504_nand.c
index 96502b6..7bf844c 100644
--- a/drivers/mtd/nand/hisi504_nand.c
+++ b/drivers/mtd/nand/hisi504_nand.c
@@ -631,8 +631,28 @@ static void hisi_nfc_host_init(struct hinfc_host *host)
hinfc_write(host, HINFC504_INTEN_DMA, HINFC504_INTEN);
 }
 
-static struct nand_ecclayout nand_ecc_2K_16bits = {
-   .oobfree = { {2, 6} },
+static int hisi_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   /* FIXME: add ECC bytes position */
+   return -ENOTSUPP;
+}
+
+static int hisi_ooblayout_free(struct mtd_info *mtd, int section,
+  struct mtd_oob_region *oobregion)
+{
+   if (section)
+   return -ERANGE;
+
+   oobregion->offset = 2;
+   oobregion->length = 6;
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops hisi_ooblayout_ops = {
+   .ecc = hisi_ooblayout_ecc,
+   .free = hisi_ooblayout_free,
 };
 
 static int hisi_nfc_ecc_probe(struct hinfc_host *host)
@@ -668,7 +688,7 @@ static int hisi_nfc_ecc_probe(struct hinfc_host *host)
case 16:
ecc_bits = 6;
if (mtd->writesize == 2048)
-   chip->ecc.layout = &nand_ecc_2K_16bits;
+   mtd_set_ooblayout(mtd, &hisi_ooblayout_ops);
 
/* TODO: add more page size support */
break;
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 43/50] mtd: nand: sm_common: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/sm_common.c | 93 
 1 file changed, 77 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/nand/sm_common.c b/drivers/mtd/nand/sm_common.c
index c514740..5939dff 100644
--- a/drivers/mtd/nand/sm_common.c
+++ b/drivers/mtd/nand/sm_common.c
@@ -12,14 +12,47 @@
 #include 
 #include "sm_common.h"
 
-static struct nand_ecclayout nand_oob_sm = {
-   .eccbytes = 6,
-   .eccpos = {8, 9, 10, 13, 14, 15},
-   .oobfree = {
-   {.offset = 0 , .length = 4}, /* reserved */
-   {.offset = 6 , .length = 2}, /* LBA1 */
-   {.offset = 11, .length = 2}  /* LBA2 */
+static int oob_sm_ooblayout_ecc(struct mtd_info *mtd, int section,
+   struct mtd_oob_region *oobregion)
+{
+   if (section > 1)
+   return -ERANGE;
+
+   oobregion->length = 3;
+   oobregion->offset = ((section + 1) * 8) - 3;
+
+   return 0;
+}
+
+static int oob_sm_ooblayout_free(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   switch (section) {
+   case 0:
+   /* reserved */
+   oobregion->offset = 0;
+   oobregion->length = 4;
+   break;
+   case 1:
+   /* LBA1 */
+   oobregion->offset = 6;
+   oobregion->length = 2;
+   break;
+   case 2:
+   /* LBA2 */
+   oobregion->offset = 11;
+   oobregion->length = 2;
+   break;
+   default:
+   return -ERANGE;
}
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops oob_sm_ops = {
+   .ecc = oob_sm_ooblayout_ecc,
+   .free = oob_sm_ooblayout_free,
 };
 
 /* NOTE: This layout is is not compatabable with SmartMedia, */
@@ -28,15 +61,43 @@ static struct nand_ecclayout nand_oob_sm = {
 /* If you use smftl, it will bypass this and work correctly */
 /* If you not, then you break SmartMedia compliance anyway */
 
-static struct nand_ecclayout nand_oob_sm_small = {
-   .eccbytes = 3,
-   .eccpos = {0, 1, 2},
-   .oobfree = {
-   {.offset = 3 , .length = 2}, /* reserved */
-   {.offset = 6 , .length = 2}, /* LBA1 */
+static int oob_sm_small_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   if (section)
+   return -ERANGE;
+
+   oobregion->length = 3;
+   oobregion->offset = 0;
+
+   return 0;
+}
+
+static int oob_sm_small_ooblayout_free(struct mtd_info *mtd, int section,
+  struct mtd_oob_region *oobregion)
+{
+   switch (section) {
+   case 0:
+   /* reserved */
+   oobregion->offset = 3;
+   oobregion->length = 2;
+   break;
+   case 1:
+   /* LBA1 */
+   oobregion->offset = 6;
+   oobregion->length = 2;
+   break;
+   default:
+   return -ERANGE;
}
-};
 
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops oob_sm_small_ops = {
+   .ecc = oob_sm_small_ooblayout_ecc,
+   .free = oob_sm_small_ooblayout_free,
+};
 
 static int sm_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
@@ -121,9 +182,9 @@ int sm_register_device(struct mtd_info *mtd, int smartmedia)
 
/* ECC layout */
if (mtd->writesize == SM_SECTOR_SIZE)
-   chip->ecc.layout = &nand_oob_sm;
+   mtd_set_ooblayout(mtd, &oob_sm_ops);
else if (mtd->writesize == SM_SMALL_PAGE)
-   chip->ecc.layout = &nand_oob_sm_small;
+   mtd_set_ooblayout(mtd, &oob_sm_small_ops);
else
return -ENODEV;
 
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 28/50] mtd: nand: diskonchip: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/diskonchip.c | 60 ---
 1 file changed, 45 insertions(+), 15 deletions(-)

diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index 547c100..a023ab9 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -950,20 +950,50 @@ static int doc200x_correct_data(struct mtd_info *mtd, 
u_char *dat,
 
 //u_char mydatabuf[528];
 
-/* The strange out-of-order .oobfree list below is a (possibly unneeded)
- * attempt to retain compatibility.  It used to read:
- * .oobfree = { {8, 8} }
- * Since that leaves two bytes unusable, it was changed.  But the following
- * scheme might affect existing jffs2 installs by moving the cleanmarker:
- * .oobfree = { {6, 10} }
- * jffs2 seems to handle the above gracefully, but the current scheme seems
- * safer.  The only problem with it is that any code that parses oobfree must
- * be able to handle out-of-order segments.
- */
-static struct nand_ecclayout doc200x_oobinfo = {
-   .eccbytes = 6,
-   .eccpos = {0, 1, 2, 3, 4, 5},
-   .oobfree = {{8, 8}, {6, 2}}
+static int doc200x_ooblayout_ecc(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   if (section)
+   return -ERANGE;
+
+   oobregion->offset = 0;
+   oobregion->length = 6;
+
+   return 0;
+}
+
+static int doc200x_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   if (section > 1)
+   return -ERANGE;
+
+   /*
+* The strange out-of-order free bytes definition is a (possibly
+* unneeded) attempt to retain compatibility.  It used to read:
+*  .oobfree = { {8, 8} }
+* Since that leaves two bytes unusable, it was changed.  But the
+* following scheme might affect existing jffs2 installs by moving the
+* cleanmarker:
+*  .oobfree = { {6, 10} }
+* jffs2 seems to handle the above gracefully, but the current scheme
+* seems safer. The only problem with it is that any code retrieving
+* free bytes position must be able to handle out-of-order segments.
+*/
+   if (!section) {
+   oobregion->offset = 8;
+   oobregion->length = 8;
+   } else {
+   oobregion->offset = 6;
+   oobregion->length = 2;
+   }
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops doc200x_ooblayout_ops = {
+   .ecc = doc200x_ooblayout_ecc,
+   .free = doc200x_ooblayout_free,
 };
 
 /* Find the (I)NFTL Media Header, and optionally also the mirror media header.
@@ -1537,6 +1567,7 @@ static int __init doc_probe(unsigned long physadr)
nand->bbt_md= nand->bbt_td + 1;
 
mtd->owner  = THIS_MODULE;
+   mtd_set_ooblayout(mtd, &doc200x_ooblayout_ops);
 
nand_set_controller_data(nand, doc);
nand->select_chip   = doc200x_select_chip;
@@ -1548,7 +1579,6 @@ static int __init doc_probe(unsigned long physadr)
nand->ecc.calculate = doc200x_calculate_ecc;
nand->ecc.correct   = doc200x_correct_data;
 
-   nand->ecc.layout= &doc200x_oobinfo;
nand->ecc.mode  = NAND_ECC_HW_SYNDROME;
nand->ecc.size  = 512;
nand->ecc.bytes = 6;
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 45/50] mtd: nand: vf610: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/vf610_nfc.c | 34 --
 1 file changed, 4 insertions(+), 30 deletions(-)

diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index 293feb1..da34de1 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -175,34 +175,6 @@ static inline struct vf610_nfc *mtd_to_nfc(struct mtd_info 
*mtd)
return container_of(mtd_to_nand(mtd), struct vf610_nfc, chip);
 }
 
-static struct nand_ecclayout vf610_nfc_ecc45 = {
-   .eccbytes = 45,
-   .eccpos = {19, 20, 21, 22, 23,
-  24, 25, 26, 27, 28, 29, 30, 31,
-  32, 33, 34, 35, 36, 37, 38, 39,
-  40, 41, 42, 43, 44, 45, 46, 47,
-  48, 49, 50, 51, 52, 53, 54, 55,
-  56, 57, 58, 59, 60, 61, 62, 63},
-   .oobfree = {
-   {.offset = 2,
-.length = 17} }
-};
-
-static struct nand_ecclayout vf610_nfc_ecc60 = {
-   .eccbytes = 60,
-   .eccpos = { 4,  5,  6,  7,  8,  9, 10, 11,
-  12, 13, 14, 15, 16, 17, 18, 19,
-  20, 21, 22, 23, 24, 25, 26, 27,
-  28, 29, 30, 31, 32, 33, 34, 35,
-  36, 37, 38, 39, 40, 41, 42, 43,
-  44, 45, 46, 47, 48, 49, 50, 51,
-  52, 53, 54, 55, 56, 57, 58, 59,
-  60, 61, 62, 63 },
-   .oobfree = {
-   {.offset = 2,
-.length = 2} }
-};
-
 static inline u32 vf610_nfc_read(struct vf610_nfc *nfc, uint reg)
 {
return readl(nfc->regs + reg);
@@ -781,14 +753,16 @@ static int vf610_nfc_probe(struct platform_device *pdev)
if (mtd->oobsize > 64)
mtd->oobsize = 64;
 
+   /*
+* mtd->ecclayout is not specified here because we're using the
+* default large page ECC layout defined in NAND core.
+*/
if (chip->ecc.strength == 32) {
nfc->ecc_mode = ECC_60_BYTE;
chip->ecc.bytes = 60;
-   chip->ecc.layout = &vf610_nfc_ecc60;
} else if (chip->ecc.strength == 24) {
nfc->ecc_mode = ECC_45_BYTE;
chip->ecc.bytes = 45;
-   chip->ecc.layout = &vf610_nfc_ecc45;
} else {
dev_err(nfc->dev, "Unsupported ECC strength\n");
err = -ENXIO;
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 48/50] staging: mt29f_spinand: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Replace the nand_ecclayout definition by the equivalent mtd_ooblayout_ops
definition.

Signed-off-by: Boris Brezillon 
---
 drivers/staging/mt29f_spinand/mt29f_spinand.c | 48 +--
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c 
b/drivers/staging/mt29f_spinand/mt29f_spinand.c
index 163f21a..f503699 100644
--- a/drivers/staging/mt29f_spinand/mt29f_spinand.c
+++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c
@@ -42,23 +42,33 @@ static inline struct spinand_state *mtd_to_state(struct 
mtd_info *mtd)
 static int enable_hw_ecc;
 static int enable_read_hw_ecc;
 
-static struct nand_ecclayout spinand_oob_64 = {
-   .eccbytes = 24,
-   .eccpos = {
-   1, 2, 3, 4, 5, 6,
-   17, 18, 19, 20, 21, 22,
-   33, 34, 35, 36, 37, 38,
-   49, 50, 51, 52, 53, 54, },
-   .oobfree = {
-   {.offset = 8,
-   .length = 8},
-   {.offset = 24,
-   .length = 8},
-   {.offset = 40,
-   .length = 8},
-   {.offset = 56,
-   .length = 8},
-   }
+static int spinand_ooblayout_64_ecc(struct mtd_info *mtd, int section,
+   struct mtd_oob_region *oobregion)
+{
+   if (section > 3)
+   return -ERANGE;
+
+   oobregion->offset = (section * 16) + 1;
+   oobregion->length = 6;
+
+   return 0;
+}
+
+static int spinand_ooblayout_64_free(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   if (section > 3)
+   return -ERANGE;
+
+   oobregion->offset = (section * 16) + 8;
+   oobregion->length = 8;
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops spinand_oob_64_ops = {
+   .ecc = spinand_ooblayout_64_ecc,
+   .free = spinand_ooblayout_64_free,
 };
 #endif
 
@@ -886,7 +896,6 @@ static int spinand_probe(struct spi_device *spi_nand)
 
chip->ecc.strength = 1;
chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
-   chip->ecc.layout = &spinand_oob_64;
chip->ecc.read_page = spinand_read_page_hwecc;
chip->ecc.write_page = spinand_write_page_hwecc;
 #else
@@ -912,6 +921,9 @@ static int spinand_probe(struct spi_device *spi_nand)
 
mtd->dev.parent = &spi_nand->dev;
mtd->oobsize = 64;
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+   mtd_set_ooblayout(mtd, &spinand_oob_64_ops);
+#endif
 
if (nand_scan(mtd, 1))
return -ENXIO;
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 46/50] mtd: nand: qcom: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
Tested-by: Archit Taneja 
---
 drivers/mtd/nand/qcom_nandc.c | 79 +++
 1 file changed, 34 insertions(+), 45 deletions(-)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 012c202..8c3db3c 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -1708,61 +1708,52 @@ static void qcom_nandc_select_chip(struct mtd_info 
*mtd, int chipnr)
  * This layout is read as is when ECC is disabled. When ECC is enabled, the
  * inaccessible Bad Block byte(s) are ignored when we write to a page/oob,
  * and assumed as 0xffs when we read a page/oob. The ECC, unused and
- * dummy/real bad block bytes are grouped as ecc bytes in nand_ecclayout (i.e,
- * ecc->bytes is the sum of the three).
+ * dummy/real bad block bytes are grouped as ecc bytes (i.e, ecc->bytes is
+ * the sum of the three).
  */
-
-static struct nand_ecclayout *
-qcom_nand_create_layout(struct qcom_nand_host *host)
+static int qcom_nand_ooblayout_ecc(struct mtd_info *mtd, int section,
+  struct mtd_oob_region *oobregion)
 {
-   struct nand_chip *chip = &host->chip;
-   struct mtd_info *mtd = nand_to_mtd(chip);
-   struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   struct qcom_nand_host *host = to_qcom_nand_host(chip);
struct nand_ecc_ctrl *ecc = &chip->ecc;
-   struct nand_ecclayout *layout;
-   int i, j, steps, pos = 0, shift = 0;
 
-   layout = devm_kzalloc(nandc->dev, sizeof(*layout), GFP_KERNEL);
-   if (!layout)
-   return NULL;
+   if (section > 1)
+   return -ERANGE;
 
-   steps = mtd->writesize / ecc->size;
-   layout->eccbytes = steps * ecc->bytes;
-
-   layout->oobfree[0].offset = (steps - 1) * ecc->bytes + host->bbm_size;
-   layout->oobfree[0].length = steps << 2;
-
-   /*
-* the oob bytes in the first n - 1 codewords are all grouped together
-* in the format:
-* DUMMY_BBM + UNUSED + ECC
-*/
-   for (i = 0; i < steps - 1; i++) {
-   for (j = 0; j < ecc->bytes; j++)
-   layout->eccpos[pos++] = i * ecc->bytes + j;
+   if (!section) {
+   oobregion->length = (ecc->bytes * (ecc->steps - 1)) +
+   host->bbm_size;
+   oobregion->offset = 0;
+   } else {
+   oobregion->length = host->ecc_bytes_hw + host->spare_bytes;
+   oobregion->offset = mtd->oobsize - oobregion->length;
}
 
-   /*
-* the oob bytes in the last codeword are grouped in the format:
-* BBM + FREE OOB + UNUSED + ECC
-*/
+   return 0;
+}
 
-   /* fill up the bbm positions */
-   for (j = 0; j < host->bbm_size; j++)
-   layout->eccpos[pos++] = i * ecc->bytes + j;
+static int qcom_nand_ooblayout_free(struct mtd_info *mtd, int section,
+   struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   struct qcom_nand_host *host = to_qcom_nand_host(chip);
+   struct nand_ecc_ctrl *ecc = &chip->ecc;
 
-   /*
-* fill up the ecc and reserved positions, their indices are offseted
-* by the free oob region
-*/
-   shift = layout->oobfree[0].length + host->bbm_size;
+   if (section)
+   return -ERANGE;
 
-   for (j = 0; j < (host->ecc_bytes_hw + host->spare_bytes); j++)
-   layout->eccpos[pos++] = i * ecc->bytes + shift + j;
+   oobregion->length = ecc->steps * 4;
+   oobregion->offset = ((ecc->steps - 1) * ecc->bytes) + host->bbm_size;
 
-   return layout;
+   return 0;
 }
 
+static const struct mtd_ooblayout_ops qcom_nand_ooblayout_ops = {
+   .ecc = qcom_nand_ooblayout_ecc,
+   .free = qcom_nand_ooblayout_free,
+};
+
 static int qcom_nand_host_setup(struct qcom_nand_host *host)
 {
struct nand_chip *chip = &host->chip;
@@ -1849,9 +1840,7 @@ static int qcom_nand_host_setup(struct qcom_nand_host 
*host)
 
ecc->mode = NAND_ECC_HW;
 
-   ecc->layout = qcom_nand_create_layout(host);
-   if (!ecc->layout)
-   return -ENOMEM;
+   mtd_set_ooblayout(mtd, &qcom_nand_ooblayout_ops);
 
cwperpage = mtd->writesize / ecc->size;
 
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 50/50] mtd: kill the nand_ecclayout struct

2016-03-30 Thread Boris Brezillon
Now that all MTD drivers have moved to the mtd_ooblayout_ops model we can
safely remove the struct nand_ecclayout definition, and all the remaining
places where it was still used.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/mtdchar.c  |  12 ++---
 drivers/mtd/mtdcore.c  | 117 -
 include/linux/mtd/mtd.h|  20 
 include/uapi/mtd/mtd-abi.h |   2 +-
 4 files changed, 7 insertions(+), 144 deletions(-)

diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 3fad2c7..2a47a3f 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -465,12 +465,12 @@ static int mtdchar_readoob(struct file *file, struct 
mtd_info *mtd,
 }
 
 /*
- * Copies (and truncates, if necessary) data from the larger struct,
- * nand_ecclayout, to the smaller, deprecated layout struct,
- * nand_ecclayout_user. This is necessary only to support the deprecated
- * API ioctl ECCGETLAYOUT while allowing all new functionality to use
- * nand_ecclayout flexibly (i.e. the struct may change size in new
- * releases without requiring major rewrites).
+ * Copies (and truncates, if necessary) OOB layout information to the
+ * deprecated layout struct, nand_ecclayout_user. This is necessary only to
+ * support the deprecated API ioctl ECCGETLAYOUT while allowing all new
+ * functionality to use mtd_ooblayout_ops flexibly (i.e. mtd_ooblayout_ops
+ * can describe any kind of OOB layout with almost zero overhead from a
+ * memory usage point of view).
  */
 static int shrink_ecclayout(struct mtd_info *mtd,
struct nand_ecclayout_user *to)
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index bebca51..cbfa5ad 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1357,123 +1357,6 @@ int mtd_ooblayout_count_eccbytes(struct mtd_info *mtd)
 }
 EXPORT_SYMBOL_GPL(mtd_ooblayout_count_eccbytes);
 
-/**
- * mtd_ecclayout_ecc - Default ooblayout_ecc iterator implementation
- * @mtd: MTD device structure
- * @section: ECC section. Depending on the layout you may have all the ECC
- *  bytes stored in a single contiguous section, or one section
- *  per ECC chunk (and sometime several sections for a single ECC
- *  ECC chunk)
- * @oobecc: OOB region struct filled with the appropriate ECC position
- * information
- *
- * This function is just a wrapper around the mtd->ecclayout field and is
- * here to ease the transition to the mtd_ooblayout_ops approach.
- * All it does is convert the layout->eccpos information into proper oob
- * region definitions.
- *
- * Returns zero on success, a negative error code otherwise.
- */
-static int mtd_ecclayout_ecc(struct mtd_info *mtd, int section,
-struct mtd_oob_region *oobecc)
-{
-   int eccbyte = 0, cursection = 0, length = 0, eccpos = 0;
-
-   if (!mtd->ecclayout)
-   return -ENOTSUPP;
-
-   /*
-* This logic allows us to reuse the ->ecclayout information and
-* expose them as ECC regions (as done for the OOB free regions).
-*
-* TODO: this should be dropped as soon as we get rid of the
-* ->ecclayout field.
-*/
-   for (eccbyte = 0; eccbyte < mtd->ecclayout->eccbytes; eccbyte++) {
-   eccpos = mtd->ecclayout->eccpos[eccbyte];
-
-   if (eccbyte < mtd->ecclayout->eccbytes - 1) {
-   int neccpos = mtd->ecclayout->eccpos[eccbyte + 1];
-
-   if (eccpos + 1 == neccpos) {
-   length++;
-   continue;
-   }
-   }
-
-   if (section == cursection)
-   break;
-
-   length = 0;
-   cursection++;
-   }
-
-   if (cursection != section || eccbyte >= mtd->ecclayout->eccbytes)
-   return -ERANGE;
-
-   oobecc->length = length + 1;
-   oobecc->offset = eccpos - length;
-
-   return 0;
-}
-
-/**
- * mtd_ecclayout_ecc - Default ooblayout_free iterator implementation
- * @mtd: MTD device structure
- * @section: Free section. Depending on the layout you may have all the free
- *  bytes stored in a single contiguous section, or one section
- *  per ECC chunk (and sometime several sections for a single ECC
- *  ECC chunk)
- * @oobfree: OOB region struct filled with the appropriate free position
- *  information
- *
- * This function is just a wrapper around the mtd->ecclayout field and is
- * here to ease the transition to the mtd_ooblayout_ops approach.
- * All it does is convert the layout->oobfree information into proper oob
- * region definitions.
- *
- * Returns zero on success, a negative error code otherwise.
- */
-static int mtd_ecclayout_free(struct mtd_info *mtd, int section,
- struct mtd_oob_region *oobfree)
-{
-   struct nand_ecclayout *layout = mtd->ecclayout;
-
-   if (

[PATCH v5 47/50] mtd: onenand: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users. Modify the onenand drivers to switch to this
approach.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/onenand/onenand_base.c | 162 ++---
 include/linux/mtd/onenand.h|   2 -
 2 files changed, 97 insertions(+), 67 deletions(-)

diff --git a/drivers/mtd/onenand/onenand_base.c 
b/drivers/mtd/onenand/onenand_base.c
index d0fa505..a4b029a 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -68,21 +68,33 @@ MODULE_PARM_DESC(otp,   "Corresponding behaviour of 
OneNAND in OTP"
  * flexonenand_oob_128 - oob info for Flex-Onenand with 4KB page
  * For now, we expose only 64 out of 80 ecc bytes
  */
-static struct nand_ecclayout flexonenand_oob_128 = {
-   .eccbytes   = 64,
-   .eccpos = {
-   6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
-   22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
-   38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
-   54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-   70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
-   86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
-   102, 103, 104, 105
-   },
-   .oobfree= {
-   {2, 4}, {18, 4}, {34, 4}, {50, 4},
-   {66, 4}, {82, 4}, {98, 4}, {114, 4}
-   }
+static int flexonenand_ooblayout_ecc(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   if (section > 7)
+   return -ERANGE;
+
+   oobregion->offset = (section * 16) + 6;
+   oobregion->length = 10;
+
+   return 0;
+}
+
+static int flexonenand_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   if (section > 7)
+   return -ERANGE;
+
+   oobregion->offset = (section * 16) + 2;
+   oobregion->length = 4;
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops flexonenand_ooblayout_ops = {
+   .ecc = flexonenand_ooblayout_ecc,
+   .free = flexonenand_ooblayout_free,
 };
 
 /*
@@ -91,56 +103,77 @@ static struct nand_ecclayout flexonenand_oob_128 = {
  * Based on specification:
  * 4Gb M-die OneNAND Flash (KFM4G16Q4M, KFN8G16Q4M). Rev. 1.3, Apr. 2010
  *
- * For eccpos we expose only 64 bytes out of 72 (see struct nand_ecclayout)
- *
- * oobfree uses the spare area fields marked as
- * "Managed by internal ECC logic for Logical Sector Number area"
- */
-static struct nand_ecclayout onenand_oob_128 = {
-   .eccbytes   = 64,
-   .eccpos = {
-   7, 8, 9, 10, 11, 12, 13, 14, 15,
-   23, 24, 25, 26, 27, 28, 29, 30, 31,
-   39, 40, 41, 42, 43, 44, 45, 46, 47,
-   55, 56, 57, 58, 59, 60, 61, 62, 63,
-   71, 72, 73, 74, 75, 76, 77, 78, 79,
-   87, 88, 89, 90, 91, 92, 93, 94, 95,
-   103, 104, 105, 106, 107, 108, 109, 110, 111,
-   119
-   },
-   .oobfree= {
-   {2, 3}, {18, 3}, {34, 3}, {50, 3},
-   {66, 3}, {82, 3}, {98, 3}, {114, 3}
-   }
+ */
+static int onenand_ooblayout_128_ecc(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   if (section > 7)
+   return -ERANGE;
+
+   oobregion->offset = (section * 16) + 7;
+   oobregion->length = 9;
+
+   return 0;
+}
+
+static int onenand_ooblayout_128_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   if (section >= 8)
+   return -ERANGE;
+
+   /*
+* free bytes are using the spare area fields marked as
+* "Managed by internal ECC logic for Logical Sector Number area"
+*/
+   oobregion->offset = (section * 16) + 2;
+   oobregion->length = 3;
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops onenand_oob_128_ooblayout_ops = {
+   .ecc = onenand_ooblayout_128_ecc,
+   .free = onenand_ooblayout_128_free,
 };
 
 /**
- * onenand_oob_64 - oob info for large (2KB) page
+ * onenand_oob_32_64 - oob info for large (2KB) page
  */
-static struct nand_ecclayout onenand_oob_64 = {
-   .eccbytes   = 20,
-   .eccpos = {
-   8, 9, 10, 11, 12,
-   24, 25, 26, 27, 28,
-   40, 41, 42, 43, 44,
-   56, 57, 58, 59, 60,
-   },
-   .oobfree= {
-   {2, 3}, {14, 2}, {18, 3}, {30, 2},
-   {34, 3}, {46, 2}, {50, 3}, {62, 2}
+static int onenand_ooblayout_32_64_ecc(struct mtd_info *mtd, int section,
+  struct mtd_oob_region *oobregion)
+{
+   if (section > 3)
+   return -ERANGE;
+
+   oobregion->offset = (section * 16) + 8;
+   oobregion->length = 5;
+

[PATCH v5 33/50] mtd: nand: fsmc: get rid of the fsmc_nand_eccplace struct

2016-03-30 Thread Boris Brezillon
Now that mtd_ooblayout_ecc() returns the ECC byte position using the
OOB free method, we can get rid of the fsmc_nand_eccplace struct.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/fsmc_nand.c | 60 +++-
 include/linux/mtd/fsmc.h | 18 -
 2 files changed, 15 insertions(+), 63 deletions(-)

diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index 275a98c..1372040 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -39,35 +39,6 @@
 #include 
 #include 
 
-/*
- * ECC placement definitions in oobfree type format.
- * There are 13 bytes of ecc for every 512 byte block and it has to be read
- * consecutively and immediately after the 512 byte data block for hardware to
- * generate the error bit offsets in 512 byte data.
- * Managing the ecc bytes in the following way makes it easier for software to
- * read ecc bytes consecutive to data bytes. This way is similar to
- * oobfree structure maintained already in generic nand driver
- */
-static struct fsmc_eccplace fsmc_ecc4_lp_place = {
-   .eccplace = {
-   {.offset = 2, .length = 13},
-   {.offset = 18, .length = 13},
-   {.offset = 34, .length = 13},
-   {.offset = 50, .length = 13},
-   {.offset = 66, .length = 13},
-   {.offset = 82, .length = 13},
-   {.offset = 98, .length = 13},
-   {.offset = 114, .length = 13}
-   }
-};
-
-static struct fsmc_eccplace fsmc_ecc4_sp_place = {
-   .eccplace = {
-   {.offset = 0, .length = 4},
-   {.offset = 6, .length = 9}
-   }
-};
-
 static int fsmc_ecc1_ooblayout_ecc(struct mtd_info *mtd, int section,
   struct mtd_oob_region *oobregion)
 {
@@ -105,6 +76,12 @@ static const struct mtd_ooblayout_ops 
fsmc_ecc1_ooblayout_ops = {
.free = fsmc_ecc1_ooblayout_free,
 };
 
+/*
+ * ECC placement definitions in oobfree type format.
+ * There are 13 bytes of ecc for every 512 byte block and it has to be read
+ * consecutively and immediately after the 512 byte data block for hardware to
+ * generate the error bit offsets in 512 byte data.
+ */
 static int fsmc_ecc4_ooblayout_ecc(struct mtd_info *mtd, int section,
   struct mtd_oob_region *oobregion)
 {
@@ -155,7 +132,6 @@ static const struct mtd_ooblayout_ops 
fsmc_ecc4_ooblayout_ops = {
  * @partitions:Partition info for a NAND Flash.
  * @nr_partitions: Total number of partition of a NAND flash.
  *
- * @ecc_place: ECC placing locations in oobfree type format.
  * @bank:  Bank number for probed device.
  * @clk:   Clock structure for FSMC.
  *
@@ -175,7 +151,6 @@ struct fsmc_nand_data {
struct mtd_partition*partitions;
unsigned intnr_partitions;
 
-   struct fsmc_eccplace*ecc_place;
unsigned intbank;
struct device   *dev;
enum access_modemode;
@@ -582,8 +557,6 @@ static void fsmc_write_buf_dma(struct mtd_info *mtd, const 
uint8_t *buf,
 static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 uint8_t *buf, int oob_required, int page)
 {
-   struct fsmc_nand_data *host = mtd_to_fsmc(mtd);
-   struct fsmc_eccplace *ecc_place = host->ecc_place;
int i, j, s, stat, eccsize = chip->ecc.size;
int eccbytes = chip->ecc.bytes;
int eccsteps = chip->ecc.steps;
@@ -606,9 +579,15 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, 
struct nand_chip *chip,
chip->read_buf(mtd, p, eccsize);
 
for (j = 0; j < eccbytes;) {
-   off = ecc_place->eccplace[group].offset;
-   len = ecc_place->eccplace[group].length;
-   group++;
+   struct mtd_oob_region oobregion;
+   int ret;
+
+   ret = mtd_ooblayout_ecc(mtd, group++, &oobregion);
+   if (ret)
+   return ret;
+
+   off = oobregion.offset;
+   len = oobregion.length;
 
/*
 * length is intentionally kept a higher multiple of 2
@@ -956,19 +935,10 @@ static int __init fsmc_nand_probe(struct platform_device 
*pdev)
if (AMBA_REV_BITS(host->pid) >= 8) {
switch (mtd->oobsize) {
case 16:
-   host->ecc_place = &fsmc_ecc4_sp_place;
-   break;
case 64:
-   host->ecc_place = &fsmc_ecc4_lp_place;
-   break;
case 128:
-   host->ecc_place = &fsmc_ecc4_lp_place;
-   break;
case 224:
-   host->ecc_place = &fsmc_ecc4_

[PATCH v5 29/50] mtd: nand: docg4: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/docg4.c | 33 -
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
index d86a60e..4731699 100644
--- a/drivers/mtd/nand/docg4.c
+++ b/drivers/mtd/nand/docg4.c
@@ -222,10 +222,33 @@ struct docg4_priv {
  * Bytes 8 - 14 are hw-generated ecc covering entire page + oob bytes 0 - 14.
  * Byte 15 (the last) is used by the driver as a "page written" flag.
  */
-static struct nand_ecclayout docg4_oobinfo = {
-   .eccbytes = 9,
-   .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15},
-   .oobfree = { {.offset = 2, .length = 5} }
+static int docg4_ooblayout_ecc(struct mtd_info *mtd, int section,
+  struct mtd_oob_region *oobregion)
+{
+   if (section)
+   return -ERANGE;
+
+   oobregion->offset = 7;
+   oobregion->length = 9;
+
+   return 0;
+}
+
+static int docg4_ooblayout_free(struct mtd_info *mtd, int section,
+   struct mtd_oob_region *oobregion)
+{
+   if (section)
+   return -ERANGE;
+
+   oobregion->offset = 2;
+   oobregion->length = 5;
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops docg4_ooblayout_ops = {
+   .ecc = docg4_ooblayout_ecc,
+   .free = docg4_ooblayout_free,
 };
 
 /*
@@ -1209,6 +1232,7 @@ static void __init init_mtd_structs(struct mtd_info *mtd)
mtd->writesize = DOCG4_PAGE_SIZE;
mtd->erasesize = DOCG4_BLOCK_SIZE;
mtd->oobsize = DOCG4_OOB_SIZE;
+   mtd_set_ooblayout(mtd, &docg4_ooblayout_ops);
nand->chipsize = DOCG4_CHIP_SIZE;
nand->chip_shift = DOCG4_CHIP_SHIFT;
nand->bbt_erase_shift = nand->phys_erase_shift = DOCG4_ERASE_SHIFT;
@@ -1217,7 +1241,6 @@ static void __init init_mtd_structs(struct mtd_info *mtd)
nand->pagemask = 0x3;
nand->badblockpos = NAND_LARGE_BADBLOCK_POS;
nand->badblockbits = 8;
-   nand->ecc.layout = &docg4_oobinfo;
nand->ecc.mode = NAND_ECC_HW_SYNDROME;
nand->ecc.size = DOCG4_PAGE_SIZE;
nand->ecc.prepad = 8;
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 37/50] mtd: nand: lpc32xx: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/lpc32xx_mlc.c | 50 --
 drivers/mtd/nand/lpc32xx_slc.c | 41 +++---
 2 files changed, 66 insertions(+), 25 deletions(-)

diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c
index d8c3e7a..f668282 100644
--- a/drivers/mtd/nand/lpc32xx_mlc.c
+++ b/drivers/mtd/nand/lpc32xx_mlc.c
@@ -139,22 +139,37 @@ struct lpc32xx_nand_cfg_mlc {
unsigned num_parts;
 };
 
-static struct nand_ecclayout lpc32xx_nand_oob = {
-   .eccbytes = 40,
-   .eccpos = { 6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
-  22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
-  38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
-  54, 55, 56, 57, 58, 59, 60, 61, 62, 63 },
-   .oobfree = {
-   { .offset = 0,
- .length = 6, },
-   { .offset = 16,
- .length = 6, },
-   { .offset = 32,
- .length = 6, },
-   { .offset = 48,
- .length = 6, },
-   },
+static int lpc32xx_ooblayout_ecc(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *nand_chip = mtd_to_nand(mtd);
+
+   if (section >= nand_chip->ecc.steps)
+   return -ERANGE;
+
+   oobregion->offset = ((section + 1) * 16) - nand_chip->ecc.bytes;
+   oobregion->length = nand_chip->ecc.bytes;
+
+   return 0;
+}
+
+static int lpc32xx_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *nand_chip = mtd_to_nand(mtd);
+
+   if (section >= nand_chip->ecc.steps)
+   return -ERANGE;
+
+   oobregion->offset = 16 * section;
+   oobregion->length = 16 - nand_chip->ecc.bytes;
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops lpc32xx_ooblayout_ops = {
+   .ecc = lpc32xx_ooblayout_ecc,
+   .free = lpc32xx_ooblayout_free,
 };
 
 static struct nand_bbt_descr lpc32xx_nand_bbt = {
@@ -713,6 +728,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
nand_chip->ecc.write_oob = lpc32xx_write_oob;
nand_chip->ecc.read_oob = lpc32xx_read_oob;
nand_chip->ecc.strength = 4;
+   nand_chip->ecc.bytes = 10;
nand_chip->waitfunc = lpc32xx_waitfunc;
 
nand_chip->options = NAND_NO_SUBPAGE_WRITE;
@@ -751,7 +767,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
 
nand_chip->ecc.mode = NAND_ECC_HW;
nand_chip->ecc.size = 512;
-   nand_chip->ecc.layout = &lpc32xx_nand_oob;
+   mtd_set_ooblayout(mtd, &lpc32xx_ooblayout_ops);
host->mlcsubpages = mtd->writesize / 512;
 
/* initially clear interrupt status */
diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c
index 10cf8e62..219dd67 100644
--- a/drivers/mtd/nand/lpc32xx_slc.c
+++ b/drivers/mtd/nand/lpc32xx_slc.c
@@ -146,13 +146,38 @@
  * NAND ECC Layout for small page NAND devices
  * Note: For large and huge page devices, the default layouts are used
  */
-static struct nand_ecclayout lpc32xx_nand_oob_16 = {
-   .eccbytes = 6,
-   .eccpos = {10, 11, 12, 13, 14, 15},
-   .oobfree = {
-   { .offset = 0, .length = 4 },
-   { .offset = 6, .length = 4 },
-   },
+static int lpc32xx_ooblayout_ecc(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   if (section)
+   return -ERANGE;
+
+   oobregion->length = 6;
+   oobregion->offset = 10;
+
+   return 0;
+}
+
+static int lpc32xx_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   if (section > 1)
+   return -ERANGE;
+
+   if (!section) {
+   oobregion->offset = 0;
+   oobregion->length = 4;
+   } else {
+   oobregion->offset = 6;
+   oobregion->length = 4;
+   }
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops lpc32xx_ooblayout_ops = {
+   .ecc = lpc32xx_ooblayout_ecc,
+   .free = lpc32xx_ooblayout_free,
 };
 
 static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
@@ -886,7 +911,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
 * custom BBT marker layout.
 */
if (mtd->writesize <= 512)
-   chip->ecc.layout = &lpc32xx_nand_oob_16;
+   mtd_set_ooblayout(mtd, &lpc32xx_ooblayout_ops);
 
/* These sizes remain the same regardless of page size */
chip->ecc.size = 256;
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailma

[PATCH v5 49/50] mtd: nand: kill the ecc->layout field

2016-03-30 Thread Boris Brezillon
Now that all NAND drivers have switch to mtd_ooblayout_ops, we can kill
the ecc->layout field.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/nand_base.c | 7 ---
 drivers/mtd/nand/nand_bch.c  | 9 -
 include/linux/mtd/nand.h | 2 --
 3 files changed, 18 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 3d6985e..cf0c3180 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -4162,13 +4162,6 @@ int nand_scan_tail(struct mtd_info *mtd)
chip->oob_poi = chip->buffers->databuf + mtd->writesize;
 
/*
-* Set the provided ECC layout. If ecc->layout is NULL, the MTD core
-* will just leave mtd->ooblayout to NULL, if it's not NULL, it will
-* set ->ooblayout to the default ecclayout wrapper.
-*/
-   mtd_set_ecclayout(mtd, ecc->layout);
-
-   /*
 * If no default placement scheme is given, select an appropriate one.
 */
if (!mtd->ooblayout && (ecc->mode != NAND_ECC_SOFT_BCH)) {
diff --git a/drivers/mtd/nand/nand_bch.c b/drivers/mtd/nand/nand_bch.c
index e29e75f..ca9b2a4 100644
--- a/drivers/mtd/nand/nand_bch.c
+++ b/drivers/mtd/nand/nand_bch.c
@@ -158,15 +158,6 @@ struct nand_bch_control *nand_bch_init(struct mtd_info 
*mtd)
 
eccsteps = mtd->writesize/eccsize;
 
-   /*
-* Rely on the default ecclayout to ooblayout wrapper provided by MTD
-* core if ecc.layout is not NULL.
-* FIXME: this should be removed when all callers have moved to the
-* mtd_ooblayout_ops approach.
-*/
-   if (nand->ecc.layout)
-   mtd_set_ecclayout(mtd, nand->ecc.layout);
-
/* if no ecc placement scheme was provided, build one */
if (!mtd->ooblayout) {
 
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index a9796ba..d766c12 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -473,7 +473,6 @@ struct nand_hw_control {
  * @prepad:padding information for syndrome based ECC generators
  * @postpad:   padding information for syndrome based ECC generators
  * @options:   ECC specific options (see NAND_ECC_XXX flags defined above)
- * @layout:ECC layout control struct pointer
  * @priv:  pointer to private ECC control data
  * @hwctl: function to control hardware ECC generator. Must only
  * be provided if an hardware ECC is available
@@ -524,7 +523,6 @@ struct nand_ecc_ctrl {
int prepad;
int postpad;
unsigned int options;
-   struct nand_ecclayout   *layout;
void *priv;
void (*hwctl)(struct mtd_info *mtd, int mode);
int (*calculate)(struct mtd_info *mtd, const uint8_t *dat,
-- 
2.5.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 44/50] mtd: nand: sunxi: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/sunxi_nand.c | 114 +++---
 1 file changed, 52 insertions(+), 62 deletions(-)

diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index 1c03eee..4b9d984 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -212,12 +212,9 @@ struct sunxi_nand_chip_sel {
  * sunxi HW ECC infos: stores information related to HW ECC support
  *
  * @mode:  the sunxi ECC mode field deduced from ECC requirements
- * @layout:the OOB layout depending on the ECC requirements and the
- * selected ECC mode
  */
 struct sunxi_nand_hw_ecc {
int mode;
-   struct nand_ecclayout layout;
 };
 
 /*
@@ -1257,6 +1254,57 @@ static int sunxi_nand_chip_init_timings(struct 
sunxi_nand_chip *chip,
return sunxi_nand_chip_set_timings(chip, timings);
 }
 
+static int sunxi_nand_ooblayout_ecc(struct mtd_info *mtd, int section,
+   struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *nand = mtd_to_nand(mtd);
+   struct nand_ecc_ctrl *ecc = &nand->ecc;
+
+   if (section >= ecc->steps)
+   return -ERANGE;
+
+   oobregion->offset = section * (ecc->bytes + 4) + 4;
+   oobregion->length = ecc->bytes;
+
+   return 0;
+}
+
+static int sunxi_nand_ooblayout_free(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *nand = mtd_to_nand(mtd);
+   struct nand_ecc_ctrl *ecc = &nand->ecc;
+
+   if (section > ecc->steps)
+   return -ERANGE;
+
+   /*
+* The first 2 bytes are used for BB markers, hence we
+* only have 2 bytes available in the first user data
+* section.
+*/
+   if (!section && ecc->mode == NAND_ECC_HW) {
+   oobregion->offset = 2;
+   oobregion->length = 2;
+
+   return 0;
+   }
+
+   oobregion->offset = section * (ecc->bytes + 4);
+
+   if (section < ecc->steps)
+   oobregion->length = 4;
+   else
+   oobregion->offset = mtd->oobsize - oobregion->offset;
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops sunxi_nand_ooblayout_ops = {
+   .ecc = sunxi_nand_ooblayout_ecc,
+   .free = sunxi_nand_ooblayout_free,
+};
+
 static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
  struct nand_ecc_ctrl *ecc,
  struct device_node *np)
@@ -1266,7 +1314,6 @@ static int sunxi_nand_hw_common_ecc_ctrl_init(struct 
mtd_info *mtd,
struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
struct sunxi_nand_hw_ecc *data;
-   struct nand_ecclayout *layout;
int nsectors;
int ret;
int i;
@@ -1295,7 +1342,6 @@ static int sunxi_nand_hw_common_ecc_ctrl_init(struct 
mtd_info *mtd,
/* HW ECC always work with even numbers of ECC bytes */
ecc->bytes = ALIGN(ecc->bytes, 2);
 
-   layout = &data->layout;
nsectors = mtd->writesize / ecc->size;
 
if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) {
@@ -1303,9 +1349,7 @@ static int sunxi_nand_hw_common_ecc_ctrl_init(struct 
mtd_info *mtd,
goto err;
}
 
-   layout->eccbytes = (ecc->bytes * nsectors);
-
-   ecc->layout = layout;
+   mtd_set_ooblayout(mtd, &sunxi_nand_ooblayout_ops);
ecc->priv = data;
 
return 0;
@@ -1325,9 +1369,6 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info 
*mtd,
   struct nand_ecc_ctrl *ecc,
   struct device_node *np)
 {
-   struct nand_ecclayout *layout;
-   int nsectors;
-   int i, j;
int ret;
 
ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
@@ -1336,40 +1377,6 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info 
*mtd,
 
ecc->read_page = sunxi_nfc_hw_ecc_read_page;
ecc->write_page = sunxi_nfc_hw_ecc_write_page;
-   layout = ecc->layout;
-   nsectors = mtd->writesize / ecc->size;
-
-   for (i = 0; i < nsectors; i++) {
-   if (i) {
-   layout->oobfree[i].offset =
-   layout->oobfree[i - 1].offset +
-   layout->oobfree[i - 1].length +
-   ecc->bytes;
-   layout->oobfree[i].length = 4;
-   } else {
-   /*
-* The first 2 bytes are used for BB markers, hence we
-* only have 2 bytes available in the first user data
-* section.
-

[PATCH v5 31/50] mtd: nand: fsl_ifc: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/fsl_ifc_nand.c | 230 
 1 file changed, 66 insertions(+), 164 deletions(-)

diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index 2e970ac..5532c38 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -67,136 +67,6 @@ struct fsl_ifc_nand_ctrl {
 
 static struct fsl_ifc_nand_ctrl *ifc_nand_ctrl;
 
-/* 512-byte page with 4-bit ECC, 8-bit */
-static struct nand_ecclayout oob_512_8bit_ecc4 = {
-   .eccbytes = 8,
-   .eccpos = {8, 9, 10, 11, 12, 13, 14, 15},
-   .oobfree = { {0, 5}, {6, 2} },
-};
-
-/* 512-byte page with 4-bit ECC, 16-bit */
-static struct nand_ecclayout oob_512_16bit_ecc4 = {
-   .eccbytes = 8,
-   .eccpos = {8, 9, 10, 11, 12, 13, 14, 15},
-   .oobfree = { {2, 6}, },
-};
-
-/* 2048-byte page size with 4-bit ECC */
-static struct nand_ecclayout oob_2048_ecc4 = {
-   .eccbytes = 32,
-   .eccpos = {
-   8, 9, 10, 11, 12, 13, 14, 15,
-   16, 17, 18, 19, 20, 21, 22, 23,
-   24, 25, 26, 27, 28, 29, 30, 31,
-   32, 33, 34, 35, 36, 37, 38, 39,
-   },
-   .oobfree = { {2, 6}, {40, 24} },
-};
-
-/* 4096-byte page size with 4-bit ECC */
-static struct nand_ecclayout oob_4096_ecc4 = {
-   .eccbytes = 64,
-   .eccpos = {
-   8, 9, 10, 11, 12, 13, 14, 15,
-   16, 17, 18, 19, 20, 21, 22, 23,
-   24, 25, 26, 27, 28, 29, 30, 31,
-   32, 33, 34, 35, 36, 37, 38, 39,
-   40, 41, 42, 43, 44, 45, 46, 47,
-   48, 49, 50, 51, 52, 53, 54, 55,
-   56, 57, 58, 59, 60, 61, 62, 63,
-   64, 65, 66, 67, 68, 69, 70, 71,
-   },
-   .oobfree = { {2, 6}, {72, 56} },
-};
-
-/* 4096-byte page size with 8-bit ECC -- requires 218-byte OOB */
-static struct nand_ecclayout oob_4096_ecc8 = {
-   .eccbytes = 128,
-   .eccpos = {
-   8, 9, 10, 11, 12, 13, 14, 15,
-   16, 17, 18, 19, 20, 21, 22, 23,
-   24, 25, 26, 27, 28, 29, 30, 31,
-   32, 33, 34, 35, 36, 37, 38, 39,
-   40, 41, 42, 43, 44, 45, 46, 47,
-   48, 49, 50, 51, 52, 53, 54, 55,
-   56, 57, 58, 59, 60, 61, 62, 63,
-   64, 65, 66, 67, 68, 69, 70, 71,
-   72, 73, 74, 75, 76, 77, 78, 79,
-   80, 81, 82, 83, 84, 85, 86, 87,
-   88, 89, 90, 91, 92, 93, 94, 95,
-   96, 97, 98, 99, 100, 101, 102, 103,
-   104, 105, 106, 107, 108, 109, 110, 111,
-   112, 113, 114, 115, 116, 117, 118, 119,
-   120, 121, 122, 123, 124, 125, 126, 127,
-   128, 129, 130, 131, 132, 133, 134, 135,
-   },
-   .oobfree = { {2, 6}, {136, 82} },
-};
-
-/* 8192-byte page size with 4-bit ECC */
-static struct nand_ecclayout oob_8192_ecc4 = {
-   .eccbytes = 128,
-   .eccpos = {
-   8, 9, 10, 11, 12, 13, 14, 15,
-   16, 17, 18, 19, 20, 21, 22, 23,
-   24, 25, 26, 27, 28, 29, 30, 31,
-   32, 33, 34, 35, 36, 37, 38, 39,
-   40, 41, 42, 43, 44, 45, 46, 47,
-   48, 49, 50, 51, 52, 53, 54, 55,
-   56, 57, 58, 59, 60, 61, 62, 63,
-   64, 65, 66, 67, 68, 69, 70, 71,
-   72, 73, 74, 75, 76, 77, 78, 79,
-   80, 81, 82, 83, 84, 85, 86, 87,
-   88, 89, 90, 91, 92, 93, 94, 95,
-   96, 97, 98, 99, 100, 101, 102, 103,
-   104, 105, 106, 107, 108, 109, 110, 111,
-   112, 113, 114, 115, 116, 117, 118, 119,
-   120, 121, 122, 123, 124, 125, 126, 127,
-   128, 129, 130, 131, 132, 133, 134, 135,
-   },
-   .oobfree = { {2, 6}, {136, 208} },
-};
-
-/* 8192-byte page size with 8-bit ECC -- requires 218-byte OOB */
-static struct nand_ecclayout oob_8192_ecc8 = {
-   .eccbytes = 256,
-   .eccpos = {
-   8, 9, 10, 11, 12, 13, 14, 15,
-   16, 17, 18, 19, 20, 21, 22, 23,
-   24, 25, 26, 27, 28, 29, 30, 31,
-   32, 33, 34, 35, 36, 37, 38, 39,
-   40, 41, 42, 43, 44, 45, 46, 47,
-   48, 49, 50, 51, 52, 53, 54, 55,
-   56, 57, 58, 59, 60, 61, 62, 63,
-   64, 65, 66, 67, 68, 69, 70, 71,
-   72, 73, 74, 75, 76, 77, 78, 79,
-   80, 81, 82, 83, 84, 85, 86, 87,
-   88, 89, 90, 91, 92, 93, 94, 95,
-   96, 97, 98, 99, 100, 101, 102, 103,
-   104, 105, 106, 107, 108, 109, 110, 111,
-   112, 113, 114, 115, 116, 117, 118, 119,
-   120, 121, 122, 123, 124, 125, 126, 127,
-   128, 129, 130, 131, 132, 133, 134, 135,
-   136, 137, 138, 139, 140, 141, 142, 143,
-   144, 145, 146,

Re: [PATCH v5 00/52] mtd: rework ECC layout definition

2016-03-30 Thread Boris Brezillon
Despite what's said in the subject, this series only contains 50
patches, not 52.

On Wed, 30 Mar 2016 18:14:15 +0200
Boris Brezillon  wrote:

> Hello,
> 
> Hopefully the last version of this patchset (but don't be sad, I'm not
> done bothering you with NAND related patches :-)).
> 
> If possible, I'd like to have as much Tested/Reviewed/Acked-by tags as
> possible, particularly on the changes done in arch/arm and arch/mips
> (since the last set of commits depends on those changes, I'd like to
> take them in my nand/next branch, even if this imply creating an
> immutable branch for the ARM and MIPS maintainers).
> 
> If nobody complains about this version, I'll merge it in 4.7.
> 
> Here comes the usual description:
> 
> This patchset aims at getting rid of the nand_ecclayout limitations.
> struct nand_ecclayout is defining fixed eccpos and oobfree arrays which
> can only be increased by modifying the MTD_MAX_ECCPOS_ENTRIES_LARGE and
> MTD_MAX_OOBFREE_ENTRIES_LARGE macros.
> This approach forces us to modify the macro values each time we add a
> new NAND chip with a bigger OOB area, and increasing these arrays also
> penalize all platforms, even those who only support small NAND devices
> (with small OOB area).
> 
> The idea to overcome this limitation, is to define the ECC/OOB layout
> by the mean of two functions: ->ecc() and ->free(), which will
> basically return the same information has those stored in the
> nand_ecclayout struct.
> 
> Another advantage of this solution is that ECC layouts are usually
> following a repetitive pattern (i.e. leave X bytes free and put Y bytes
> of ECC per ECC chunk), which allows one to implement the ->ecc()
> and ->free() functions with a simple logic that can be applied
> to any size of OOB.
> 
> Patches 1 to 4 are just cleanups or trivial fixes that can be taken
> independently.
> 
> Also note that the last two commits are removing the nand_ecclayout
> definition, thus preventing any new driver to use this structure.
> Of course, this step can be delayed if some of the previous patches
> are not accepted.
> 
> All those changes are available here [1].
> 
> Best Regards,
> 
> Boris
> 
> [1]https://github.com/bbrezillon/linux-0day/tree/nand/ecclayout
> 
> Changes since v4:
> - dropped already applied patches
> - patch the recently merged qcom driver
> 
> Changes since v3:
> - fixed two bugs in mtd_ooblayout core implementation
> - use ecc->total instead of (ecc->steps * ecc->bytes) in NAND drivers
> 
> Changes since v2:
> - fixed a few bugs in the core and driver implementations
> 
> Changes since v1:
> - unified the way of defining ECC and free bytes
> - fixed a few bugs in some ->ecc()/->free() implementations
> 
> Boris Brezillon (50):
>   mtd: add mtd_ooblayout_xxx() helper functions
>   mtd: use mtd_ooblayout_xxx() helpers where appropriate
>   mtd: nand: core: use mtd_ooblayout_xxx() helpers where appropriate
>   mtd: nand: atmel: use mtd_ooblayout_xxx() helpers where appropriate
>   mtd: nand: fsl_ifc: use mtd_ooblayout_xxx() helpers where appropriate
>   mtd: nand: gpmi: use mtd_ooblayout_xxx() helpers where appropriate
>   mtd: nand: lpc32xx: use mtd_ooblayout_xxx() helpers where appropriate
>   mtd: nand: omap2: use mtd_ooblayout_xxx() helpers where appropriate
>   mtd: nand: qcom: use mtd_ooblayout_xxx() helpers where appropriate
>   mtd: onenand: use mtd_ooblayout_xxx() helpers where appropriate
>   mtd: add mtd_set_ecclayout() helper function
>   mtd: use mtd_set_ecclayout() where appropriate
>   mtd: nand: use mtd_set_ecclayout() where appropriate
>   mtd: onenand: use mtd_set_ecclayout() where appropriate
>   mtd: docg3: use mtd_set_ecclayout() where appropriate
>   mtd: create an mtd_ooblayout_ops struct to ease ECC layout definition
>   mtd: docg3: switch to mtd_ooblayout_ops
>   mtd: nand: implement the default mtd_ooblayout_ops
>   mtd: nand: bch: switch to mtd_ooblayout_ops
>   mtd: nand: sharpsl: switch to mtd_ooblayout_ops
>   mtd: nand: jz4740: switch to mtd_ooblayout_ops
>   mtd: nand: atmel: switch to mtd_ooblayout_ops
>   mtd: nand: bf5xx: switch to mtd_ooblayout_ops
>   mtd: nand: brcm: switch to mtd_ooblayout_ops
>   mtd: nand: cafe: switch to mtd_ooblayout_ops
>   mtd: nand: davinci: switch to mtd_ooblayout_ops
>   mtd: nand: denali: switch to mtd_ooblayout_ops
>   mtd: nand: diskonchip: switch to mtd_ooblayout_ops
>   mtd: nand: docg4: switch to mtd_ooblayout_ops
>   mtd: nand: fsl_elbc: switch to mtd_ooblayout_ops
>   mtd: nand: fsl_ifc: switch to mtd_ooblayout_ops
>   mtd: nand: fsmc: switch to mtd_ooblayout_ops
>   mtd: nand: fsmc: get rid of the fsmc_nand_eccplace struct
>   mtd: nand: gpmi: switch to mtd_ooblayout_ops
>   mtd: nand: hisi504: switch to mtd_ooblayout_ops
>   mtd: nand: jz4780: switch to mtd_ooblayout_ops
>   mtd: nand: lpc32xx: switch to mtd_ooblayout_ops
>   mtd: nand: mxc: switch to mtd_ooblayout_ops
>   mtd: nand: omap2: switch to mtd_ooblayout_ops
>   mtd: nand: pxa3xx: switch to mtd_ooblayout_ops
>   mtd: nand: s3c

[PATCH v5 40/50] mtd: nand: pxa3xx: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/pxa3xx_nand.c | 104 +
 1 file changed, 64 insertions(+), 40 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index d650885..ce2e2d9 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -324,6 +324,62 @@ static struct pxa3xx_nand_flash builtin_flash_types[] = {
{ 0xba20, 16, 16, &timing[3] },
 };
 
+static int pxa3xx_ooblayout_ecc(struct mtd_info *mtd, int section,
+   struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
+   struct pxa3xx_nand_info *info = host->info_data;
+   int nchunks = mtd->writesize / info->chunk_size;
+
+   if (section >= nchunks)
+   return -ERANGE;
+
+   oobregion->offset = ((info->ecc_size + info->spare_size) * section) +
+   info->spare_size;
+   oobregion->length = info->ecc_size;
+
+   return 0;
+}
+
+static int pxa3xx_ooblayout_free(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
+   struct pxa3xx_nand_info *info = host->info_data;
+   int nchunks = mtd->writesize / info->chunk_size;
+
+   if (section >= nchunks)
+   return -ERANGE;
+
+   if (!info->spare_size)
+   return 0;
+
+   oobregion->offset = section * (info->ecc_size + info->spare_size);
+   oobregion->length = info->spare_size;
+   if (!section) {
+   /*
+* Bootrom looks in bytes 0 & 5 for bad blocks for the
+* 4KB page / 4bit BCH combination.
+*/
+   if (mtd->writesize == 4096 && info->chunk_size == 2048) {
+   oobregion->offset += 6;
+   oobregion->length -= 6;
+   } else {
+   oobregion->offset += 2;
+   oobregion->length -= 2;
+   }
+   }
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops pxa3xx_ooblayout_ops = {
+   .ecc = pxa3xx_ooblayout_ecc,
+   .free = pxa3xx_ooblayout_free,
+};
+
 static u8 bbt_pattern[] = {'M', 'V', 'B', 'b', 't', '0' };
 static u8 bbt_mirror_pattern[] = {'1', 't', 'b', 'B', 'V', 'M' };
 
@@ -347,41 +403,6 @@ static struct nand_bbt_descr bbt_mirror_descr = {
.pattern = bbt_mirror_pattern
 };
 
-static struct nand_ecclayout ecc_layout_2KB_bch4bit = {
-   .eccbytes = 32,
-   .eccpos = {
-   32, 33, 34, 35, 36, 37, 38, 39,
-   40, 41, 42, 43, 44, 45, 46, 47,
-   48, 49, 50, 51, 52, 53, 54, 55,
-   56, 57, 58, 59, 60, 61, 62, 63},
-   .oobfree = { {2, 30} }
-};
-
-static struct nand_ecclayout ecc_layout_4KB_bch4bit = {
-   .eccbytes = 64,
-   .eccpos = {
-   32,  33,  34,  35,  36,  37,  38,  39,
-   40,  41,  42,  43,  44,  45,  46,  47,
-   48,  49,  50,  51,  52,  53,  54,  55,
-   56,  57,  58,  59,  60,  61,  62,  63,
-   96,  97,  98,  99,  100, 101, 102, 103,
-   104, 105, 106, 107, 108, 109, 110, 111,
-   112, 113, 114, 115, 116, 117, 118, 119,
-   120, 121, 122, 123, 124, 125, 126, 127},
-   /* Bootrom looks in bytes 0 & 5 for bad blocks */
-   .oobfree = { {6, 26}, { 64, 32} }
-};
-
-static struct nand_ecclayout ecc_layout_4KB_bch8bit = {
-   .eccbytes = 128,
-   .eccpos = {
-   32,  33,  34,  35,  36,  37,  38,  39,
-   40,  41,  42,  43,  44,  45,  46,  47,
-   48,  49,  50,  51,  52,  53,  54,  55,
-   56,  57,  58,  59,  60,  61,  62,  63},
-   .oobfree = { }
-};
-
 #define NDTR0_tCH(c)   (min((c), 7) << 19)
 #define NDTR0_tCS(c)   (min((c), 7) << 16)
 #define NDTR0_tWH(c)   (min((c), 7) << 11)
@@ -1546,9 +1567,12 @@ static void pxa3xx_nand_free_buff(struct 
pxa3xx_nand_info *info)
 }
 
 static int pxa_ecc_init(struct pxa3xx_nand_info *info,
-   struct nand_ecc_ctrl *ecc,
+   struct mtd_info *mtd,
int strength, int ecc_stepsize, int page_size)
 {
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   struct nand_ecc_ctrl *ecc = &chip->ecc;
+
if (strength == 1 && ecc_stepsize == 512 && page_size == 2048) {
info->nfullchunks = 1;
info->ntotalchunks = 1;
@@ -1582,7 +1606,7 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info,
info->ecc_size = 32;
ecc->mode = NAND_ECC_HW;
ecc->size = info->chunk_size;
- 

[PATCH v5 39/50] mtd: nand: omap2: switch to mtd_ooblayout_ops

2016-03-30 Thread Boris Brezillon
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

Signed-off-by: Boris Brezillon 
---
 drivers/mtd/nand/omap2.c | 194 +++
 1 file changed, 113 insertions(+), 81 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 4ebf16b..bca154a 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -169,8 +169,6 @@ struct omap_nand_info {
u_char  *buf;
int buf_len;
struct gpmc_nand_regs   reg;
-   /* generated at runtime depending on ECC algorithm and layout selected 
*/
-   struct nand_ecclayout   oobinfo;
/* fields specific for BCHx_HW ECC scheme */
struct device   *elm_dev;
struct device_node  *of_node;
@@ -1639,19 +1637,108 @@ static bool omap2_nand_ecc_check(struct omap_nand_info 
*info,
return true;
 }
 
+static int omap_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   int off = chip->options & NAND_BUSWIDTH_16 ?
+ BADBLOCK_MARKER_LENGTH : 1;
+
+   if (section)
+   return -ERANGE;
+
+   oobregion->offset = off;
+   oobregion->length = chip->ecc.total;
+
+   return 0;
+}
+
+static int omap_ooblayout_free(struct mtd_info *mtd, int section,
+  struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   int off = chip->options & NAND_BUSWIDTH_16 ?
+ BADBLOCK_MARKER_LENGTH : 1;
+
+   if (section)
+   return -ERANGE;
+
+   off += chip->ecc.total;
+   if (off >= mtd->oobsize)
+   return -ERANGE;
+
+   oobregion->offset = off;
+   oobregion->length = mtd->oobsize - off;
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops omap_ooblayout_ops = {
+   .ecc = omap_ooblayout_ecc,
+   .free = omap_ooblayout_free,
+};
+
+static int omap_sw_ooblayout_ecc(struct mtd_info *mtd, int section,
+struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   int off = chip->options & NAND_BUSWIDTH_16 ?
+ BADBLOCK_MARKER_LENGTH : 1;
+
+   if (section >= chip->ecc.steps)
+   return -ERANGE;
+
+   /*
+* When SW correction is employed, one OMAP specific marker byte is
+* reserved after each ECC step.
+*/
+   oobregion->offset = off + (section * (chip->ecc.bytes + 1));
+   oobregion->length = chip->ecc.bytes;
+
+   return 0;
+}
+
+static int omap_sw_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   int off = chip->options & NAND_BUSWIDTH_16 ?
+ BADBLOCK_MARKER_LENGTH : 1;
+
+   if (section)
+   return -ERANGE;
+
+   /*
+* When SW correction is employed, one OMAP specific marker byte is
+* reserved after each ECC step.
+*/
+   off += ((chip->ecc.bytes + 1) * chip->ecc.steps);
+   if (off >= mtd->oobsize)
+   return -ERANGE;
+
+   oobregion->offset = off;
+   oobregion->length = mtd->oobsize - off;
+
+   return 0;
+}
+
+static const struct mtd_ooblayout_ops omap_sw_ooblayout_ops = {
+   .ecc = omap_sw_ooblayout_ecc,
+   .free = omap_sw_ooblayout_free,
+};
+
 static int omap_nand_probe(struct platform_device *pdev)
 {
struct omap_nand_info   *info;
struct omap_nand_platform_data  *pdata;
struct mtd_info *mtd;
struct nand_chip*nand_chip;
-   struct nand_ecclayout   *ecclayout;
int err;
-   int i;
dma_cap_mask_t  mask;
unsignedsig;
-   unsignedoob_index;
struct resource *res;
+   int min_oobbytes;
+   int oobbytes_per_step;
 
pdata = dev_get_platdata(&pdev->dev);
if (pdata == NULL) {
@@ -1810,7 +1897,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 
/*
 * Bail out earlier to let NAND_ECC_SOFT code create its own
-* ecclayout instead of using ours.
+* ooblayout instead of using ours.
 */
if (info->ecc_opt == OMAP_ECC_HAM1_CODE_SW) {
nand_chip->ecc.mode = NAND_ECC_SOFT;
@@ -1818,8 +1905,6 @@ static int omap_nand_probe(struct platform_device *pdev)
}
 
/* populate MTD interface based on ECC scheme */
-   ecclayout   = &info->oobinfo;

[PATCH 02/43] staging/lustre: Get rid of CFS_PAGE_MASK

2016-03-30 Thread green
From: Oleg Drokin 

CFS_PAGE_MASK is the same as PAGE_MASK, so get rid of it.

We are replacing it with PAGE_MASK instead of PAGE_CACHE_MASK
because PAGE_CACHE_* stuff is apparently going away.

Signed-off-by: Oleg Drokin 
---
 .../lustre/include/linux/libcfs/linux/linux-mem.h  |  1 -
 .../lustre/lnet/libcfs/linux/linux-crypto.c|  2 +-
 drivers/staging/lustre/lnet/selftest/brw_test.c|  2 +-
 drivers/staging/lustre/lustre/llite/llite_mmap.c   |  4 ++--
 drivers/staging/lustre/lustre/llite/rw26.c |  8 
 drivers/staging/lustre/lustre/llite/vvp_io.c   |  6 +++---
 drivers/staging/lustre/lustre/lmv/lmv_obd.c|  2 +-
 drivers/staging/lustre/lustre/obdclass/class_obd.c |  2 +-
 .../staging/lustre/lustre/obdecho/echo_client.c|  6 +++---
 drivers/staging/lustre/lustre/osc/osc_cache.c  |  4 ++--
 drivers/staging/lustre/lustre/osc/osc_request.c| 24 +++---
 drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c|  2 +-
 drivers/staging/lustre/lustre/ptlrpc/sec_plain.c   |  2 +-
 13 files changed, 32 insertions(+), 33 deletions(-)

diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h 
b/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h
index 0f2fd79..448379b 100644
--- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h
+++ b/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h
@@ -57,7 +57,6 @@
 #include "../libcfs_cpu.h"
 #endif
 
-#define CFS_PAGE_MASK (~((__u64)PAGE_CACHE_SIZE-1))
 #define page_index(p)   ((p)->index)
 
 #define memory_pressure_get() (current->flags & PF_MEMALLOC)
diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c 
b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c
index 0715101..84f9b7b 100644
--- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c
+++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c
@@ -227,7 +227,7 @@ int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc 
*hdesc,
struct scatterlist sl;
 
sg_init_table(&sl, 1);
-   sg_set_page(&sl, page, len, offset & ~CFS_PAGE_MASK);
+   sg_set_page(&sl, page, len, offset & ~PAGE_MASK);
 
ahash_request_set_crypt(req, &sl, NULL, sl.length);
return crypto_ahash_update(req);
diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c 
b/drivers/staging/lustre/lnet/selftest/brw_test.c
index b33c356..1988cee 100644
--- a/drivers/staging/lustre/lnet/selftest/brw_test.c
+++ b/drivers/staging/lustre/lnet/selftest/brw_test.c
@@ -457,7 +457,7 @@ brw_server_handle(struct srpc_server_rpc *rpc)
 
if (!(reqstmsg->msg_ses_feats & LST_FEAT_BULK_LEN)) {
/* compat with old version */
-   if (reqst->brw_len & ~CFS_PAGE_MASK) {
+   if (reqst->brw_len & ~PAGE_MASK) {
reply->brw_status = EINVAL;
return 0;
}
diff --git a/drivers/staging/lustre/lustre/llite/llite_mmap.c 
b/drivers/staging/lustre/lustre/llite/llite_mmap.c
index 69445a9..baccf93 100644
--- a/drivers/staging/lustre/lustre/llite/llite_mmap.c
+++ b/drivers/staging/lustre/lustre/llite/llite_mmap.c
@@ -57,10 +57,10 @@ void policy_from_vma(ldlm_policy_data_t *policy,
 struct vm_area_struct *vma, unsigned long addr,
 size_t count)
 {
-   policy->l_extent.start = ((addr - vma->vm_start) & CFS_PAGE_MASK) +
+   policy->l_extent.start = ((addr - vma->vm_start) & PAGE_MASK) +
 (vma->vm_pgoff << PAGE_CACHE_SHIFT);
policy->l_extent.end = (policy->l_extent.start + count - 1) |
-  ~CFS_PAGE_MASK;
+  ~PAGE_MASK;
 }
 
 struct vm_area_struct *our_vma(struct mm_struct *mm, unsigned long addr,
diff --git a/drivers/staging/lustre/lustre/llite/rw26.c 
b/drivers/staging/lustre/lustre/llite/rw26.c
index 7a5db67..3d7e64e 100644
--- a/drivers/staging/lustre/lustre/llite/rw26.c
+++ b/drivers/staging/lustre/lustre/llite/rw26.c
@@ -376,7 +376,7 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct 
iov_iter *iter,
return -EBADF;
 
/* FIXME: io smaller than PAGE_SIZE is broken on ia64 ??? */
-   if ((file_offset & ~CFS_PAGE_MASK) || (count & ~CFS_PAGE_MASK))
+   if ((file_offset & ~PAGE_MASK) || (count & ~PAGE_MASK))
return -EINVAL;
 
CDEBUG(D_VFSTRACE,
@@ -386,7 +386,7 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct 
iov_iter *iter,
   MAX_DIO_SIZE >> PAGE_CACHE_SHIFT);
 
/* Check that all user buffers are aligned as well */
-   if (iov_iter_alignment(iter) & ~CFS_PAGE_MASK)
+   if (iov_iter_alignment(iter) & ~PAGE_MASK)
return -EINVAL;
 
env = cl_env_get(&refcheck);
@@ -435,8 +435,8 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct 
iov_iter *iter,
size > (PAGE_CACHE_SIZE / sizeof(*pages)) *
 

[PATCH 00/43] Lustre IO stack simplifications and cleanups

2016-03-30 Thread green
From: Oleg Drokin 

This large body of patches mostly deals with Lustre IO stack
simplifications and related cleanups.
In particular the whole cl_page and cl_lock stuff is reduced to
basically nothing.
The simplifications remove about 5K lines of code and the other 5k
are mostly due to shuffling code around and renaming stuff
to get rid of now defunct layers.

Bobi Jam (1):
  staging/lustre: update comments after cl_lock simplification

Jinshan Xiong (14):
  staging/lustre: Reintroduce global env list
  staging/lustre/osc: Adjustment on osc LRU for performance
  staging/lustre/osc: to drop LRU pages with cl_lru_work
  staging/lustre/clio: collapse layer of cl_page
  staging/lustre/obdclass: Add a preallocated percpu cl_env
  staging/lustre/clio: add pages into writeback cache in batches
  staging/lustre/osc: add weight function for DLM lock
  staging/lustre/clio: remove stackable cl_page completely
  staging/lustre/clio: optimize read ahead code
  staging/lustre/clio: generalize cl_sync_io
  staging/lustre/clio: cl_lock simplification
  staging/lustre/llite: clip page correctly for vvp_io_commit_sync
  staging/lustre/llite: deadlock for page write
  staging/lustre/ldlm: ELC picks locks in a safer policy

John Hammond (5):
  staging/lustre/llite: Rename struct ccc_grouplock to ll_grouplock
  staging/lustre/llite: Rename struct vvp_thread_info to ll_thread_info
  staging/lustre/llite: rename struct ccc_thread_info to vvp_thread_info
  staging/lustre/llite: Remove ccc_global_{init,fini}()
  staging/lustre/llite: Move several declarations to llite_internal.h

John L. Hammond (15):
  staging/lustre: merge lclient/*.c into llite/
  staging/lustre/llite: remove lli_lvb
  staging/lustre/lmv: remove lmv_init_{lock,unlock}()
  staging/lustre/obd: remove struct client_obd_lock
  staging/lustre/llite: remove some cl wrappers
  staging/lustre/llite: merge lclient.h into llite/vvp_internal.h
  staging/lustre/llite: rename ccc_device to vvp_device
  staging/lustre/llite: rename ccc_object to vvp_object
  staging/lustre/llite: rename ccc_page to vvp_page
  staging/lustre/llite: rename ccc_lock to vvp_lock
  staging/lustre:llite: remove struct ll_ra_read
  staging/lustre/llite: merge ccc_io and vvp_io
  staging/lustre/llite: use vui prefix for struct vvp_io members
  staging/lustre/llite: move vvp_io functions to vvp_io.c
  staging/lustre/llite: rename ccc_req to vvp_req

Li Dongyang (1):
  staging/lustre/llite: make sure we do cl_page_clip on the last page

Niu Yawei (1):
  staging/lustre/ldlm: revert changes to ldlm_cancel_aged_policy()

Oleg Drokin (5):
  staging/lustre/obdclass: limit lu_site hash table size
  staging/lustre: Get rid of CFS_PAGE_MASK
  staging/lustre: Remove struct ll_iattr
  staging/lustre/llite: Move ll_dirent_type_get and make it static
  staging/lustre/llite: Remove unused vui_local_lock field

Vitaly Fertman (1):
  staging/lustre/ldlm: restore the ELC for enqueue

 .../lustre/include/linux/libcfs/linux/linux-mem.h  |1 -
 .../lustre/lnet/libcfs/linux/linux-crypto.c|2 +-
 drivers/staging/lustre/lnet/selftest/brw_test.c|2 +-
 drivers/staging/lustre/lustre/fld/fld_request.c|   14 +-
 drivers/staging/lustre/lustre/include/cl_object.h  |  962 ++---
 drivers/staging/lustre/lustre/include/lclient.h|  408 
 drivers/staging/lustre/lustre/include/linux/obd.h  |  125 --
 .../lustre/lustre/include/lustre/lustre_idl.h  |2 +
 drivers/staging/lustre/lustre/include/lustre_dlm.h |   14 +-
 drivers/staging/lustre/lustre/include/obd.h|   14 +-
 drivers/staging/lustre/lustre/lclient/glimpse.c|  270 ---
 drivers/staging/lustre/lustre/lclient/lcommon_cl.c | 1203 ---
 .../staging/lustre/lustre/lclient/lcommon_misc.c   |  200 --
 drivers/staging/lustre/lustre/ldlm/ldlm_internal.h |7 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_lib.c  |5 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c |3 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_request.c  |   74 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |1 +
 drivers/staging/lustre/lustre/llite/Makefile   |5 +-
 drivers/staging/lustre/lustre/llite/dir.c  |   24 +-
 drivers/staging/lustre/lustre/llite/file.c |  133 +-
 drivers/staging/lustre/lustre/llite/glimpse.c  |  255 +++
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   |  327 +++
 drivers/staging/lustre/lustre/llite/lcommon_misc.c |  201 ++
 drivers/staging/lustre/lustre/llite/llite_close.c  |   28 +-
 .../staging/lustre/lustre/llite/llite_internal.h   |  244 +--
 drivers/staging/lustre/lustre/llite/llite_lib.c|   21 +-
 drivers/staging/lustre/lustre/llite/llite_mmap.c   |   38 +-
 drivers/staging/lustre/lustre/llite/lproc_llite.c  |   10 +-
 drivers/staging/lustre/lustre/llite/rw.c   |  363 ++--
 drivers/staging/lustre/lustre/llite/rw26.c |  304 ++-
 drivers/staging/lustre/lustre/llite/super25.c  |   14 +-
 drivers/staging/lustre/lustre/llite/vvp_dev.c  |  253 ++-
 dri

[PATCH 04/43] staging/lustre: Reintroduce global env list

2016-03-30 Thread green
From: Jinshan Xiong 

This reverts a patch that was merged before lustre client
was introduced into the staging tree, so it's not in the history.

The performance dropped a lot when memory reclaim process kicked
in as ll_releasepage() was called to destroy lustre pages. It turned
out that big overhead to allocate cl_env and keys on the fly so we
have to revert this patch.

The original problem for the reverted patch would be solved in a
follow on patch instead.

Signed-off-by: Jinshan Xiong 
Reviewed-on: http://review.whamcloud.com/7888
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3321
Reviewed-by: Niu Yawei 
Reviewed-by: Lai Siyao 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/cl_object.h  |  1 +
 drivers/staging/lustre/lustre/llite/lcommon_misc.c |  3 +-
 drivers/staging/lustre/lustre/llite/llite_lib.c|  2 +
 drivers/staging/lustre/lustre/obdclass/cl_object.c | 90 --
 drivers/staging/lustre/lustre/obdclass/lu_object.c |  2 +
 5 files changed, 92 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h 
b/drivers/staging/lustre/lustre/include/cl_object.h
index fb971de..e611f79 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -3241,6 +3241,7 @@ void *cl_env_reenter(void);
 void cl_env_reexit(void *cookie);
 void cl_env_implant(struct lu_env *env, int *refcheck);
 void cl_env_unplant(struct lu_env *env, int *refcheck);
+unsigned int cl_env_cache_purge(unsigned int nr);
 
 /** @} cl_env */
 
diff --git a/drivers/staging/lustre/lustre/llite/lcommon_misc.c 
b/drivers/staging/lustre/lustre/llite/lcommon_misc.c
index d80bcedd..f68c368 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_misc.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_misc.c
@@ -146,10 +146,11 @@ int cl_get_grouplock(struct cl_object *obj, unsigned long 
gid, int nonblock,
 
rc = cl_io_init(env, io, CIT_MISC, io->ci_obj);
if (rc) {
+   cl_io_fini(env, io);
+   cl_env_put(env, &refcheck);
/* Does not make sense to take GL for released layout */
if (rc > 0)
rc = -ENOTSUPP;
-   cl_env_put(env, &refcheck);
return rc;
}
 
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c 
b/drivers/staging/lustre/lustre/llite/llite_lib.c
index 6d6bb33..673d31e 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -999,6 +999,8 @@ void ll_put_super(struct super_block *sb)
 
lustre_common_put_super(sb);
 
+   cl_env_cache_purge(~0);
+
module_put(THIS_MODULE);
 } /* client_put_super */
 
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c 
b/drivers/staging/lustre/lustre/obdclass/cl_object.c
index 43e299d..0772706 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
@@ -492,6 +492,13 @@ EXPORT_SYMBOL(cl_site_stats_print);
  * bz20044, bz22683.
  */
 
+static LIST_HEAD(cl_envs);
+static unsigned int cl_envs_cached_nr;
+static unsigned int cl_envs_cached_max = 128; /* XXX: prototype: arbitrary 
limit
+  * for now.
+  */
+static DEFINE_SPINLOCK(cl_envs_guard);
+
 struct cl_env {
void *ce_magic;
struct lu_env ce_lu;
@@ -697,6 +704,39 @@ static void cl_env_fini(struct cl_env *cle)
kmem_cache_free(cl_env_kmem, cle);
 }
 
+static struct lu_env *cl_env_obtain(void *debug)
+{
+   struct cl_env *cle;
+   struct lu_env *env;
+
+   spin_lock(&cl_envs_guard);
+   LASSERT(equi(cl_envs_cached_nr == 0, list_empty(&cl_envs)));
+   if (cl_envs_cached_nr > 0) {
+   int rc;
+
+   cle = container_of(cl_envs.next, struct cl_env, ce_linkage);
+   list_del_init(&cle->ce_linkage);
+   cl_envs_cached_nr--;
+   spin_unlock(&cl_envs_guard);
+
+   env = &cle->ce_lu;
+   rc = lu_env_refill(env);
+   if (rc == 0) {
+   cl_env_init0(cle, debug);
+   lu_context_enter(&env->le_ctx);
+   lu_context_enter(&cle->ce_ses);
+   } else {
+   cl_env_fini(cle);
+   env = ERR_PTR(rc);
+   }
+   } else {
+   spin_unlock(&cl_envs_guard);
+   env = cl_env_new(lu_context_tags_default,
+lu_session_tags_default, debug);
+   }
+   return env;
+}
+
 static inline struct cl_env *cl_env_container(struct lu_env *env)
 {
return container_of(env, struct cl_env, ce_lu);
@@ -727,6 +767,8 @@ static struct lu_env *cl_env_peek(int *refcheck)
  * Returns lu_env: if there already is an environment associated with the
  * curr

[PATCH 01/43] staging/lustre/obdclass: limit lu_site hash table size

2016-03-30 Thread green
From: Oleg Drokin 

Allocating a big hash table using the formula for osd
does not really work for clients. We will create new
hash table for each mount on a single client which is
a lot of memory more than expected.

This patch limits the hash table up to 8M which has
524288 entries

Signed-off-by: Li Dongyang 
Reviewed-on: http://review.whamcloud.com/18048
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-7689
Reviewed-by: Fan Yong 
Reviewed-by: Alex Zhuravlev 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/obdclass/lu_object.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c 
b/drivers/staging/lustre/lustre/obdclass/lu_object.c
index 65a4746..69fdcee 100644
--- a/drivers/staging/lustre/lustre/obdclass/lu_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c
@@ -935,7 +935,7 @@ static void lu_dev_add_linkage(struct lu_site *s, struct 
lu_device *d)
  * Initialize site \a s, with \a d as the top level device.
  */
 #define LU_SITE_BITS_MIN12
-#define LU_SITE_BITS_MAX24
+#define LU_SITE_BITS_MAX19
 /**
  * total 256 buckets, we don't want too many buckets because:
  * - consume too much memory
-- 
2.1.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 08/43] staging/lustre/obdclass: Add a preallocated percpu cl_env

2016-03-30 Thread green
From: Jinshan Xiong 

This change adds support for a single preallocated cl_env per CPU
which can be used in circumstances where reschedule is not possible.
Currently this interface is only used by the ll_releasepage function.

Signed-off-by: Jinshan Xiong 
Signed-off-by: Prakash Surya 
Reviewed-on: http://review.whamcloud.com/8174
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3321
Reviewed-by: Lai Siyao 
Reviewed-by: Bobi Jam 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/cl_object.h  |  12 +++
 drivers/staging/lustre/lustre/llite/rw26.c |  54 +++
 drivers/staging/lustre/lustre/obdclass/cl_lock.c   |   1 -
 drivers/staging/lustre/lustre/obdclass/cl_object.c | 107 +
 drivers/staging/lustre/lustre/obdclass/cl_page.c   |   1 -
 5 files changed, 152 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h 
b/drivers/staging/lustre/lustre/include/cl_object.h
index 5daf688..e8455dc 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -2773,6 +2773,16 @@ static inline void *cl_object_page_slice(struct 
cl_object *clob,
return (void *)((char *)page + clob->co_slice_off);
 }
 
+/**
+ * Return refcount of cl_object.
+ */
+static inline int cl_object_refc(struct cl_object *clob)
+{
+   struct lu_object_header *header = clob->co_lu.lo_header;
+
+   return atomic_read(&header->loh_ref);
+}
+
 /** @} cl_object */
 
 /** \defgroup cl_page cl_page
@@ -3226,6 +3236,8 @@ void cl_env_reexit(void *cookie);
 void cl_env_implant(struct lu_env *env, int *refcheck);
 void cl_env_unplant(struct lu_env *env, int *refcheck);
 unsigned int cl_env_cache_purge(unsigned int nr);
+struct lu_env *cl_env_percpu_get(void);
+void cl_env_percpu_put(struct lu_env *env);
 
 /** @} cl_env */
 
diff --git a/drivers/staging/lustre/lustre/llite/rw26.c 
b/drivers/staging/lustre/lustre/llite/rw26.c
index b5335de..cc49c21 100644
--- a/drivers/staging/lustre/lustre/llite/rw26.c
+++ b/drivers/staging/lustre/lustre/llite/rw26.c
@@ -107,12 +107,12 @@ static void ll_invalidatepage(struct page *vmpage, 
unsigned int offset,
 
 static int ll_releasepage(struct page *vmpage, gfp_t gfp_mask)
 {
-   struct cl_env_nest nest;
struct lu_env *env;
+   void*cookie;
struct cl_object  *obj;
struct cl_page*page;
struct address_space *mapping;
-   int result;
+   int result = 0;
 
LASSERT(PageLocked(vmpage));
if (PageWriteback(vmpage) || PageDirty(vmpage))
@@ -126,30 +126,42 @@ static int ll_releasepage(struct page *vmpage, gfp_t 
gfp_mask)
if (!obj)
return 1;
 
-   /* 1 for page allocator, 1 for cl_page and 1 for page cache */
+   /* 1 for caller, 1 for cl_page and 1 for page cache */
if (page_count(vmpage) > 3)
return 0;
 
-   /* TODO: determine what gfp should be used by @gfp_mask. */
-   env = cl_env_nested_get(&nest);
-   if (IS_ERR(env))
-   /* If we can't allocate an env we won't call cl_page_put()
-* later on which further means it's impossible to drop
-* page refcount by cl_page, so ask kernel to not free
-* this page.
-*/
-   return 0;
-
page = cl_vmpage_page(vmpage, obj);
-   result = !page;
-   if (page) {
-   if (!cl_page_in_use(page)) {
-   result = 1;
-   cl_page_delete(env, page);
-   }
-   cl_page_put(env, page);
+   if (!page)
+   return 1;
+
+   cookie = cl_env_reenter();
+   env = cl_env_percpu_get();
+   LASSERT(!IS_ERR(env));
+
+   if (!cl_page_in_use(page)) {
+   result = 1;
+   cl_page_delete(env, page);
}
-   cl_env_nested_put(&nest, env);
+
+   /* To use percpu env array, the call path can not be rescheduled;
+* otherwise percpu array will be messed if ll_releaspage() called
+* again on the same CPU.
+*
+* If this page holds the last refc of cl_object, the following
+* call path may cause reschedule:
+*   cl_page_put -> cl_page_free -> cl_object_put ->
+* lu_object_put -> lu_object_free -> lov_delete_raid0 ->
+* cl_locks_prune.
+*
+* However, the kernel can't get rid of this inode until all pages have
+* been cleaned up. Now that we hold page lock here, it's pretty safe
+* that we won't get into object delete path.
+*/
+   LASSERT(cl_object_refc(obj) > 1);
+   cl_page_put(env, page);
+
+   cl_env_percpu_put(env);
+   cl_env_reexit(cookie);
return result;
 }
 
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c 
b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
index 32ecc5a..fe8059a 100644
--- a/drivers/stagi

[PATCH 07/43] staging/lustre/clio: collapse layer of cl_page

2016-03-30 Thread green
From: Jinshan Xiong 

Move radix tree to osc layer too for performance improvement.

Signed-off-by: Jinshan Xiong 
Reviewed-on: http://review.whamcloud.com/7892
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3321
Reviewed-by: Lai Siyao 
Reviewed-by: Bobi Jam 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/cl_object.h  |  36 +--
 drivers/staging/lustre/lustre/llite/rw.c   |   2 +-
 drivers/staging/lustre/lustre/llite/rw26.c |   4 -
 drivers/staging/lustre/lustre/llite/vvp_dev.c  |  47 +--
 drivers/staging/lustre/lustre/llite/vvp_io.c   |   1 -
 drivers/staging/lustre/lustre/llite/vvp_object.c   |  13 +
 drivers/staging/lustre/lustre/llite/vvp_page.c |  36 +--
 drivers/staging/lustre/lustre/lov/lov_object.c |   9 +-
 drivers/staging/lustre/lustre/lov/lov_page.c   |  29 +-
 drivers/staging/lustre/lustre/obdclass/cl_io.c |   1 +
 drivers/staging/lustre/lustre/obdclass/cl_lock.c   | 131 +---
 drivers/staging/lustre/lustre/obdclass/cl_object.c |  47 +--
 drivers/staging/lustre/lustre/obdclass/cl_page.c   | 354 ++---
 drivers/staging/lustre/lustre/osc/osc_cache.c  | 207 +++-
 .../staging/lustre/lustre/osc/osc_cl_internal.h|  27 +-
 drivers/staging/lustre/lustre/osc/osc_io.c |  14 +-
 drivers/staging/lustre/lustre/osc/osc_lock.c   |  10 +-
 drivers/staging/lustre/lustre/osc/osc_object.c |   2 +
 drivers/staging/lustre/lustre/osc/osc_page.c   |  28 +-
 19 files changed, 394 insertions(+), 604 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h 
b/drivers/staging/lustre/lustre/include/cl_object.h
index e611f79..5daf688 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -388,6 +388,12 @@ struct cl_object_operations {
 */
int (*coo_glimpse)(const struct lu_env *env,
   const struct cl_object *obj, struct ost_lvb *lvb);
+   /**
+* Object prune method. Called when the layout is going to change on
+* this object, therefore each layer has to clean up their cache,
+* mainly pages and locks.
+*/
+   int (*coo_prune)(const struct lu_env *env, struct cl_object *obj);
 };
 
 /**
@@ -403,15 +409,9 @@ struct cl_object_header {
 * mostly useless otherwise.
 */
/** @{ */
-   /** Lock protecting page tree. */
-   spinlock_t   coh_page_guard;
/** Lock protecting lock list. */
spinlock_t   coh_lock_guard;
/** @} locks */
-   /** Radix tree of cl_page's, cached for this object. */
-   struct radix_tree_root   coh_tree;
-   /** # of pages in radix tree. */
-   unsigned long   coh_pages;
/** List of cl_lock's granted for this object. */
struct list_head   coh_locks;
 
@@ -897,14 +897,6 @@ struct cl_page_operations {
void  (*cpo_export)(const struct lu_env *env,
const struct cl_page_slice *slice, int uptodate);
/**
-* Unmaps page from the user space (if it is mapped).
-*
-* \see cl_page_unmap()
-* \see vvp_page_unmap()
-*/
-   int (*cpo_unmap)(const struct lu_env *env,
-const struct cl_page_slice *slice, struct cl_io *io);
-   /**
 * Checks whether underlying VM page is locked (in the suitable
 * sense). Used for assertions.
 *
@@ -2794,19 +2786,13 @@ enum {
 };
 
 /* callback of cl_page_gang_lookup() */
-typedef int   (*cl_page_gang_cb_t)  (const struct lu_env *, struct cl_io *,
-struct cl_page *, void *);
-int cl_page_gang_lookup(const struct lu_env *env, struct cl_object *obj,
-   struct cl_io *io, pgoff_t start, pgoff_t end,
-   cl_page_gang_cb_t cb, void *cbdata);
-struct cl_page *cl_page_lookup(struct cl_object_header *hdr, pgoff_t index);
 struct cl_page *cl_page_find(const struct lu_env *env, struct cl_object *obj,
 pgoff_t idx, struct page *vmpage,
 enum cl_page_type type);
-struct cl_page *cl_page_find_sub(const struct lu_env *env,
-struct cl_object *obj,
-pgoff_t idx, struct page *vmpage,
-struct cl_page *parent);
+struct cl_page *cl_page_alloc(const struct lu_env *env,
+ struct cl_object *o, pgoff_t ind,
+ struct page *vmpage,
+ enum cl_page_type type);
 void cl_page_get(struct cl_page *page);
 void cl_page_put(const struct lu_env *env, struct cl_page *page);
 void cl_page_print(const struct lu_env *env, void *cookie, lu_printer_t 
printer,
@@ -2872,8 +2858,6 @@ int cl_page_flush(const struct lu_env *env, struct cl_io 
*io,
 void cl_page_discard(const struct

[PATCH 10/43] staging/lustre/osc: add weight function for DLM lock

2016-03-30 Thread green
From: Jinshan Xiong 

Use weigh_ast to decide if a lock covers any pages.
In recovery, weigh_ast will be used to decide if a DLM read lock
covers any locked pages, or it will be canceled instead being
recovered.

The problem with the original implementation is that it attached
each osc_page to an osc_lock also changed lock state to add every
pages for readahead.

Signed-off-by: Jinshan Xiong 
Reviewed-on: http://review.whamcloud.com/7894
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3321
Reviewed-by: Bobi Jam 
Reviewed-by: Lai Siyao 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/ldlm/ldlm_request.c  |   9 +-
 .../staging/lustre/lustre/osc/osc_cl_internal.h|  20 
 drivers/staging/lustre/lustre/osc/osc_internal.h   |   3 +-
 drivers/staging/lustre/lustre/osc/osc_lock.c   | 113 +++--
 drivers/staging/lustre/lustre/osc/osc_page.c   |  78 +-
 drivers/staging/lustre/lustre/osc/osc_request.c|   5 +-
 6 files changed, 89 insertions(+), 139 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c 
b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index c7904a9..d5968e0 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -1139,10 +1139,10 @@ static ldlm_policy_res_t 
ldlm_cancel_no_wait_policy(struct ldlm_namespace *ns,
ldlm_policy_res_t result = LDLM_POLICY_CANCEL_LOCK;
ldlm_cancel_for_recovery cb = ns->ns_cancel_for_recovery;
 
-   lock_res_and_lock(lock);
-
/* don't check added & count since we want to process all locks
-* from unused list
+* from unused list.
+* It's fine to not take lock to access lock->l_resource since
+* the lock has already been granted so it won't change.
 */
switch (lock->l_resource->lr_type) {
case LDLM_EXTENT:
@@ -1151,11 +1151,12 @@ static ldlm_policy_res_t 
ldlm_cancel_no_wait_policy(struct ldlm_namespace *ns,
break;
default:
result = LDLM_POLICY_SKIP_LOCK;
+   lock_res_and_lock(lock);
lock->l_flags |= LDLM_FL_SKIPPED;
+   unlock_res_and_lock(lock);
break;
}
 
-   unlock_res_and_lock(lock);
return result;
 }
 
diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h 
b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h
index 0e06bed..cf87043 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h
+++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h
@@ -275,16 +275,6 @@ struct osc_lock {
enum osc_lock_state  ols_state;
 
/**
-* How many pages are using this lock for io, currently only used by
-* read-ahead. If non-zero, the underlying dlm lock won't be cancelled
-* during recovery to avoid deadlock. see bz16774.
-*
-* \see osc_page::ops_lock
-* \see osc_page_addref_lock(), osc_page_putref_lock()
-*/
-   atomic_t ols_pageref;
-
-   /**
 * true, if ldlm_lock_addref() was called against
 * osc_lock::ols_lock. This is used for sanity checking.
 *
@@ -400,16 +390,6 @@ struct osc_page {
 * Submit time - the time when the page is starting RPC. For debugging.
 */
unsigned long   ops_submit_time;
-
-   /**
-* A lock of which we hold a reference covers this page. Only used by
-* read-ahead: for a readahead page, we hold it's covering lock to
-* prevent it from being canceled during recovery.
-*
-* \see osc_lock::ols_pageref
-* \see osc_page_addref_lock(), osc_page_putref_lock().
-*/
-   struct cl_lock   *ops_lock;
 };
 
 extern struct kmem_cache *osc_lock_kmem;
diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h 
b/drivers/staging/lustre/lustre/osc/osc_internal.h
index 906225c..b7fb01a 100644
--- a/drivers/staging/lustre/lustre/osc/osc_internal.h
+++ b/drivers/staging/lustre/lustre/osc/osc_internal.h
@@ -141,6 +141,7 @@ int osc_lru_shrink(const struct lu_env *env, struct 
client_obd *cli,
 int osc_lru_reclaim(struct client_obd *cli);
 
 extern spinlock_t osc_ast_guard;
+unsigned long osc_ldlm_weigh_ast(struct ldlm_lock *dlmlock);
 
 int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg);
 
@@ -181,8 +182,6 @@ static inline struct osc_device *obd2osc_dev(const struct 
obd_device *d)
return container_of0(d->obd_lu_dev, struct osc_device, od_cl.cd_lu_dev);
 }
 
-int osc_dlm_lock_pageref(struct ldlm_lock *dlm);
-
 extern struct kmem_cache *osc_quota_kmem;
 struct osc_quota_info {
/** linkage for quota hash table */
diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c 
b/drivers/staging/lustre/lustre/osc/osc_lock.c
index 3a8a6d1..978b6ea 100644
--- a/drivers/staging/lustre/lustre/osc/osc_lock.c
+++ b/drivers/staging/lustre/lustre/osc/osc_lock.c
@@ -51,8 +51,6 @@
  

[PATCH 09/43] staging/lustre/clio: add pages into writeback cache in batches

2016-03-30 Thread green
From: Jinshan Xiong 

in ll_write_end(), instead of adding the page into writeback
cache directly, it will be held in a page list. After enough
pages have been collected, issue them all with cio_commit_async().

Signed-off-by: Jinshan Xiong 
Reviewed-on: http://review.whamcloud.com/7893
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3321
Reviewed-by: Bobi Jam 
Reviewed-by: Lai Siyao 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/cl_object.h  |  77 ++--
 drivers/staging/lustre/lustre/include/lclient.h|   6 +
 drivers/staging/lustre/lustre/llite/file.c |  11 +-
 .../staging/lustre/lustre/llite/llite_internal.h   |   8 +-
 drivers/staging/lustre/lustre/llite/rw.c   | 186 ++--
 drivers/staging/lustre/lustre/llite/rw26.c | 210 +++--
 drivers/staging/lustre/lustre/llite/vvp_internal.h |  10 +-
 drivers/staging/lustre/lustre/llite/vvp_io.c   | 490 +++--
 .../staging/lustre/lustre/lov/lov_cl_internal.h|   2 +
 drivers/staging/lustre/lustre/lov/lov_io.c | 219 -
 drivers/staging/lustre/lustre/lov/lov_page.c   |  28 --
 drivers/staging/lustre/lustre/obdclass/cl_io.c | 108 ++---
 drivers/staging/lustre/lustre/obdclass/cl_page.c   |  38 --
 .../staging/lustre/lustre/obdecho/echo_client.c|  25 +-
 drivers/staging/lustre/lustre/osc/osc_cache.c  |  14 +-
 .../staging/lustre/lustre/osc/osc_cl_internal.h|   2 +
 drivers/staging/lustre/lustre/osc/osc_internal.h   |   6 +
 drivers/staging/lustre/lustre/osc/osc_io.c | 160 ---
 drivers/staging/lustre/lustre/osc/osc_page.c   |  32 +-
 drivers/staging/lustre/lustre/osc/osc_request.c|  56 ++-
 20 files changed, 792 insertions(+), 896 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h 
b/drivers/staging/lustre/lustre/include/cl_object.h
index e8455dc..c3865ec 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -1019,26 +1019,6 @@ struct cl_page_operations {
 */
int  (*cpo_make_ready)(const struct lu_env *env,
   const struct cl_page_slice *slice);
-   /**
-* Announce that this page is to be written out
-* opportunistically, that is, page is dirty, it is not
-* necessary to start write-out transfer right now, but
-* eventually page has to be written out.
-*
-* Main caller of this is the write path (see
-* vvp_io_commit_write()), using this method to build a
-* "transfer cache" from which large transfers are then
-* constructed by the req-formation engine.
-*
-* \todo XXX it would make sense to add page-age tracking
-* semantics here, and to oblige the req-formation engine to
-* send the page out not later than it is too old.
-*
-* \see cl_page_cache_add()
-*/
-   int  (*cpo_cache_add)(const struct lu_env *env,
- const struct cl_page_slice *slice,
- struct cl_io *io);
} io[CRT_NR];
/**
 * Tell transfer engine that only [to, from] part of a page should be
@@ -2023,6 +2003,8 @@ struct cl_io_slice {
struct list_head cis_linkage;
 };
 
+typedef void (*cl_commit_cbt)(const struct lu_env *, struct cl_io *,
+ struct cl_page *);
 /**
  * Per-layer io operations.
  * \see vvp_io_ops, lov_io_ops, lovsub_io_ops, osc_io_ops
@@ -2106,7 +2088,7 @@ struct cl_io_operations {
void (*cio_fini)(const struct lu_env *env,
 const struct cl_io_slice *slice);
} op[CIT_OP_NR];
-   struct {
+
/**
 * Submit pages from \a queue->c2_qin for IO, and move
 * successfully submitted pages into \a queue->c2_qout. Return
@@ -2119,7 +2101,15 @@ struct cl_io_operations {
   const struct cl_io_slice *slice,
   enum cl_req_type crt,
   struct cl_2queue *queue);
-   } req_op[CRT_NR];
+   /**
+* Queue async page for write.
+* The difference between cio_submit and cio_queue is that
+* cio_submit is for urgent request.
+*/
+   int  (*cio_commit_async)(const struct lu_env *env,
+const struct cl_io_slice *slice,
+struct cl_page_list *queue, int from, int to,
+cl_commit_cbt cb);
/**
 * Read missing page.
 *
@@ -2132,31 +2122,6 @@ struct cl_io_operations {
 const struct cl_io_slice *slice,

[PATCH 14/43] staging/lustre/lmv: remove lmv_init_{lock,unlock}()

2016-03-30 Thread green
From: "John L. Hammond" 

In struct lmv_obd rename the init_mutex member to
lmv_init_mutex. Remove the compat macros lmv_init_{lock,unlock}() and
use mutex_{lock,unlock}(&lmv->lmv_init_mutex) instead.

Signed-off-by: John L. Hammond 
Reviewed-on: http://review.whamcloud.com/12115
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-2675
Reviewed-by: Bob Glossman 
Reviewed-by: James Simmons 
Reviewed-by: Dmitry Eremin 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/obd.h  |  2 +-
 drivers/staging/lustre/lustre/lmv/lmv_internal.h |  3 ---
 drivers/staging/lustre/lustre/lmv/lmv_obd.c  | 24 
 3 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/obd.h 
b/drivers/staging/lustre/lustre/include/obd.h
index 26182ca..15c514c 100644
--- a/drivers/staging/lustre/lustre/include/obd.h
+++ b/drivers/staging/lustre/lustre/include/obd.h
@@ -512,7 +512,7 @@ struct lmv_obd {
struct obd_uuid cluuid;
struct obd_export   *exp;
 
-   struct mutexinit_mutex;
+   struct mutexlmv_init_mutex;
int connected;
int max_easize;
int max_def_easize;
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_internal.h 
b/drivers/staging/lustre/lustre/lmv/lmv_internal.h
index 8a00871..7007e4c 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_internal.h
+++ b/drivers/staging/lustre/lustre/lmv/lmv_internal.h
@@ -42,9 +42,6 @@
 
 #define LMV_MAX_TGT_COUNT 128
 
-#define lmv_init_lock(lmv)   mutex_lock(&lmv->init_mutex)
-#define lmv_init_unlock(lmv) mutex_unlock(&lmv->init_mutex)
-
 #define LL_IT2STR(it)  \
((it) ? ldlm_it2str((it)->it_op) : "0")
 
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c 
b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
index e3a7216..8bd2dc5 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c
+++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
@@ -425,7 +425,7 @@ static int lmv_add_target(struct obd_device *obd, struct 
obd_uuid *uuidp,
 
CDEBUG(D_CONFIG, "Target uuid: %s. index %d\n", uuidp->uuid, index);
 
-   lmv_init_lock(lmv);
+   mutex_lock(&lmv->lmv_init_mutex);
 
if (lmv->desc.ld_tgt_count == 0) {
struct obd_device *mdc_obd;
@@ -433,7 +433,7 @@ static int lmv_add_target(struct obd_device *obd, struct 
obd_uuid *uuidp,
mdc_obd = class_find_client_obd(uuidp, LUSTRE_MDC_NAME,
&obd->obd_uuid);
if (!mdc_obd) {
-   lmv_init_unlock(lmv);
+   mutex_unlock(&lmv->lmv_init_mutex);
CERROR("%s: Target %s not attached: rc = %d\n",
   obd->obd_name, uuidp->uuid, -EINVAL);
return -EINVAL;
@@ -445,7 +445,7 @@ static int lmv_add_target(struct obd_device *obd, struct 
obd_uuid *uuidp,
CERROR("%s: UUID %s already assigned at LOV target index %d: rc 
= %d\n",
   obd->obd_name,
   obd_uuid2str(&tgt->ltd_uuid), index, -EEXIST);
-   lmv_init_unlock(lmv);
+   mutex_unlock(&lmv->lmv_init_mutex);
return -EEXIST;
}
 
@@ -459,7 +459,7 @@ static int lmv_add_target(struct obd_device *obd, struct 
obd_uuid *uuidp,
newsize <<= 1;
newtgts = kcalloc(newsize, sizeof(*newtgts), GFP_NOFS);
if (!newtgts) {
-   lmv_init_unlock(lmv);
+   mutex_unlock(&lmv->lmv_init_mutex);
return -ENOMEM;
}
 
@@ -481,7 +481,7 @@ static int lmv_add_target(struct obd_device *obd, struct 
obd_uuid *uuidp,
 
tgt = kzalloc(sizeof(*tgt), GFP_NOFS);
if (!tgt) {
-   lmv_init_unlock(lmv);
+   mutex_unlock(&lmv->lmv_init_mutex);
return -ENOMEM;
}
 
@@ -507,7 +507,7 @@ static int lmv_add_target(struct obd_device *obd, struct 
obd_uuid *uuidp,
}
}
 
-   lmv_init_unlock(lmv);
+   mutex_unlock(&lmv->lmv_init_mutex);
return rc;
 }
 
@@ -522,14 +522,14 @@ int lmv_check_connect(struct obd_device *obd)
if (lmv->connected)
return 0;
 
-   lmv_init_lock(lmv);
+   mutex_lock(&lmv->lmv_init_mutex);
if (lmv->connected) {
-   lmv_init_unlock(lmv);
+   mutex_unlock(&lmv->lmv_init_mutex);
return 0;
}
 
if (lmv->desc.ld_tgt_count == 0) {
-   lmv_init_unlock(lmv);
+   mutex_unlock(&lmv->lmv_init_mutex);
CERROR("%s: no targets configured.\n", obd->obd_name);
return -EINVAL;
}
@@ -551,7 +551,7 @@ int lmv_check_connect(struct obd_device *obd)
lmv->connected = 1;
easize = 

[PATCH 03/43] staging/lustre: merge lclient/*.c into llite/

2016-03-30 Thread green
From: "John L. Hammond" 

Separate lclient was necessary to be shared between
different client implementations, make no sense to have
them separate in Linux kernel.

Signed-off-by: John L. Hammond 
Based-on: http://review.whamcloud.com/10171
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/lclient/glimpse.c|  270 -
 drivers/staging/lustre/lustre/lclient/lcommon_cl.c | 1203 ---
 .../staging/lustre/lustre/lclient/lcommon_misc.c   |  200 
 drivers/staging/lustre/lustre/llite/Makefile   |2 +-
 drivers/staging/lustre/lustre/llite/glimpse.c  |  273 +
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   | 1209 
 drivers/staging/lustre/lustre/llite/lcommon_misc.c |  200 
 7 files changed, 1683 insertions(+), 1674 deletions(-)
 delete mode 100644 drivers/staging/lustre/lustre/lclient/glimpse.c
 delete mode 100644 drivers/staging/lustre/lustre/lclient/lcommon_cl.c
 delete mode 100644 drivers/staging/lustre/lustre/lclient/lcommon_misc.c
 create mode 100644 drivers/staging/lustre/lustre/llite/glimpse.c
 create mode 100644 drivers/staging/lustre/lustre/llite/lcommon_cl.c
 create mode 100644 drivers/staging/lustre/lustre/llite/lcommon_misc.c

diff --git a/drivers/staging/lustre/lustre/lclient/glimpse.c 
b/drivers/staging/lustre/lustre/lclient/glimpse.c
deleted file mode 100644
index c4e8a08..000
--- a/drivers/staging/lustre/lustre/lclient/glimpse.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2011, 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * glimpse code shared between vvp and liblustre (and other Lustre clients in
- * the future).
- *
- *   Author: Nikita Danilov 
- *   Author: Oleg Drokin 
- */
-
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
-#include "../include/obd.h"
-
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_lite.h"
-#include "../include/lustre_mdc.h"
-#include 
-#include 
-
-#include "../include/cl_object.h"
-#include "../include/lclient.h"
-#include "../llite/llite_internal.h"
-
-static const struct cl_lock_descr whole_file = {
-   .cld_start = 0,
-   .cld_end   = CL_PAGE_EOF,
-   .cld_mode  = CLM_READ
-};
-
-/*
- * Check whether file has possible unwriten pages.
- *
- * \retval 1file is mmap-ed or has dirty pages
- *  0otherwise
- */
-blkcnt_t dirty_cnt(struct inode *inode)
-{
-   blkcnt_t cnt = 0;
-   struct ccc_object *vob = cl_inode2ccc(inode);
-   void  *results[1];
-
-   if (inode->i_mapping)
-   cnt += radix_tree_gang_lookup_tag(&inode->i_mapping->page_tree,
- results, 0, 1,
- PAGECACHE_TAG_DIRTY);
-   if (cnt == 0 && atomic_read(&vob->cob_mmap_cnt) > 0)
-   cnt = 1;
-
-   return (cnt > 0) ? 1 : 0;
-}
-
-int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io,
-   struct inode *inode, struct cl_object *clob, int agl)
-{
-   struct cl_lock_descr *descr = &ccc_env_info(env)->cti_descr;
-   struct cl_inode_info *lli   = cl_i2info(inode);
-   const struct lu_fid  *fid   = lu_object_fid(&clob->co_lu);
-   struct ccc_io   *cio   = ccc_env_io(env);
-   struct cl_lock   *lock;
-   int result;
-
-   result = 0;
-   if (!(lli->lli_flags & LLIF_MDS_SIZE_LOCK)) {
-   CDEBUG(D_DLMTRACE, "Glimpsing inode "DFID"\n", PFID(fid));
-   if (lli->lli_has_smd) {
-   /* NOTE: this looks like DLM lock request, but it may
-*   not be one. Due to CEF_ASYNC flag (translated
-*   to L

[PATCH 13/43] staging/lustre/llite: remove lli_lvb

2016-03-30 Thread green
From: "John L. Hammond" 

In struct ll_inode_info remove the struct ost_lvb lli_lvb member and
replace it with s64 lli_{a,m,c}time. Rename ll_merge_lvb() to
ll_merge_attr(). Remove cl_merge_lvb() and replace calls to it with
calls to ll_merge_attr().

Signed-off-by: John L. Hammond 
Reviewed-on: http://review.whamcloud.com/12849
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-2675
Reviewed-by: Bobi Jam 
Reviewed-by: Lai Siyao 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/llite/file.c | 65 --
 drivers/staging/lustre/lustre/llite/glimpse.c  |  6 +-
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   |  2 +-
 .../staging/lustre/lustre/llite/llite_internal.h   | 11 ++--
 drivers/staging/lustre/lustre/llite/llite_lib.c|  6 +-
 drivers/staging/lustre/lustre/llite/vvp_io.c   |  2 +-
 6 files changed, 48 insertions(+), 44 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/file.c 
b/drivers/staging/lustre/lustre/llite/file.c
index 127fff6..8fc9da0 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -994,50 +994,57 @@ int ll_inode_getattr(struct inode *inode, struct obdo 
*obdo,
return rc;
 }
 
-int ll_merge_lvb(const struct lu_env *env, struct inode *inode)
+int ll_merge_attr(const struct lu_env *env, struct inode *inode)
 {
struct ll_inode_info *lli = ll_i2info(inode);
struct cl_object *obj = lli->lli_clob;
struct cl_attr *attr = ccc_env_thread_attr(env);
-   struct ost_lvb lvb;
+   s64 atime;
+   s64 mtime;
+   s64 ctime;
int rc = 0;
 
ll_inode_size_lock(inode);
+
/* merge timestamps the most recently obtained from mds with
 * timestamps obtained from osts
 */
-   LTIME_S(inode->i_atime) = lli->lli_lvb.lvb_atime;
-   LTIME_S(inode->i_mtime) = lli->lli_lvb.lvb_mtime;
-   LTIME_S(inode->i_ctime) = lli->lli_lvb.lvb_ctime;
+   LTIME_S(inode->i_atime) = lli->lli_atime;
+   LTIME_S(inode->i_mtime) = lli->lli_mtime;
+   LTIME_S(inode->i_ctime) = lli->lli_ctime;
 
-   lvb.lvb_size = i_size_read(inode);
-   lvb.lvb_blocks = inode->i_blocks;
-   lvb.lvb_mtime = LTIME_S(inode->i_mtime);
-   lvb.lvb_atime = LTIME_S(inode->i_atime);
-   lvb.lvb_ctime = LTIME_S(inode->i_ctime);
+   mtime = LTIME_S(inode->i_mtime);
+   atime = LTIME_S(inode->i_atime);
+   ctime = LTIME_S(inode->i_ctime);
 
cl_object_attr_lock(obj);
rc = cl_object_attr_get(env, obj, attr);
cl_object_attr_unlock(obj);
 
-   if (rc == 0) {
-   if (lvb.lvb_atime < attr->cat_atime)
-   lvb.lvb_atime = attr->cat_atime;
-   if (lvb.lvb_ctime < attr->cat_ctime)
-   lvb.lvb_ctime = attr->cat_ctime;
-   if (lvb.lvb_mtime < attr->cat_mtime)
-   lvb.lvb_mtime = attr->cat_mtime;
+   if (rc != 0)
+   goto out_size_unlock;
 
-   CDEBUG(D_VFSTRACE, DFID " updating i_size %llu\n",
-  PFID(&lli->lli_fid), attr->cat_size);
-   cl_isize_write_nolock(inode, attr->cat_size);
+   if (atime < attr->cat_atime)
+   atime = attr->cat_atime;
 
-   inode->i_blocks = attr->cat_blocks;
+   if (ctime < attr->cat_ctime)
+   ctime = attr->cat_ctime;
 
-   LTIME_S(inode->i_mtime) = lvb.lvb_mtime;
-   LTIME_S(inode->i_atime) = lvb.lvb_atime;
-   LTIME_S(inode->i_ctime) = lvb.lvb_ctime;
-   }
+   if (mtime < attr->cat_mtime)
+   mtime = attr->cat_mtime;
+
+   CDEBUG(D_VFSTRACE, DFID " updating i_size %llu\n",
+  PFID(&lli->lli_fid), attr->cat_size);
+
+   cl_isize_write_nolock(inode, attr->cat_size);
+
+   inode->i_blocks = attr->cat_blocks;
+
+   LTIME_S(inode->i_mtime) = mtime;
+   LTIME_S(inode->i_atime) = atime;
+   LTIME_S(inode->i_ctime) = ctime;
+
+out_size_unlock:
ll_inode_size_unlock(inode);
 
return rc;
@@ -1936,7 +1943,7 @@ int ll_hsm_release(struct inode *inode)
goto out;
}
 
-   ll_merge_lvb(env, inode);
+   ll_merge_attr(env, inode);
cl_env_nested_put(&nest, env);
 
/* Release the file.
@@ -3001,9 +3008,9 @@ static int ll_inode_revalidate(struct dentry *dentry, 
__u64 ibits)
 
/* if object isn't regular file, don't validate size */
if (!S_ISREG(inode->i_mode)) {
-   LTIME_S(inode->i_atime) = ll_i2info(inode)->lli_lvb.lvb_atime;
-   LTIME_S(inode->i_mtime) = ll_i2info(inode)->lli_lvb.lvb_mtime;
-   LTIME_S(inode->i_ctime) = ll_i2info(inode)->lli_lvb.lvb_ctime;
+   LTIME_S(inode->i_atime) = ll_i2info(inode)->lli_atime;
+   LTIME_S(inode->i_mtime) = ll_i2info(inode)->lli_mtime;
+   LTIME_S(inode->i_ctime) = ll_i2info(inode)->lli_ctime;
} else {
  

[PATCH 12/43] staging/lustre/clio: optimize read ahead code

2016-03-30 Thread green
From: Jinshan Xiong 

It used to check each page in the readahead window is covered by
a lock underneath, now cpo_page_is_under_lock() provides @max_index
to help decide the maximum ra window. @max_index can be modified by
OSC to extend the maximum lock region, to align stripe boundary at
LOV, and to make sure the readahead region at least covers read
region at LLITE layer.

After this is done, usually readahead code calls
cpo_page_is_under_lock() for each stripe.

Signed-off-by: Jinshan Xiong 
Reviewed-on: http://review.whamcloud.com/8523
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3321
Reviewed-by: Andreas Dilger 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/cl_object.h  |   6 +-
 drivers/staging/lustre/lustre/include/lclient.h|   2 -
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   |  28 --
 .../staging/lustre/lustre/llite/llite_internal.h   |   7 +-
 drivers/staging/lustre/lustre/llite/lproc_llite.c  |   1 +
 drivers/staging/lustre/lustre/llite/rw.c   | 103 ++---
 drivers/staging/lustre/lustre/llite/vvp_io.c   |  23 +
 drivers/staging/lustre/lustre/llite/vvp_page.c |  26 --
 .../staging/lustre/lustre/lov/lov_cl_internal.h|   1 +
 drivers/staging/lustre/lustre/lov/lov_internal.h   |   2 +
 drivers/staging/lustre/lustre/lov/lov_io.c |   2 +-
 drivers/staging/lustre/lustre/lov/lov_offset.c |  13 +++
 drivers/staging/lustre/lustre/lov/lov_page.c   |  60 ++--
 drivers/staging/lustre/lustre/lov/lovsub_page.c|   4 +-
 drivers/staging/lustre/lustre/obdclass/cl_io.c |   2 +-
 drivers/staging/lustre/lustre/obdclass/cl_page.c   |  39 ++--
 .../staging/lustre/lustre/obdecho/echo_client.c|   2 +-
 drivers/staging/lustre/lustre/osc/osc_page.c   |  10 +-
 18 files changed, 208 insertions(+), 123 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h 
b/drivers/staging/lustre/lustre/include/cl_object.h
index 5b65854..69b40f5 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -935,7 +935,7 @@ struct cl_page_operations {
 */
int (*cpo_is_under_lock)(const struct lu_env *env,
 const struct cl_page_slice *slice,
-struct cl_io *io);
+struct cl_io *io, pgoff_t *max);
 
/**
 * Optional debugging helper. Prints given page slice.
@@ -2674,7 +2674,7 @@ static inline void cl_device_fini(struct cl_device *d)
 }
 
 void cl_page_slice_add(struct cl_page *page, struct cl_page_slice *slice,
-  struct cl_object *obj,
+  struct cl_object *obj, pgoff_t index,
   const struct cl_page_operations *ops);
 void cl_lock_slice_add(struct cl_lock *lock, struct cl_lock_slice *slice,
   struct cl_object *obj,
@@ -2826,7 +2826,7 @@ void cl_page_delete(const struct lu_env *env, struct 
cl_page *pg);
 int cl_page_is_vmlocked(const struct lu_env *env, const struct cl_page *pg);
 void cl_page_export(const struct lu_env *env, struct cl_page *pg, int 
uptodate);
 int cl_page_is_under_lock(const struct lu_env *env, struct cl_io *io,
- struct cl_page *page);
+ struct cl_page *page, pgoff_t *max_index);
 loff_t cl_offset(const struct cl_object *obj, pgoff_t idx);
 pgoff_t cl_index(const struct cl_object *obj, loff_t offset);
 int cl_page_size(const struct cl_object *obj);
diff --git a/drivers/staging/lustre/lustre/include/lclient.h 
b/drivers/staging/lustre/lustre/include/lclient.h
index c91fb01..a8c8788 100644
--- a/drivers/staging/lustre/lustre/include/lclient.h
+++ b/drivers/staging/lustre/lustre/include/lclient.h
@@ -299,8 +299,6 @@ int ccc_lock_init(const struct lu_env *env, struct 
cl_object *obj,
  const struct cl_lock_operations *lkops);
 int ccc_object_glimpse(const struct lu_env *env,
   const struct cl_object *obj, struct ost_lvb *lvb);
-int ccc_page_is_under_lock(const struct lu_env *env,
-  const struct cl_page_slice *slice, struct cl_io *io);
 int ccc_fail(const struct lu_env *env, const struct cl_page_slice *slice);
 int ccc_transient_page_prep(const struct lu_env *env,
const struct cl_page_slice *slice,
diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c 
b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
index 55fa0da..e34d832 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
@@ -452,34 +452,6 @@ static void ccc_object_size_unlock(struct cl_object *obj)
  *
  */
 
-int ccc_page_is_under_lock(const struct lu_env *env,
-  const struct cl_page_slice *slice,
-  struct cl_io *io)
-{
-   struct ccc_io   *cio  = ccc_env_io(env);
-   struct cl_lock_descr *de

[PATCH 11/43] staging/lustre/clio: remove stackable cl_page completely

2016-03-30 Thread green
From: Jinshan Xiong 

>From now on, cl_page becomes one to one mapping of vmpage.

Signed-off-by: Jinshan Xiong 
Reviewed-on: http://review.whamcloud.com/7895
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3321
Reviewed-by: Bobi Jam 
Reviewed-by: Lai Siyao 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/cl_object.h  |  43 ++---
 drivers/staging/lustre/lustre/include/lclient.h|   7 +-
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   |  12 +-
 .../staging/lustre/lustre/llite/llite_internal.h   |   4 +
 drivers/staging/lustre/lustre/llite/rw.c   |   7 +-
 drivers/staging/lustre/lustre/llite/rw26.c |  35 +---
 drivers/staging/lustre/lustre/llite/vvp_internal.h |   2 +-
 drivers/staging/lustre/lustre/llite/vvp_io.c   |  45 +++--
 drivers/staging/lustre/lustre/llite/vvp_page.c |  23 +--
 .../staging/lustre/lustre/lov/lov_cl_internal.h|  14 +-
 drivers/staging/lustre/lustre/lov/lov_io.c |   8 +-
 drivers/staging/lustre/lustre/lov/lov_object.c |  32 +++-
 drivers/staging/lustre/lustre/lov/lov_page.c   | 104 +++---
 drivers/staging/lustre/lustre/lov/lovsub_page.c|   2 +-
 drivers/staging/lustre/lustre/obdclass/cl_io.c |  63 +-
 drivers/staging/lustre/lustre/obdclass/cl_object.c |   4 +-
 drivers/staging/lustre/lustre/obdclass/cl_page.c   | 213 +
 .../staging/lustre/lustre/obdecho/echo_client.c|  22 +--
 drivers/staging/lustre/lustre/osc/osc_cache.c  |  59 +++---
 .../staging/lustre/lustre/osc/osc_cl_internal.h|  12 +-
 drivers/staging/lustre/lustre/osc/osc_io.c |  41 ++--
 drivers/staging/lustre/lustre/osc/osc_page.c   |  33 ++--
 22 files changed, 257 insertions(+), 528 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h 
b/drivers/staging/lustre/lustre/include/cl_object.h
index c3865ec..5b65854 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -322,7 +322,7 @@ struct cl_object_operations {
 *   to be used instead of newly created.
 */
int  (*coo_page_init)(const struct lu_env *env, struct cl_object *obj,
- struct cl_page *page, struct page *vmpage);
+   struct cl_page *page, pgoff_t index);
/**
 * Initialize lock slice for this layer. Called top-to-bottom through
 * every object layer when a new cl_lock is instantiated. Layer
@@ -460,10 +460,6 @@ struct cl_object_header {
co_lu.lo_linkage)
 /** @} cl_object */
 
-#ifndef pgoff_t
-#define pgoff_t unsigned long
-#endif
-
 #define CL_PAGE_EOF ((pgoff_t)~0ull)
 
 /** \addtogroup cl_page cl_page
@@ -727,16 +723,10 @@ struct cl_page {
atomic_t cp_ref;
/** An object this page is a part of. Immutable after creation. */
struct cl_object*cp_obj;
-   /** Logical page index within the object. Immutable after creation. */
-   pgoff_t   cp_index;
/** List of slices. Immutable after creation. */
struct list_head   cp_layers;
-   /** Parent page, NULL for top-level page. Immutable after creation. */
-   struct cl_page*cp_parent;
-   /** Lower-layer page. NULL for bottommost page. Immutable after
-* creation.
-*/
-   struct cl_page*cp_child;
+   /** vmpage */
+   struct page *cp_vmpage;
/**
 * Page state. This field is const to avoid accidental update, it is
 * modified only internally within cl_page.c. Protected by a VM lock.
@@ -791,6 +781,7 @@ struct cl_page {
  */
 struct cl_page_slice {
struct cl_page*cpl_page;
+   pgoff_t  cpl_index;
/**
 * Object slice corresponding to this page slice. Immutable after
 * creation.
@@ -846,11 +837,6 @@ struct cl_page_operations {
 */
 
/**
-* \return the underlying VM page. Optional.
-*/
-   struct page *(*cpo_vmpage)(const struct lu_env *env,
-  const struct cl_page_slice *slice);
-   /**
 * Called when \a io acquires this page into the exclusive
 * ownership. When this method returns, it is guaranteed that the is
 * not owned by other io, and no transfer is going on against
@@ -1102,6 +1088,12 @@ static inline int __page_in_use(const struct cl_page 
*page, int refc)
 #define cl_page_in_use(pg)   __page_in_use(pg, 1)
 #define cl_page_in_use_noref(pg) __page_in_use(pg, 0)
 
+static inline struct page *cl_page_vmpage(struct cl_page *page)
+{
+   LASSERT(page->cp_vmpage);
+   return page->cp_vmpage;
+}
+
 /** @} cl_page */
 
 /** \addtogroup cl_lock cl_lock
@@ -2729,7 +2721,7 @@ static inline int cl_object_same(struct cl_object *o0, 
struct cl_object *o1)
 static inline void cl_object_page_init(struct cl_object *clob, i

[PATCH 18/43] staging/lustre/clio: generalize cl_sync_io

2016-03-30 Thread green
From: Jinshan Xiong 

To make cl_sync_io interfaces not just wait for pages, but to be
a generic synchronization mechanism.

Also remove cl_io_cancel that became not used.

Signed-off-by: Jinshan Xiong 
Reviewed-on: http://review.whamcloud.com/8656
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4198
Reviewed-by: Bobi Jam 
Reviewed-by: Lai Siyao 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/cl_object.h | 13 ++--
 drivers/staging/lustre/lustre/obdclass/cl_io.c| 74 +++
 drivers/staging/lustre/lustre/obdclass/cl_page.c  |  2 +-
 3 files changed, 44 insertions(+), 45 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h 
b/drivers/staging/lustre/lustre/include/cl_object.h
index 69b40f5..91261b1 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -3125,13 +3125,18 @@ struct cl_sync_io {
atomic_tcsi_barrier;
/** completion to be signaled when transfer is complete. */
wait_queue_head_t   csi_waitq;
+   /** callback to invoke when this IO is finished */
+   void(*csi_end_io)(const struct lu_env *,
+ struct cl_sync_io *);
 };
 
-void cl_sync_io_init(struct cl_sync_io *anchor, int nrpages);
-int  cl_sync_io_wait(const struct lu_env *env, struct cl_io *io,
-struct cl_page_list *queue, struct cl_sync_io *anchor,
+void cl_sync_io_init(struct cl_sync_io *anchor, int nr,
+void (*end)(const struct lu_env *, struct cl_sync_io *));
+int  cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
 long timeout);
-void cl_sync_io_note(struct cl_sync_io *anchor, int ioret);
+void cl_sync_io_note(const struct lu_env *env, struct cl_sync_io *anchor,
+int ioret);
+void cl_sync_io_end(const struct lu_env *env, struct cl_sync_io *anchor);
 
 /** @} cl_sync_io */
 
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c 
b/drivers/staging/lustre/lustre/obdclass/cl_io.c
index 65d6cee..6a8dd9f 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -800,6 +800,9 @@ int cl_io_submit_rw(const struct lu_env *env, struct cl_io 
*io,
 }
 EXPORT_SYMBOL(cl_io_submit_rw);
 
+static void cl_page_list_assume(const struct lu_env *env,
+   struct cl_io *io, struct cl_page_list *plist);
+
 /**
  * Submit a sync_io and wait for the IO to be finished, or error happens.
  * If \a timeout is zero, it means to wait for the IO unconditionally.
@@ -817,7 +820,7 @@ int cl_io_submit_sync(const struct lu_env *env, struct 
cl_io *io,
pg->cp_sync_io = anchor;
}
 
-   cl_sync_io_init(anchor, queue->c2_qin.pl_nr);
+   cl_sync_io_init(anchor, queue->c2_qin.pl_nr, &cl_sync_io_end);
rc = cl_io_submit_rw(env, io, iot, queue);
if (rc == 0) {
/*
@@ -828,12 +831,12 @@ int cl_io_submit_sync(const struct lu_env *env, struct 
cl_io *io,
 */
cl_page_list_for_each(pg, &queue->c2_qin) {
pg->cp_sync_io = NULL;
-   cl_sync_io_note(anchor, 1);
+   cl_sync_io_note(env, anchor, 1);
}
 
/* wait for the IO to be finished. */
-   rc = cl_sync_io_wait(env, io, &queue->c2_qout,
-anchor, timeout);
+   rc = cl_sync_io_wait(env, anchor, timeout);
+   cl_page_list_assume(env, io, &queue->c2_qout);
} else {
LASSERT(list_empty(&queue->c2_qout.pl_pages));
cl_page_list_for_each(pg, &queue->c2_qin)
@@ -844,25 +847,6 @@ int cl_io_submit_sync(const struct lu_env *env, struct 
cl_io *io,
 EXPORT_SYMBOL(cl_io_submit_sync);
 
 /**
- * Cancel an IO which has been submitted by cl_io_submit_rw.
- */
-static int cl_io_cancel(const struct lu_env *env, struct cl_io *io,
-   struct cl_page_list *queue)
-{
-   struct cl_page *page;
-   int result = 0;
-
-   CERROR("Canceling ongoing page transmission\n");
-   cl_page_list_for_each(page, queue) {
-   int rc;
-
-   rc = cl_page_cancel(env, page);
-   result = result ?: rc;
-   }
-   return result;
-}
-
-/**
  * Main io loop.
  *
  * Pumps io through iterations calling
@@ -1433,25 +1417,38 @@ void cl_req_attr_set(const struct lu_env *env, struct 
cl_req *req,
 }
 EXPORT_SYMBOL(cl_req_attr_set);
 
+/* cl_sync_io_callback assumes the caller must call cl_sync_io_wait() to
+ * wait for the IO to finish.
+ */
+void cl_sync_io_end(const struct lu_env *env, struct cl_sync_io *anchor)
+{
+   wake_up_all(&anchor->csi_waitq);
+
+   /* it's safe to nuke or reuse anchor now */
+   atomic_set(&anchor->csi_barrier, 0);
+}
+EXPORT_SYMBOL(cl

[PATCH 15/43] staging/lustre/obd: remove struct client_obd_lock

2016-03-30 Thread green
From: "John L. Hammond" 

Remove the definition of struct client_obd_lock and the functions
client_obd_list_{init,lock,unlock,done}(). Use spinlock_t for the
cl_{loi,lru}_list_lock members of struct client_obd and call
spin_{lock,unlock}() directly.

Signed-off-by: John L. Hammond 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/fld/fld_request.c| 14 ++---
 drivers/staging/lustre/lustre/include/linux/obd.h  | 67 --
 drivers/staging/lustre/lustre/include/obd.h|  9 +--
 drivers/staging/lustre/lustre/ldlm/ldlm_lib.c  |  4 +-
 drivers/staging/lustre/lustre/mdc/lproc_mdc.c  |  8 +--
 drivers/staging/lustre/lustre/mdc/mdc_lib.c| 18 +++---
 drivers/staging/lustre/lustre/osc/lproc_osc.c  | 38 ++--
 drivers/staging/lustre/lustre/osc/osc_cache.c  | 50 
 .../staging/lustre/lustre/osc/osc_cl_internal.h|  2 +-
 drivers/staging/lustre/lustre/osc/osc_page.c   | 24 
 drivers/staging/lustre/lustre/osc/osc_request.c| 46 +++
 11 files changed, 105 insertions(+), 175 deletions(-)

diff --git a/drivers/staging/lustre/lustre/fld/fld_request.c 
b/drivers/staging/lustre/lustre/fld/fld_request.c
index a3d122d..2dfdb51 100644
--- a/drivers/staging/lustre/lustre/fld/fld_request.c
+++ b/drivers/staging/lustre/lustre/fld/fld_request.c
@@ -64,9 +64,9 @@ static int fld_req_avail(struct client_obd *cli, struct 
mdc_cache_waiter *mcw)
 {
int rc;
 
-   client_obd_list_lock(&cli->cl_loi_list_lock);
+   spin_lock(&cli->cl_loi_list_lock);
rc = list_empty(&mcw->mcw_entry);
-   client_obd_list_unlock(&cli->cl_loi_list_lock);
+   spin_unlock(&cli->cl_loi_list_lock);
return rc;
 };
 
@@ -75,15 +75,15 @@ static void fld_enter_request(struct client_obd *cli)
struct mdc_cache_waiter mcw;
struct l_wait_info lwi = { 0 };
 
-   client_obd_list_lock(&cli->cl_loi_list_lock);
+   spin_lock(&cli->cl_loi_list_lock);
if (cli->cl_r_in_flight >= cli->cl_max_rpcs_in_flight) {
list_add_tail(&mcw.mcw_entry, &cli->cl_cache_waiters);
init_waitqueue_head(&mcw.mcw_waitq);
-   client_obd_list_unlock(&cli->cl_loi_list_lock);
+   spin_unlock(&cli->cl_loi_list_lock);
l_wait_event(mcw.mcw_waitq, fld_req_avail(cli, &mcw), &lwi);
} else {
cli->cl_r_in_flight++;
-   client_obd_list_unlock(&cli->cl_loi_list_lock);
+   spin_unlock(&cli->cl_loi_list_lock);
}
 }
 
@@ -92,7 +92,7 @@ static void fld_exit_request(struct client_obd *cli)
struct list_head *l, *tmp;
struct mdc_cache_waiter *mcw;
 
-   client_obd_list_lock(&cli->cl_loi_list_lock);
+   spin_lock(&cli->cl_loi_list_lock);
cli->cl_r_in_flight--;
list_for_each_safe(l, tmp, &cli->cl_cache_waiters) {
 
@@ -106,7 +106,7 @@ static void fld_exit_request(struct client_obd *cli)
cli->cl_r_in_flight++;
wake_up(&mcw->mcw_waitq);
}
-   client_obd_list_unlock(&cli->cl_loi_list_lock);
+   spin_unlock(&cli->cl_loi_list_lock);
 }
 
 static int fld_rrb_hash(struct lu_client_fld *fld, u64 seq)
diff --git a/drivers/staging/lustre/lustre/include/linux/obd.h 
b/drivers/staging/lustre/lustre/include/linux/obd.h
index 3907bf4..e1063e8 100644
--- a/drivers/staging/lustre/lustre/include/linux/obd.h
+++ b/drivers/staging/lustre/lustre/include/linux/obd.h
@@ -55,71 +55,4 @@ struct ll_iattr {
unsigned intia_attr_flags;
 };
 
-#define CLIENT_OBD_LIST_LOCK_DEBUG 1
-
-struct client_obd_lock {
-   spinlock_t  lock;
-
-   unsigned long   time;
-   struct task_struct *task;
-   const char   *func;
-   int  line;
-};
-
-static inline void __client_obd_list_lock(struct client_obd_lock *lock,
- const char *func, int line)
-{
-   unsigned long cur = jiffies;
-
-   while (1) {
-   if (spin_trylock(&lock->lock)) {
-   LASSERT(!lock->task);
-   lock->task = current;
-   lock->func = func;
-   lock->line = line;
-   lock->time = jiffies;
-   break;
-   }
-
-   if (time_before(cur + 5 * HZ, jiffies) &&
-   time_before(lock->time + 5 * HZ, jiffies)) {
-   struct task_struct *task = lock->task;
-
-   if (!task)
-   continue;
-
-   LCONSOLE_WARN("%s:%d: lock %p was acquired by 
<%s:%d:%s:%d> for %lu seconds.\n",
- current->comm, current->pid,
- lock, task->comm, task->pid,
- lock->func, lock->line,
- (jiffies - lock->time) / HZ);
-   

[PATCH 25/43] staging/lustre/llite: rename ccc_device to vvp_device

2016-03-30 Thread green
From: "John L. Hammond" 

Rename struct ccc_device to struct vvp_device and merge the CCC device
methods into the VVP device methods.

Signed-off-by: John L. Hammond 
Reviewed-on: http://review.whamcloud.com/13075
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971
Reviewed-by: Lai Siyao 
Reviewed-by: James Simmons 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/cl_object.h  |   2 +-
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   | 104 +
 .../staging/lustre/lustre/llite/llite_internal.h   |   2 +-
 drivers/staging/lustre/lustre/llite/vvp_dev.c  |  84 -
 drivers/staging/lustre/lustre/llite/vvp_internal.h |  38 
 5 files changed, 102 insertions(+), 128 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h 
b/drivers/staging/lustre/lustre/include/cl_object.h
index f2bb8f8..f2a242b 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -149,7 +149,7 @@ struct cl_device_operations {
 /**
  * Device in the client stack.
  *
- * \see ccc_device, lov_device, lovsub_device, osc_device
+ * \see vvp_device, lov_device, lovsub_device, osc_device
  */
 struct cl_device {
/** Super-class. */
diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c 
b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
index 79cdf83..b0d4a3d 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
@@ -159,91 +159,6 @@ struct lu_context_key ccc_session_key = {
.lct_fini = ccc_session_key_fini
 };
 
-/* type constructor/destructor: ccc_type_{init,fini,start,stop}(). */
-/* LU_TYPE_INIT_FINI(ccc, &ccc_key, &ccc_session_key); */
-
-int ccc_device_init(const struct lu_env *env, struct lu_device *d,
-   const char *name, struct lu_device *next)
-{
-   struct ccc_device  *vdv;
-   int rc;
-
-   vdv = lu2ccc_dev(d);
-   vdv->cdv_next = lu2cl_dev(next);
-
-   LASSERT(d->ld_site && next->ld_type);
-   next->ld_site = d->ld_site;
-   rc = next->ld_type->ldt_ops->ldto_device_init(
-   env, next, next->ld_type->ldt_name, NULL);
-   if (rc == 0) {
-   lu_device_get(next);
-   lu_ref_add(&next->ld_reference, "lu-stack", &lu_site_init);
-   }
-   return rc;
-}
-
-struct lu_device *ccc_device_fini(const struct lu_env *env,
- struct lu_device *d)
-{
-   return cl2lu_dev(lu2ccc_dev(d)->cdv_next);
-}
-
-struct lu_device *ccc_device_alloc(const struct lu_env *env,
-  struct lu_device_type *t,
-  struct lustre_cfg *cfg,
-  const struct lu_device_operations *luops,
-  const struct cl_device_operations *clops)
-{
-   struct ccc_device *vdv;
-   struct lu_device  *lud;
-   struct cl_site*site;
-   int rc;
-
-   vdv = kzalloc(sizeof(*vdv), GFP_NOFS);
-   if (!vdv)
-   return ERR_PTR(-ENOMEM);
-
-   lud = &vdv->cdv_cl.cd_lu_dev;
-   cl_device_init(&vdv->cdv_cl, t);
-   ccc2lu_dev(vdv)->ld_ops = luops;
-   vdv->cdv_cl.cd_ops = clops;
-
-   site = kzalloc(sizeof(*site), GFP_NOFS);
-   if (site) {
-   rc = cl_site_init(site, &vdv->cdv_cl);
-   if (rc == 0) {
-   rc = lu_site_init_finish(&site->cs_lu);
-   } else {
-   LASSERT(!lud->ld_site);
-   CERROR("Cannot init lu_site, rc %d.\n", rc);
-   kfree(site);
-   }
-   } else {
-   rc = -ENOMEM;
-   }
-   if (rc != 0) {
-   ccc_device_free(env, lud);
-   lud = ERR_PTR(rc);
-   }
-   return lud;
-}
-
-struct lu_device *ccc_device_free(const struct lu_env *env,
- struct lu_device *d)
-{
-   struct ccc_device *vdv  = lu2ccc_dev(d);
-   struct cl_site*site = lu2cl_site(d->ld_site);
-   struct lu_device  *next = cl2lu_dev(vdv->cdv_next);
-
-   if (d->ld_site) {
-   cl_site_fini(site);
-   kfree(site);
-   }
-   cl_device_fini(lu2cl_dev(d));
-   kfree(vdv);
-   return next;
-}
-
 int ccc_req_init(const struct lu_env *env, struct cl_device *dev,
 struct cl_req *req)
 {
@@ -360,13 +275,13 @@ int ccc_object_init0(const struct lu_env *env,
 int ccc_object_init(const struct lu_env *env, struct lu_object *obj,
const struct lu_object_conf *conf)
 {
-   struct ccc_device *dev = lu2ccc_dev(obj->lo_dev);
+   struct vvp_device *dev = lu2vvp_dev(obj->lo_dev);
struct ccc_object *vob = lu2ccc(obj);
struct lu_object  *below;
struct lu_device  *under;
int result;
 
-   under = &dev->cdv_next->cd_lu_dev;
+   under = &dev->

[PATCH 21/43] staging/lustre/llite: clip page correctly for vvp_io_commit_sync

2016-03-30 Thread green
From: Jinshan Xiong 

The original code was wrong which clipped page incorrectly for
partial pages started with zero.

Signed-off-by: Jinshan Xiong 
Reviewed-on: http://review.whamcloud.com/8531
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4201
Reviewed-by: Andreas Dilger 
Reviewed-by: wangdi 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/llite/vvp_io.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c 
b/drivers/staging/lustre/lustre/llite/vvp_io.c
index fb6f932..e44ef21 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_io.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_io.c
@@ -595,15 +595,17 @@ static int vvp_io_commit_sync(const struct lu_env *env, 
struct cl_io *io,
if (plist->pl_nr == 0)
return 0;
 
-   if (from != 0) {
+   if (from > 0 || to != PAGE_SIZE) {
page = cl_page_list_first(plist);
-   cl_page_clip(env, page, from,
-plist->pl_nr == 1 ? to : PAGE_SIZE);
-   }
-   if (to != PAGE_SIZE && plist->pl_nr > 1) {
+   if (plist->pl_nr == 1) {
+   cl_page_clip(env, page, from, to);
+   } else if (from > 0) {
+   cl_page_clip(env, page, from, PAGE_SIZE);
+   } else {
page = cl_page_list_last(plist);
cl_page_clip(env, page, 0, to);
}
+   }
 
cl_2queue_init(queue);
cl_page_list_splice(plist, &queue->c2_qin);
-- 
2.1.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 20/43] staging/lustre: update comments after cl_lock simplification

2016-03-30 Thread green
From: Bobi Jam 

Update comments to reflect current cl_lock situations.

Signed-off-by: Bobi Jam 
Reviewed-on: http://review.whamcloud.com/13137
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6046
Reviewed-by: John L. Hammond 
Reviewed-by: Jinshan Xiong 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/cl_object.h  | 130 +++--
 .../staging/lustre/lustre/lov/lov_cl_internal.h|  13 ---
 2 files changed, 19 insertions(+), 124 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h 
b/drivers/staging/lustre/lustre/include/cl_object.h
index 8f9512e..e613007 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -1117,111 +1117,29 @@ static inline struct page *cl_page_vmpage(struct 
cl_page *page)
  *
  * LIFE CYCLE
  *
- * cl_lock is reference counted. When reference counter drops to 0, lock is
- * placed in the cache, except when lock is in CLS_FREEING state. CLS_FREEING
- * lock is destroyed when last reference is released. Referencing between
- * top-lock and its sub-locks is described in the lov documentation module.
- *
- * STATE MACHINE
- *
- * Also, cl_lock is a state machine. This requires some clarification. One of
- * the goals of client IO re-write was to make IO path non-blocking, or at
- * least to make it easier to make it non-blocking in the future. Here
- * `non-blocking' means that when a system call (read, write, truncate)
- * reaches a situation where it has to wait for a communication with the
- * server, it should --instead of waiting-- remember its current state and
- * switch to some other work.  E.g,. instead of waiting for a lock enqueue,
- * client should proceed doing IO on the next stripe, etc. Obviously this is
- * rather radical redesign, and it is not planned to be fully implemented at
- * this time, instead we are putting some infrastructure in place, that would
- * make it easier to do asynchronous non-blocking IO easier in the
- * future. Specifically, where old locking code goes to sleep (waiting for
- * enqueue, for example), new code returns cl_lock_transition::CLO_WAIT. When
- * enqueue reply comes, its completion handler signals that lock state-machine
- * is ready to transit to the next state. There is some generic code in
- * cl_lock.c that sleeps, waiting for these signals. As a result, for users of
- * this cl_lock.c code, it looks like locking is done in normal blocking
- * fashion, and it the same time it is possible to switch to the non-blocking
- * locking (simply by returning cl_lock_transition::CLO_WAIT from cl_lock.c
- * functions).
- *
- * For a description of state machine states and transitions see enum
- * cl_lock_state.
- *
- * There are two ways to restrict a set of states which lock might move to:
- *
- * - placing a "hold" on a lock guarantees that lock will not be moved
- *   into cl_lock_state::CLS_FREEING state until hold is released. Hold
- *   can be only acquired on a lock that is not in
- *   cl_lock_state::CLS_FREEING. All holds on a lock are counted in
- *   cl_lock::cll_holds. Hold protects lock from cancellation and
- *   destruction. Requests to cancel and destroy a lock on hold will be
- *   recorded, but only honored when last hold on a lock is released;
- *
- * - placing a "user" on a lock guarantees that lock will not leave
- *   cl_lock_state::CLS_NEW, cl_lock_state::CLS_QUEUING,
- *   cl_lock_state::CLS_ENQUEUED and cl_lock_state::CLS_HELD set of
- *   states, once it enters this set. That is, if a user is added onto a
- *   lock in a state not from this set, it doesn't immediately enforce
- *   lock to move to this set, but once lock enters this set it will
- *   remain there until all users are removed. Lock users are counted in
- *   cl_lock::cll_users.
- *
- *   User is used to assure that lock is not canceled or destroyed while
- *   it is being enqueued, or actively used by some IO.
- *
- *   Currently, a user always comes with a hold (cl_lock_invariant()
- *   checks that a number of holds is not less than a number of users).
- *
- * CONCURRENCY
- *
- * This is how lock state-machine operates. struct cl_lock contains a mutex
- * cl_lock::cll_guard that protects struct fields.
- *
- * - mutex is taken, and cl_lock::cll_state is examined.
- *
- * - for every state there are possible target states where lock can move
- *   into. They are tried in order. Attempts to move into next state are
- *   done by _try() functions in cl_lock.c:cl_{enqueue,unlock,wait}_try().
- *
- * - if the transition can be performed immediately, state is changed,
- *   and mutex is released.
- *
- * - if the transition requires blocking, _try() function returns
- *   cl_lock_transition::CLO_WAIT. Caller unlocks mutex and goes to
- *   sleep, waiting for possibility of lock state change. It is woken
- *   up whe

[PATCH 22/43] staging/lustre/llite: deadlock for page write

2016-03-30 Thread green
From: Jinshan Xiong 

Writing thread already locked page #1, and then wait for the
Writeback bit of page #2;

Ptlrpc thread is composing a write RPC, so it sets Writeback on
page #2 and tries to lock page #1 to make it ready.

Deadlocked.

Signed-off-by: Jinshan Xiong 
Reviewed-on: http://review.whamcloud.com/9036
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4540
Reviewed-by: wangdi 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/llite/rw26.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/rw26.c 
b/drivers/staging/lustre/lustre/llite/rw26.c
index 50d8289..f87238b 100644
--- a/drivers/staging/lustre/lustre/llite/rw26.c
+++ b/drivers/staging/lustre/lustre/llite/rw26.c
@@ -512,7 +512,7 @@ static int ll_write_begin(struct file *file, struct 
address_space *mapping,
 
/* To avoid deadlock, try to lock page first. */
vmpage = grab_cache_page_nowait(mapping, index);
-   if (unlikely(!vmpage || PageDirty(vmpage))) {
+   if (unlikely(!vmpage || PageDirty(vmpage) || PageWriteback(vmpage))) {
struct ccc_io *cio = ccc_env_io(env);
struct cl_page_list *plist = &cio->u.write.cui_queue;
 
@@ -522,7 +522,7 @@ static int ll_write_begin(struct file *file, struct 
address_space *mapping,
 * more grants. It's okay for the dirty page to be the first
 * one in commit page list, though.
 */
-   if (vmpage && PageDirty(vmpage) && plist->pl_nr > 0) {
+   if (vmpage && plist->pl_nr > 0) {
unlock_page(vmpage);
page_cache_release(vmpage);
vmpage = NULL;
-- 
2.1.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 16/43] staging/lustre/llite: remove some cl wrappers

2016-03-30 Thread green
From: "John L. Hammond" 

In llite remove the wrapper functions and macros:
  cl_i2info()
  cl_i2sbi()
  cl_iattr2fd()
  cl_inode_info
  cl_inode_mode()
  cl_inode_{a,m,c}time()
  cl_isize_{read,write,write_nolock}()

Signed-off-by: John L. Hammond 
Reviewed-on: http://review.whamcloud.com/12850
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-2675
Reviewed-by: James Simmons 
Reviewed-by: Lai Siyao 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/llite/dir.c  |  2 +-
 drivers/staging/lustre/lustre/llite/file.c |  8 ++--
 drivers/staging/lustre/lustre/llite/glimpse.c  | 10 ++---
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   | 45 +++---
 .../staging/lustre/lustre/llite/llite_internal.h   | 32 ---
 drivers/staging/lustre/lustre/llite/llite_lib.c|  2 +-
 drivers/staging/lustre/lustre/llite/vvp_object.c   |  4 +-
 7 files changed, 35 insertions(+), 68 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/dir.c 
b/drivers/staging/lustre/lustre/llite/dir.c
index 4e0a3e5..2ca4b0e 100644
--- a/drivers/staging/lustre/lustre/llite/dir.c
+++ b/drivers/staging/lustre/lustre/llite/dir.c
@@ -191,7 +191,7 @@ static int ll_dir_filler(void *_hash, struct page *page0)
body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY);
/* Checked by mdc_readpage() */
if (body->valid & OBD_MD_FLSIZE)
-   cl_isize_write(inode, body->size);
+   i_size_write(inode, body->size);
 
nrdpgs = 
(request->rq_bulk->bd_nob_transferred+PAGE_CACHE_SIZE-1)
 >> PAGE_CACHE_SHIFT;
diff --git a/drivers/staging/lustre/lustre/llite/file.c 
b/drivers/staging/lustre/lustre/llite/file.c
index 8fc9da0..c3c258f 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -1036,7 +1036,7 @@ int ll_merge_attr(const struct lu_env *env, struct inode 
*inode)
CDEBUG(D_VFSTRACE, DFID " updating i_size %llu\n",
   PFID(&lli->lli_fid), attr->cat_size);
 
-   cl_isize_write_nolock(inode, attr->cat_size);
+   i_size_write(inode, attr->cat_size);
 
inode->i_blocks = attr->cat_blocks;
 
@@ -1592,7 +1592,7 @@ ll_get_grouplock(struct inode *inode, struct file *file, 
unsigned long arg)
LASSERT(!fd->fd_grouplock.cg_lock);
spin_unlock(&lli->lli_lock);
 
-   rc = cl_get_grouplock(cl_i2info(inode)->lli_clob,
+   rc = cl_get_grouplock(ll_i2info(inode)->lli_clob,
  arg, (file->f_flags & O_NONBLOCK), &grouplock);
if (rc)
return rc;
@@ -2614,7 +2614,7 @@ int cl_sync_file_range(struct inode *inode, loff_t start, 
loff_t end,
return PTR_ERR(env);
 
io = ccc_env_thread_io(env);
-   io->ci_obj = cl_i2info(inode)->lli_clob;
+   io->ci_obj = ll_i2info(inode)->lli_clob;
io->ci_ignore_layout = ignore_layout;
 
/* initialize parameters for sync */
@@ -3629,7 +3629,7 @@ int ll_layout_restore(struct inode *inode)
   sizeof(hur->hur_user_item[0].hui_fid));
hur->hur_user_item[0].hui_extent.length = -1;
hur->hur_request.hr_itemcount = 1;
-   rc = obd_iocontrol(LL_IOC_HSM_REQUEST, cl_i2sbi(inode)->ll_md_exp,
+   rc = obd_iocontrol(LL_IOC_HSM_REQUEST, ll_i2sbi(inode)->ll_md_exp,
   len, hur, NULL);
kfree(hur);
return rc;
diff --git a/drivers/staging/lustre/lustre/llite/glimpse.c 
b/drivers/staging/lustre/lustre/llite/glimpse.c
index 88bc7c9..9b0e2ec 100644
--- a/drivers/staging/lustre/lustre/llite/glimpse.c
+++ b/drivers/staging/lustre/lustre/llite/glimpse.c
@@ -87,7 +87,7 @@ int cl_glimpse_lock(const struct lu_env *env, struct cl_io 
*io,
struct inode *inode, struct cl_object *clob, int agl)
 {
struct cl_lock_descr *descr = &ccc_env_info(env)->cti_descr;
-   struct cl_inode_info *lli   = cl_i2info(inode);
+   struct ll_inode_info *lli   = ll_i2info(inode);
const struct lu_fid  *fid   = lu_object_fid(&clob->co_lu);
struct ccc_io   *cio   = ccc_env_io(env);
struct cl_lock   *lock;
@@ -140,7 +140,7 @@ int cl_glimpse_lock(const struct lu_env *env, struct cl_io 
*io,
result = cl_wait(env, lock);
if (result == 0) {
ll_merge_attr(env, inode);
-   if (cl_isize_read(inode) > 0 &&
+   if (i_size_read(inode) > 0 &&
inode->i_blocks == 0) {
/*
 * LU-417: Add dirty pages block count
@@ -167,11 +167,11 @@ static int cl_io_get(struct inode *inode, struct lu_env 
**envout,
 {
struct lu_env *env;
struct cl_io   *io;
-   struct cl_inode_info   *lli = cl_i2info(inode);
+   struct ll

[PATCH 17/43] staging/lustre: Remove struct ll_iattr

2016-03-30 Thread green
From: Oleg Drokin 

This was a compat code from the time we had ia_attr_flags.
Instead convert all the cryptic callers that did
((struct ll_iattr *)&op_data->op_attr)->ia_attr_flags into
direct access to op_data->op_attr_flags

This also makes lustre/include/linux/obd.h not needed anymore,
so remove it.

Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/linux/obd.h | 58 ---
 drivers/staging/lustre/lustre/include/obd.h   |  2 +-
 drivers/staging/lustre/lustre/llite/file.c|  4 +-
 drivers/staging/lustre/lustre/llite/llite_lib.c   |  2 +-
 drivers/staging/lustre/lustre/mdc/mdc_lib.c   |  3 +-
 drivers/staging/lustre/lustre/obdclass/obdo.c |  3 +-
 6 files changed, 6 insertions(+), 66 deletions(-)
 delete mode 100644 drivers/staging/lustre/lustre/include/linux/obd.h

diff --git a/drivers/staging/lustre/lustre/include/linux/obd.h 
b/drivers/staging/lustre/lustre/include/linux/obd.h
deleted file mode 100644
index e1063e8..000
--- a/drivers/staging/lustre/lustre/include/linux/obd.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2011, 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef __LINUX_OBD_H
-#define __LINUX_OBD_H
-
-#ifndef __OBD_H
-#error Do not #include this file directly. #include  instead
-#endif
-
-#include "../obd_support.h"
-
-#include 
-#include 
-#include   /* for struct task_struct, for current.h */
-#include 
-
-#include "../lustre_intent.h"
-
-struct ll_iattr {
-   struct iattriattr;
-   unsigned intia_attr_flags;
-};
-
-#endif /* __LINUX_OBD_H */
diff --git a/drivers/staging/lustre/lustre/include/obd.h 
b/drivers/staging/lustre/lustre/include/obd.h
index 84cc001..ded7b10 100644
--- a/drivers/staging/lustre/lustre/include/obd.h
+++ b/drivers/staging/lustre/lustre/include/obd.h
@@ -38,7 +38,6 @@
 #define __OBD_H
 
 #include 
-#include "linux/obd.h"
 
 #define IOC_OSC_TYPE'h'
 #define IOC_OSC_MIN_NR   20
@@ -55,6 +54,7 @@
 #include "lustre_export.h"
 #include "lustre_fid.h"
 #include "lustre_fld.h"
+#include "lustre_intent.h"
 
 #define MAX_OBD_DEVICES 8192
 
diff --git a/drivers/staging/lustre/lustre/llite/file.c 
b/drivers/staging/lustre/lustre/llite/file.c
index c3c258f..bf2a5ee 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -45,6 +45,7 @@
 #include "../include/lustre_lite.h"
 #include 
 #include 
+#include 
 #include "llite_internal.h"
 #include "../include/lustre/ll_fiemap.h"
 
@@ -87,8 +88,7 @@ void ll_pack_inode2opdata(struct inode *inode, struct 
md_op_data *op_data,
op_data->op_attr.ia_ctime = inode->i_ctime;
op_data->op_attr.ia_size = i_size_read(inode);
op_data->op_attr_blocks = inode->i_blocks;
-   ((struct ll_iattr *)&op_data->op_attr)->ia_attr_flags =
-   ll_inode_to_ext_flags(inode->i_flags);
+   op_data->op_attr_flags = ll_inode_to_ext_flags(inode->i_flags);
op_data->op_ioepoch = ll_i2info(inode)->lli_ioepoch;
if (fh)
op_data->op_handle = *fh;
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c 
b/drivers/staging/lustre/lustre/llite/llite_lib.c
index 041d221..0f01cfc 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -1771,7 +1771,7 @@ int ll_iocontrol(struct inode *inode, struct file *file,
if (IS_ERR(op_data))
return PTR_ERR(op_data);
 
-   ((struct ll_iattr *)&op_data->op_attr)->ia_attr_flags = flags;
+   op_data->op_attr_flags = flags;
op_data->op_attr.ia_valid |= ATTR_ATTR_FLAG;
rc = md_setattr(sbi->ll_md_exp, op_data,

[PATCH 23/43] staging/lustre/llite: make sure we do cl_page_clip on the last page

2016-03-30 Thread green
From: Li Dongyang 

When we are doing a partial IO on both first and last page,
the logic currently only call cl_page_clip on the first page, which
will end up with a incorrect i_size.

Signed-off-by: Li Dongyang 
Reviewed-on: http://review.whamcloud.com/11630
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5552
Reviewed-by: Ian Costello 
Reviewed-by: Niu Yawei 
Reviewed-by: Li Xi 
Reviewed-by: Jinshan Xiong 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/llite/vvp_io.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c 
b/drivers/staging/lustre/lustre/llite/vvp_io.c
index e44ef21..1d2fc3b 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_io.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_io.c
@@ -599,12 +599,14 @@ static int vvp_io_commit_sync(const struct lu_env *env, 
struct cl_io *io,
page = cl_page_list_first(plist);
if (plist->pl_nr == 1) {
cl_page_clip(env, page, from, to);
-   } else if (from > 0) {
-   cl_page_clip(env, page, from, PAGE_SIZE);
} else {
-   page = cl_page_list_last(plist);
-   cl_page_clip(env, page, 0, to);
-   }
+   if (from > 0)
+   cl_page_clip(env, page, from, PAGE_SIZE);
+   if (to != PAGE_SIZE) {
+   page = cl_page_list_last(plist);
+   cl_page_clip(env, page, 0, to);
+   }
+   }
}
 
cl_2queue_init(queue);
-- 
2.1.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 28/43] staging/lustre/llite: rename ccc_lock to vvp_lock

2016-03-30 Thread green
From: "John L. Hammond" 

Rename struct ccc_lock to struct vvp_lock and merge the CCC lock
methods into the VVP lock methods.

Signed-off-by: John L. Hammond 
Reviewed-on: http://review.whamcloud.com/13088
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971
Reviewed-by: James Simmons 
Reviewed-by: Jinshan Xiong 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/cl_object.h  |  6 +--
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   | 52 --
 drivers/staging/lustre/lustre/llite/vvp_dev.c  |  6 +++
 drivers/staging/lustre/lustre/llite/vvp_internal.h | 20 -
 drivers/staging/lustre/lustre/llite/vvp_lock.c | 38 +---
 5 files changed, 50 insertions(+), 72 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h 
b/drivers/staging/lustre/lustre/include/cl_object.h
index 3488349..d509f94 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -1227,7 +1227,7 @@ struct cl_lock {
 /**
  * Per-layer part of cl_lock
  *
- * \see ccc_lock, lov_lock, lovsub_lock, osc_lock
+ * \see vvp_lock, lov_lock, lovsub_lock, osc_lock
  */
 struct cl_lock_slice {
struct cl_lock*cls_lock;
@@ -1254,7 +1254,7 @@ struct cl_lock_operations {
 *  @anchor for resources
 * \retval -ve  failure
 *
-* \see ccc_lock_enqueue(), lov_lock_enqueue(), lovsub_lock_enqueue(),
+* \see vvp_lock_enqueue(), lov_lock_enqueue(), lovsub_lock_enqueue(),
 * \see osc_lock_enqueue()
 */
int  (*clo_enqueue)(const struct lu_env *env,
@@ -1270,7 +1270,7 @@ struct cl_lock_operations {
/**
 * Destructor. Frees resources and the slice.
 *
-* \see ccc_lock_fini(), lov_lock_fini(), lovsub_lock_fini(),
+* \see vvp_lock_fini(), lov_lock_fini(), lovsub_lock_fini(),
 * \see osc_lock_fini()
 */
void (*clo_fini)(const struct lu_env *env, struct cl_lock_slice *slice);
diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c 
b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
index 0762032..8884317 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
@@ -67,18 +67,12 @@ static const struct cl_req_operations ccc_req_ops;
  * ccc_ prefix stands for "Common Client Code".
  */
 
-static struct kmem_cache *ccc_lock_kmem;
 static struct kmem_cache *ccc_thread_kmem;
 static struct kmem_cache *ccc_session_kmem;
 static struct kmem_cache *ccc_req_kmem;
 
 static struct lu_kmem_descr ccc_caches[] = {
{
-   .ckd_cache = &ccc_lock_kmem,
-   .ckd_name  = "ccc_lock_kmem",
-   .ckd_size  = sizeof(struct ccc_lock)
-   },
-   {
.ckd_cache = &ccc_thread_kmem,
.ckd_name  = "ccc_thread_kmem",
.ckd_size  = sizeof(struct ccc_thread_info),
@@ -221,26 +215,6 @@ void ccc_global_fini(struct lu_device_type *device_type)
lu_kmem_fini(ccc_caches);
 }
 
-int ccc_lock_init(const struct lu_env *env,
- struct cl_object *obj, struct cl_lock *lock,
- const struct cl_io *unused,
- const struct cl_lock_operations *lkops)
-{
-   struct ccc_lock *clk;
-   int result;
-
-   CLOBINVRNT(env, obj, vvp_object_invariant(obj));
-
-   clk = kmem_cache_zalloc(ccc_lock_kmem, GFP_NOFS);
-   if (clk) {
-   cl_lock_slice_add(lock, &clk->clk_cl, obj, lkops);
-   result = 0;
-   } else {
-   result = -ENOMEM;
-   }
-   return result;
-}
-
 static void vvp_object_size_lock(struct cl_object *obj)
 {
struct inode *inode = vvp_object_inode(obj);
@@ -259,27 +233,6 @@ static void vvp_object_size_unlock(struct cl_object *obj)
 
 /*
  *
- * Lock operations.
- *
- */
-
-void ccc_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice)
-{
-   struct ccc_lock *clk = cl2ccc_lock(slice);
-
-   kmem_cache_free(ccc_lock_kmem, clk);
-}
-
-int ccc_lock_enqueue(const struct lu_env *env,
-const struct cl_lock_slice *slice,
-struct cl_io *unused, struct cl_sync_io *anchor)
-{
-   CLOBINVRNT(env, slice->cls_obj, vvp_object_invariant(slice->cls_obj));
-   return 0;
-}
-
-/*
- *
  * io operations.
  *
  */
@@ -571,11 +524,6 @@ again:
  *
  */
 
-struct ccc_lock *cl2ccc_lock(const struct cl_lock_slice *slice)
-{
-   return container_of(slice, struct ccc_lock, clk_cl);
-}
-
 struct ccc_io *cl2ccc_io(const struct lu_env *env,
 const struct cl_io_slice *slice)
 {
diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c 
b/drivers/staging/lustre/lustre/llite/vvp_dev.c
index 3891b0d..4b77db3 100644
--- a/dr

[PATCH 27/43] staging/lustre/llite: rename ccc_page to vvp_page

2016-03-30 Thread green
From: "John L. Hammond" 

Rename struct ccc_page to struct vvp_page and remove obsolete CCC page
methods.

Signed-off-by: John L. Hammond 
Reviewed-on: http://review.whamcloud.com/13086
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971
Reviewed-by: James Simmons 
Reviewed-by: Jinshan Xiong 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/cl_object.h  |   2 +-
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   |  28 --
 drivers/staging/lustre/lustre/llite/llite_close.c  |  12 +--
 .../staging/lustre/lustre/llite/llite_internal.h   |   4 +-
 drivers/staging/lustre/lustre/llite/rw.c   |  14 +--
 drivers/staging/lustre/lustre/llite/rw26.c |  10 +-
 drivers/staging/lustre/lustre/llite/vvp_dev.c  |  12 +--
 drivers/staging/lustre/lustre/llite/vvp_internal.h |  38 
 drivers/staging/lustre/lustre/llite/vvp_io.c   |  34 +++
 drivers/staging/lustre/lustre/llite/vvp_object.c   |   2 +-
 drivers/staging/lustre/lustre/llite/vvp_page.c | 107 +
 11 files changed, 131 insertions(+), 132 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h 
b/drivers/staging/lustre/lustre/include/cl_object.h
index d3271ff..3488349 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -769,7 +769,7 @@ struct cl_page {
 /**
  * Per-layer part of cl_page.
  *
- * \see ccc_page, lov_page, osc_page
+ * \see vvp_page, lov_page, osc_page
  */
 struct cl_page_slice {
struct cl_page*cpl_page;
diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c 
b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
index 9db0510..0762032 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
@@ -259,29 +259,6 @@ static void vvp_object_size_unlock(struct cl_object *obj)
 
 /*
  *
- * Page operations.
- *
- */
-
-int ccc_fail(const struct lu_env *env, const struct cl_page_slice *slice)
-{
-   /*
-* Cached read?
-*/
-   LBUG();
-   return 0;
-}
-
-int ccc_transient_page_prep(const struct lu_env *env,
-   const struct cl_page_slice *slice,
-   struct cl_io *unused)
-{
-   /* transient page should always be sent. */
-   return 0;
-}
-
-/*
- *
  * Lock operations.
  *
  */
@@ -614,11 +591,6 @@ struct ccc_req *cl2ccc_req(const struct cl_req_slice 
*slice)
return container_of0(slice, struct ccc_req, crq_cl);
 }
 
-struct page *cl2vm_page(const struct cl_page_slice *slice)
-{
-   return cl2ccc_page(slice)->cpg_page;
-}
-
 /**
  * Initialize or update CLIO structures for regular files when new
  * meta-data arrives from the server.
diff --git a/drivers/staging/lustre/lustre/llite/llite_close.c 
b/drivers/staging/lustre/lustre/llite/llite_close.c
index 6e99d34..8d23980 100644
--- a/drivers/staging/lustre/lustre/llite/llite_close.c
+++ b/drivers/staging/lustre/lustre/llite/llite_close.c
@@ -46,26 +46,26 @@
 #include "llite_internal.h"
 
 /** records that a write is in flight */
-void vvp_write_pending(struct vvp_object *club, struct ccc_page *page)
+void vvp_write_pending(struct vvp_object *club, struct vvp_page *page)
 {
struct ll_inode_info *lli = ll_i2info(club->vob_inode);
 
spin_lock(&lli->lli_lock);
lli->lli_flags |= LLIF_SOM_DIRTY;
-   if (page && list_empty(&page->cpg_pending_linkage))
-   list_add(&page->cpg_pending_linkage, &club->vob_pending_list);
+   if (page && list_empty(&page->vpg_pending_linkage))
+   list_add(&page->vpg_pending_linkage, &club->vob_pending_list);
spin_unlock(&lli->lli_lock);
 }
 
 /** records that a write has completed */
-void vvp_write_complete(struct vvp_object *club, struct ccc_page *page)
+void vvp_write_complete(struct vvp_object *club, struct vvp_page *page)
 {
struct ll_inode_info *lli = ll_i2info(club->vob_inode);
int rc = 0;
 
spin_lock(&lli->lli_lock);
-   if (page && !list_empty(&page->cpg_pending_linkage)) {
-   list_del_init(&page->cpg_pending_linkage);
+   if (page && !list_empty(&page->vpg_pending_linkage)) {
+   list_del_init(&page->vpg_pending_linkage);
rc = 1;
}
spin_unlock(&lli->lli_lock);
diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h 
b/drivers/staging/lustre/lustre/llite/llite_internal.h
index 1c39d15..78b3edd 100644
--- a/drivers/staging/lustre/lustre/llite/llite_internal.h
+++ b/drivers/staging/lustre/lustre/llite/llite_internal.h
@@ -828,8 +828,8 @@ struct ll_close_queue {
atomic_tlcq_stop;
 };
 
-void vvp_write_pending(struct vvp_object *club, struct ccc_page *page);
-void vvp_write_complete(struct vvp_object *cl

[PATCH 26/43] staging/lustre/llite: rename ccc_object to vvp_object

2016-03-30 Thread green
From: "John L. Hammond" 

Rename struct ccc_object to struct vvp_object and merge the CCC object
methods into the VVP object methods.

Signed-off-by: John L. Hammond 
Reviewed-on: http://review.whamcloud.com/13077
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971
Reviewed-by: James Simmons 
Reviewed-by: Dmitry Eremin 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/cl_object.h  |   4 +-
 drivers/staging/lustre/lustre/llite/glimpse.c  |   4 +-
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   | 166 ++---
 drivers/staging/lustre/lustre/llite/llite_close.c  |  22 +--
 .../staging/lustre/lustre/llite/llite_internal.h   |   6 +-
 drivers/staging/lustre/lustre/llite/llite_lib.c|   4 +-
 drivers/staging/lustre/lustre/llite/llite_mmap.c   |  16 +-
 drivers/staging/lustre/lustre/llite/rw.c   |   4 +-
 drivers/staging/lustre/lustre/llite/rw26.c |   6 +-
 drivers/staging/lustre/lustre/llite/vvp_dev.c  |  10 +-
 drivers/staging/lustre/lustre/llite/vvp_internal.h |  61 
 drivers/staging/lustre/lustre/llite/vvp_io.c   |  36 ++---
 drivers/staging/lustre/lustre/llite/vvp_object.c   | 121 +--
 drivers/staging/lustre/lustre/llite/vvp_page.c |  40 ++---
 .../staging/lustre/lustre/osc/osc_cl_internal.h|   2 +-
 15 files changed, 231 insertions(+), 271 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h 
b/drivers/staging/lustre/lustre/include/cl_object.h
index f2a242b..d3271ff 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -245,7 +245,7 @@ enum cl_attr_valid {
  *be discarded from the memory, all its sub-objects are torn-down and
  *destroyed too.
  *
- * \see ccc_object, lov_object, lovsub_object, osc_object
+ * \see vvp_object, lov_object, lovsub_object, osc_object
  */
 struct cl_object {
/** super class */
@@ -385,7 +385,7 @@ struct cl_object_operations {
 * object. Layers are supposed to fill parts of \a lvb that will be
 * shipped to the glimpse originator as a glimpse result.
 *
-* \see ccc_object_glimpse(), lovsub_object_glimpse(),
+* \see vvp_object_glimpse(), lovsub_object_glimpse(),
 * \see osc_object_glimpse()
 */
int (*coo_glimpse)(const struct lu_env *env,
diff --git a/drivers/staging/lustre/lustre/llite/glimpse.c 
b/drivers/staging/lustre/lustre/llite/glimpse.c
index a634633..d76fa16 100644
--- a/drivers/staging/lustre/lustre/llite/glimpse.c
+++ b/drivers/staging/lustre/lustre/llite/glimpse.c
@@ -69,14 +69,14 @@ static const struct cl_lock_descr whole_file = {
 blkcnt_t dirty_cnt(struct inode *inode)
 {
blkcnt_t cnt = 0;
-   struct ccc_object *vob = cl_inode2ccc(inode);
+   struct vvp_object *vob = cl_inode2vvp(inode);
void  *results[1];
 
if (inode->i_mapping)
cnt += radix_tree_gang_lookup_tag(&inode->i_mapping->page_tree,
  results, 0, 1,
  PAGECACHE_TAG_DIRTY);
-   if (cnt == 0 && atomic_read(&vob->cob_mmap_cnt) > 0)
+   if (cnt == 0 && atomic_read(&vob->vob_mmap_cnt) > 0)
cnt = 1;
 
return (cnt > 0) ? 1 : 0;
diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c 
b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
index b0d4a3d..9db0510 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
@@ -68,7 +68,6 @@ static const struct cl_req_operations ccc_req_ops;
  */
 
 static struct kmem_cache *ccc_lock_kmem;
-static struct kmem_cache *ccc_object_kmem;
 static struct kmem_cache *ccc_thread_kmem;
 static struct kmem_cache *ccc_session_kmem;
 static struct kmem_cache *ccc_req_kmem;
@@ -80,11 +79,6 @@ static struct lu_kmem_descr ccc_caches[] = {
.ckd_size  = sizeof(struct ccc_lock)
},
{
-   .ckd_cache = &ccc_object_kmem,
-   .ckd_name  = "ccc_object_kmem",
-   .ckd_size  = sizeof(struct ccc_object)
-   },
-   {
.ckd_cache = &ccc_thread_kmem,
.ckd_name  = "ccc_thread_kmem",
.ckd_size  = sizeof(struct ccc_thread_info),
@@ -227,84 +221,6 @@ void ccc_global_fini(struct lu_device_type *device_type)
lu_kmem_fini(ccc_caches);
 }
 
-/*
- *
- * Object operations.
- *
- */
-
-struct lu_object *ccc_object_alloc(const struct lu_env *env,
-  const struct lu_object_header *unused,
-  struct lu_device *dev,
-  const struct cl_object_operations *clops,
-  const struct lu_object_operations *luops)
-{
-   struct ccc_object *vob;
-   struct lu_object  *obj;
-
-   

[PATCH 29/43] staging/lustre:llite: remove struct ll_ra_read

2016-03-30 Thread green
From: "John L. Hammond" 

Ever since removal of the the unused function ll_ra_read_get(),
the struct ll_ra_read members lrr_reader and lrr_linkage and
the struct ll_readahead_state member ras_read_beads unnecessary
so remove them.
In struct vvp_io replace the struct ll_ra_read cui_bead member with
cui_ra_start and cui_ra_count.

Signed-off-by: John L. Hammond 
Reviewed-on: http://review.whamcloud.com/13347
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971
Reviewed-by: Bobi Jam 
Reviewed-by: Lai Siyao 
Reviewed-by: Jinshan Xiong 
Signed-off-by: Oleg Drokin 
---
 .../staging/lustre/lustre/llite/llite_internal.h   | 30 +++-
 drivers/staging/lustre/lustre/llite/rw.c   | 53 ++
 drivers/staging/lustre/lustre/llite/vvp_io.c   | 31 -
 3 files changed, 28 insertions(+), 86 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h 
b/drivers/staging/lustre/lustre/llite/llite_internal.h
index 78b3edd..9dd4325 100644
--- a/drivers/staging/lustre/lustre/llite/llite_internal.h
+++ b/drivers/staging/lustre/lustre/llite/llite_internal.h
@@ -528,13 +528,6 @@ struct ll_sb_info {
struct completionll_kobj_unregister;
 };
 
-struct ll_ra_read {
-   pgoff_t  lrr_start;
-   pgoff_t  lrr_count;
-   struct task_struct *lrr_reader;
-   struct list_head  lrr_linkage;
-};
-
 /*
  * per file-descriptor read-ahead data.
  */
@@ -593,12 +586,6 @@ struct ll_readahead_state {
 */
unsigned long   ras_request_index;
/*
-* list of struct ll_ra_read's one per read(2) call current in
-* progress against this file descriptor. Used by read-ahead code,
-* protected by ->ras_lock.
-*/
-   struct list_head  ras_read_beads;
-   /*
 * The following 3 items are used for detecting the stride I/O
 * mode.
 * In stride I/O mode,
@@ -666,8 +653,7 @@ static inline int ll_need_32bit_api(struct ll_sb_info *sbi)
 #endif
 }
 
-void ll_ra_read_in(struct file *f, struct ll_ra_read *rar);
-void ll_ra_read_ex(struct file *f, struct ll_ra_read *rar);
+void ll_ras_enter(struct file *f);
 
 /* llite/lproc_llite.c */
 int ldebugfs_register_mountpoint(struct dentry *parent,
@@ -876,14 +862,12 @@ struct vvp_io {
} fault;
} fault;
} u;
-   /**
-* Read-ahead state used by read and page-fault IO contexts.
-*/
-   struct ll_ra_readcui_bead;
-   /**
-* Set when cui_bead has been initialized.
-*/
-   int   cui_ra_window_set;
+
+   /* Readahead state. */
+   pgoff_t cui_ra_start;
+   pgoff_t cui_ra_count;
+   /* Set when cui_ra_{start,count} have been initialized. */
+   boolcui_ra_valid;
 };
 
 /**
diff --git a/drivers/staging/lustre/lustre/llite/rw.c 
b/drivers/staging/lustre/lustre/llite/rw.c
index 2c4d4c4..f06d8be 100644
--- a/drivers/staging/lustre/lustre/llite/rw.c
+++ b/drivers/staging/lustre/lustre/llite/rw.c
@@ -258,38 +258,15 @@ static int index_in_window(unsigned long index, unsigned 
long point,
return start <= index && index <= end;
 }
 
-static struct ll_readahead_state *ll_ras_get(struct file *f)
+void ll_ras_enter(struct file *f)
 {
-   struct ll_file_data   *fd;
-
-   fd = LUSTRE_FPRIVATE(f);
-   return &fd->fd_ras;
-}
-
-void ll_ra_read_in(struct file *f, struct ll_ra_read *rar)
-{
-   struct ll_readahead_state *ras;
-
-   ras = ll_ras_get(f);
+   struct ll_file_data *fd = LUSTRE_FPRIVATE(f);
+   struct ll_readahead_state *ras = &fd->fd_ras;
 
spin_lock(&ras->ras_lock);
ras->ras_requests++;
ras->ras_request_index = 0;
ras->ras_consecutive_requests++;
-   rar->lrr_reader = current;
-
-   list_add(&rar->lrr_linkage, &ras->ras_read_beads);
-   spin_unlock(&ras->ras_lock);
-}
-
-void ll_ra_read_ex(struct file *f, struct ll_ra_read *rar)
-{
-   struct ll_readahead_state *ras;
-
-   ras = ll_ras_get(f);
-
-   spin_lock(&ras->ras_lock);
-   list_del_init(&rar->lrr_linkage);
spin_unlock(&ras->ras_lock);
 }
 
@@ -551,7 +528,6 @@ int ll_readahead(const struct lu_env *env, struct cl_io *io,
unsigned long start = 0, end = 0, reserved;
unsigned long ra_end, len, mlen = 0;
struct inode *inode;
-   struct ll_ra_read *bead;
struct ra_io_arg *ria = &vti->vti_ria;
struct cl_object *clob;
int ret = 0;
@@ -575,17 +551,15 @@ int ll_readahead(const struct lu_env *env, struct cl_io 
*io,
}
 
spin_lock(&ras->ras_lock);
-   if (vio->cui_ra_window_set)
-   bead = &vio->cui_bead;
-   else
-   bead = NULL;
 
/* Enlarge the RA window to encompass the full read */
-   if (bead && ras->ras_window_start + ras->ras_window_len <
-   bead->lrr_start + bead->lrr_count) {
-   ras->ras_window_len = bead->lrr_st

[PATCH 38/43] staging/lustre/llite: Move ll_dirent_type_get and make it static

2016-03-30 Thread green
From: Oleg Drokin 

ll_dirent_type_get is only used in one place in llite/dir.c,
so move it there.

Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/llite/dir.c  | 22 ++
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   | 22 --
 drivers/staging/lustre/lustre/llite/vvp_internal.h |  1 -
 3 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/dir.c 
b/drivers/staging/lustre/lustre/llite/dir.c
index 2ca4b0e..b085fb4 100644
--- a/drivers/staging/lustre/lustre/llite/dir.c
+++ b/drivers/staging/lustre/lustre/llite/dir.c
@@ -469,6 +469,28 @@ fail:
goto out_unlock;
 }
 
+/**
+ * return IF_* type for given lu_dirent entry.
+ * IF_* flag shld be converted to particular OS file type in
+ * platform llite module.
+ */
+static __u16 ll_dirent_type_get(struct lu_dirent *ent)
+{
+   __u16 type = 0;
+   struct luda_type *lt;
+   int len = 0;
+
+   if (le32_to_cpu(ent->lde_attrs) & LUDA_TYPE) {
+   const unsigned int align = sizeof(struct luda_type) - 1;
+
+   len = le16_to_cpu(ent->lde_namelen);
+   len = (len + align) & ~align;
+   lt = (void *)ent->lde_name + len;
+   type = IFTODT(le16_to_cpu(lt->lt_type));
+   }
+   return type;
+}
+
 int ll_dir_read(struct inode *inode, struct dir_context *ctx)
 {
struct ll_inode_info *info   = ll_i2info(inode);
diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c 
b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
index 164737a..6c00715 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
@@ -280,28 +280,6 @@ void cl_inode_fini(struct inode *inode)
 }
 
 /**
- * return IF_* type for given lu_dirent entry.
- * IF_* flag shld be converted to particular OS file type in
- * platform llite module.
- */
-__u16 ll_dirent_type_get(struct lu_dirent *ent)
-{
-   __u16 type = 0;
-   struct luda_type *lt;
-   int len = 0;
-
-   if (le32_to_cpu(ent->lde_attrs) & LUDA_TYPE) {
-   const unsigned int align = sizeof(struct luda_type) - 1;
-
-   len = le16_to_cpu(ent->lde_namelen);
-   len = (len + align) & ~align;
-   lt = (void *)ent->lde_name + len;
-   type = IFTODT(le16_to_cpu(lt->lt_type));
-   }
-   return type;
-}
-
-/**
  * build inode number from passed @fid
  */
 __u64 cl_fid_build_ino(const struct lu_fid *fid, int api32)
diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h 
b/drivers/staging/lustre/lustre/llite/vvp_internal.h
index fe29fb5..06e2726 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_internal.h
+++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h
@@ -376,7 +376,6 @@ int cl_file_inode_init(struct inode *inode, struct 
lustre_md *md);
 void cl_inode_fini(struct inode *inode);
 int cl_local_size(struct inode *inode);
 
-__u16 ll_dirent_type_get(struct lu_dirent *ent);
 __u64 cl_fid_build_ino(const struct lu_fid *fid, int api32);
 __u32 cl_fid_build_gen(const struct lu_fid *fid);
 
-- 
2.1.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 35/43] staging/lustre/llite: Rename struct vvp_thread_info to ll_thread_info

2016-03-30 Thread green
From: John Hammond 

struct vvp_thread_info is used in the non-VVP parts of llite so rename
it struct ll_thread_info. Rename supporting functions accordingly.

Signed-off-by: John L. Hammond 
Signed-off-by: Jinshan Xiong 
Reviewed-on: http://review.whamcloud.com/13714
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971
Reviewed-by: Bobi Jam 
Reviewed-by: James Simmons 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/llite/file.c |  6 ++--
 .../staging/lustre/lustre/llite/llite_internal.h   | 30 ++--
 drivers/staging/lustre/lustre/llite/rw.c   |  6 ++--
 drivers/staging/lustre/lustre/llite/vvp_dev.c  | 33 +-
 4 files changed, 40 insertions(+), 35 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/file.c 
b/drivers/staging/lustre/lustre/llite/file.c
index 210d1e2..f7aabac 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -1221,7 +1221,7 @@ static ssize_t ll_file_read_iter(struct kiocb *iocb, 
struct iov_iter *to)
if (IS_ERR(env))
return PTR_ERR(env);
 
-   args = vvp_env_args(env, IO_NORMAL);
+   args = ll_env_args(env, IO_NORMAL);
args->u.normal.via_iter = to;
args->u.normal.via_iocb = iocb;
 
@@ -1245,7 +1245,7 @@ static ssize_t ll_file_write_iter(struct kiocb *iocb, 
struct iov_iter *from)
if (IS_ERR(env))
return PTR_ERR(env);
 
-   args = vvp_env_args(env, IO_NORMAL);
+   args = ll_env_args(env, IO_NORMAL);
args->u.normal.via_iter = from;
args->u.normal.via_iocb = iocb;
 
@@ -1271,7 +1271,7 @@ static ssize_t ll_file_splice_read(struct file *in_file, 
loff_t *ppos,
if (IS_ERR(env))
return PTR_ERR(env);
 
-   args = vvp_env_args(env, IO_SPLICE);
+   args = ll_env_args(env, IO_SPLICE);
args->u.splice.via_pipe = pipe;
args->u.splice.via_flags = flags;
 
diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h 
b/drivers/staging/lustre/lustre/llite/llite_internal.h
index 8b943df..a6ee2fe 100644
--- a/drivers/staging/lustre/lustre/llite/llite_internal.h
+++ b/drivers/staging/lustre/lustre/llite/llite_internal.h
@@ -855,30 +855,30 @@ struct ll_cl_context {
int  lcc_refcheck;
 };
 
-struct vvp_thread_info {
-   struct vvp_io_args   vti_args;
-   struct ra_io_arg vti_ria;
-   struct ll_cl_context vti_io_ctx;
+struct ll_thread_info {
+   struct vvp_io_args   lti_args;
+   struct ra_io_arg lti_ria;
+   struct ll_cl_context lti_io_ctx;
 };
 
-static inline struct vvp_thread_info *vvp_env_info(const struct lu_env *env)
+extern struct lu_context_key ll_thread_key;
+static inline struct ll_thread_info *ll_env_info(const struct lu_env *env)
 {
-   extern struct lu_context_key vvp_key;
-   struct vvp_thread_info  *info;
+   struct ll_thread_info *lti;
 
-   info = lu_context_key_get(&env->le_ctx, &vvp_key);
-   LASSERT(info);
-   return info;
+   lti = lu_context_key_get(&env->le_ctx, &ll_thread_key);
+   LASSERT(lti);
+   return lti;
 }
 
-static inline struct vvp_io_args *vvp_env_args(const struct lu_env *env,
-  enum vvp_io_subtype type)
+static inline struct vvp_io_args *ll_env_args(const struct lu_env *env,
+ enum vvp_io_subtype type)
 {
-   struct vvp_io_args *ret = &vvp_env_info(env)->vti_args;
+   struct vvp_io_args *via = &ll_env_info(env)->lti_args;
 
-   ret->via_io_subtype = type;
+   via->via_io_subtype = type;
 
-   return ret;
+   return via;
 }
 
 int vvp_global_init(void);
diff --git a/drivers/staging/lustre/lustre/llite/rw.c 
b/drivers/staging/lustre/lustre/llite/rw.c
index 634f0bb..f9bc3e4 100644
--- a/drivers/staging/lustre/lustre/llite/rw.c
+++ b/drivers/staging/lustre/lustre/llite/rw.c
@@ -102,7 +102,7 @@ struct ll_cl_context *ll_cl_init(struct file *file, struct 
page *vmpage)
if (IS_ERR(env))
return ERR_CAST(env);
 
-   lcc = &vvp_env_info(env)->vti_io_ctx;
+   lcc = &ll_env_info(env)->lti_io_ctx;
memset(lcc, 0, sizeof(*lcc));
lcc->lcc_env = env;
lcc->lcc_refcheck = refcheck;
@@ -523,12 +523,12 @@ int ll_readahead(const struct lu_env *env, struct cl_io 
*io,
 bool hit)
 {
struct vvp_io *vio = vvp_env_io(env);
-   struct vvp_thread_info *vti = vvp_env_info(env);
+   struct ll_thread_info *lti = ll_env_info(env);
struct cl_attr *attr = ccc_env_thread_attr(env);
unsigned long start = 0, end = 0, reserved;
unsigned long ra_end, len, mlen = 0;
struct inode *inode;
-   struct ra_io_arg *ria = &vti->vti_ria;
+   struct ra_io_arg *ria = lti_ria;
struct cl_object *clob;
int ret = 0;
__u64 kms;
diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c 
b/drivers/s

[PATCH 41/43] staging/lustre/ldlm: ELC picks locks in a safer policy

2016-03-30 Thread green
From: Jinshan Xiong 

Change the policy of ELC to pick locks that have no dirty pages,
no page in writeback state, and no locked pages.

Signed-off-by: Jinshan Xiong 
Reviewed-on: http://review.whamcloud.com/9175
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4300
Reviewed-by: Andreas Dilger 
Reviewed-by: Bobi Jam 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/lustre_dlm.h | 13 ++
 drivers/staging/lustre/lustre/ldlm/ldlm_request.c  | 28 +++---
 drivers/staging/lustre/lustre/mdc/mdc_request.c|  4 ++--
 drivers/staging/lustre/lustre/osc/osc_lock.c   |  4 +++-
 drivers/staging/lustre/lustre/osc/osc_request.c| 19 ++-
 5 files changed, 39 insertions(+), 29 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h 
b/drivers/staging/lustre/lustre/include/lustre_dlm.h
index b1abdc2..9cade14 100644
--- a/drivers/staging/lustre/lustre/include/lustre_dlm.h
+++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h
@@ -270,7 +270,7 @@ struct ldlm_pool {
struct completionpl_kobj_unregister;
 };
 
-typedef int (*ldlm_cancel_for_recovery)(struct ldlm_lock *lock);
+typedef int (*ldlm_cancel_cbt)(struct ldlm_lock *lock);
 
 /**
  * LVB operations.
@@ -447,8 +447,11 @@ struct ldlm_namespace {
/** Limit of parallel AST RPC count. */
unsignedns_max_parallel_ast;
 
-   /** Callback to cancel locks before replaying it during recovery. */
-   ldlm_cancel_for_recovery ns_cancel_for_recovery;
+   /**
+* Callback to check if a lock is good to be canceled by ELC or
+* during recovery.
+*/
+   ldlm_cancel_cbt ns_cancel;
 
/** LDLM lock stats */
struct lprocfs_stats*ns_stats;
@@ -480,9 +483,9 @@ static inline int ns_connect_lru_resize(struct 
ldlm_namespace *ns)
 }
 
 static inline void ns_register_cancel(struct ldlm_namespace *ns,
- ldlm_cancel_for_recovery arg)
+ ldlm_cancel_cbt arg)
 {
-   ns->ns_cancel_for_recovery = arg;
+   ns->ns_cancel = arg;
 }
 
 struct ldlm_lock;
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c 
b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index 42925ac..2f12194 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -1137,7 +1137,6 @@ static ldlm_policy_res_t 
ldlm_cancel_no_wait_policy(struct ldlm_namespace *ns,
int count)
 {
ldlm_policy_res_t result = LDLM_POLICY_CANCEL_LOCK;
-   ldlm_cancel_for_recovery cb = ns->ns_cancel_for_recovery;
 
/* don't check added & count since we want to process all locks
 * from unused list.
@@ -1147,7 +1146,7 @@ static ldlm_policy_res_t 
ldlm_cancel_no_wait_policy(struct ldlm_namespace *ns,
switch (lock->l_resource->lr_type) {
case LDLM_EXTENT:
case LDLM_IBITS:
-   if (cb && cb(lock))
+   if (ns->ns_cancel && ns->ns_cancel(lock) != 0)
break;
default:
result = LDLM_POLICY_SKIP_LOCK;
@@ -1197,8 +1196,13 @@ static ldlm_policy_res_t ldlm_cancel_lrur_policy(struct 
ldlm_namespace *ns,
/* Stop when SLV is not yet come from server or lv is smaller than
 * it is.
 */
-   return (slv == 0 || lv < slv) ?
-   LDLM_POLICY_KEEP_LOCK : LDLM_POLICY_CANCEL_LOCK;
+   if (slv == 0 || lv < slv)
+   return LDLM_POLICY_KEEP_LOCK;
+
+   if (ns->ns_cancel && ns->ns_cancel(lock) == 0)
+   return LDLM_POLICY_KEEP_LOCK;
+
+   return LDLM_POLICY_CANCEL_LOCK;
 }
 
 /**
@@ -1236,11 +1240,17 @@ static ldlm_policy_res_t ldlm_cancel_aged_policy(struct 
ldlm_namespace *ns,
 int unused, int added,
 int count)
 {
-   /* Stop LRU processing if young lock is found and we reach past count */
-   return ((added >= count) &&
-   time_before(cfs_time_current(),
-   cfs_time_add(lock->l_last_used, ns->ns_max_age))) ?
-   LDLM_POLICY_KEEP_LOCK : LDLM_POLICY_CANCEL_LOCK;
+   if (added >= count)
+   return LDLM_POLICY_KEEP_LOCK;
+
+   if (time_before(cfs_time_current(),
+   cfs_time_add(lock->l_last_used, ns->ns_max_age)))
+   return LDLM_POLICY_KEEP_LOCK;
+
+   if (ns->ns_cancel && ns->ns_cancel(lock) == 0)
+   return LDLM_POLICY_KEEP_LOCK;
+
+   return LDLM_POLICY_CANCEL_LOCK;
 }
 
 /**
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c 
b/drivers/staging/lustre/lustre/mdc/mdc_request.c
index 55dd8ef..98b27f1 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_request.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c
@@ -2249,7 +2249,7 @@ static struct 

[PATCH 40/43] staging/lustre/llite: Remove unused vui_local_lock field

2016-03-30 Thread green
From: Oleg Drokin 

vvp_io_setattr_lock is the only user that sets it, but it's
never checked anywhere, so could go away.
Also get rid of enum ccc_setattr_lock_type that becomes unused.

Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/llite/vvp_internal.h | 12 
 drivers/staging/lustre/lustre/llite/vvp_io.c   |  3 ---
 2 files changed, 15 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h 
b/drivers/staging/lustre/lustre/llite/vvp_internal.h
index ce4aeca..27b9b0a 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_internal.h
+++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h
@@ -53,15 +53,6 @@ struct obd_device;
 struct obd_export;
 struct page;
 
-enum ccc_setattr_lock_type {
-   /** Locking is done by server */
-   SETATTR_NOLOCK,
-   /** Extent lock is enqueued */
-   SETATTR_EXTENT_LOCK,
-   /** Existing local extent lock is used */
-   SETATTR_MATCH_LOCK
-};
-
 /* specific architecture can implement only part of this list */
 enum vvp_io_subtype {
/** normal IO */
@@ -112,9 +103,6 @@ struct vvp_io {
boolft_flags_valid;
} fault;
struct {
-   enum ccc_setattr_lock_type vui_local_lock;
-   } setattr;
-   struct {
struct pipe_inode_info  *vui_pipe;
unsigned int vui_flags;
} splice;
diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c 
b/drivers/staging/lustre/lustre/llite/vvp_io.c
index 366ac1c..aed7b8e 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_io.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_io.c
@@ -567,7 +567,6 @@ static int vvp_io_setattr_iter_init(const struct lu_env 
*env,
 static int vvp_io_setattr_lock(const struct lu_env *env,
   const struct cl_io_slice *ios)
 {
-   struct vvp_io *vio = vvp_env_io(env);
struct cl_io  *io  = ios->cis_io;
__u64 new_size;
__u32 enqflags = 0;
@@ -585,8 +584,6 @@ static int vvp_io_setattr_lock(const struct lu_env *env,
new_size = 0;
}
 
-   vio->u.setattr.vui_local_lock = SETATTR_EXTENT_LOCK;
-
return vvp_io_one_lock(env, io, enqflags, CLM_WRITE,
   new_size, OBD_OBJECT_EOF);
 }
-- 
2.1.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 31/43] staging/lustre/llite: use vui prefix for struct vvp_io members

2016-03-30 Thread green
From: "John L. Hammond" 

Rename members of struct vvp_io to used to start with vui_ rather than
cui_.  Rename several instances of struct vvp_io * from cio to vio.

Signed-off-by: John L. Hammond 
Reviewed-on: http://review.whamcloud.com/13363
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971
Reviewed-by: Bobi Jam 
Reviewed-by: Lai Siyao 
Reviewed-by: Jinshan Xiong 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/llite/file.c |  20 ++--
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   |  34 +++---
 drivers/staging/lustre/lustre/llite/llite_mmap.c   |   6 +-
 drivers/staging/lustre/lustre/llite/rw.c   |  24 ++--
 drivers/staging/lustre/lustre/llite/rw26.c |  20 ++--
 drivers/staging/lustre/lustre/llite/vvp_internal.h |  38 +++---
 drivers/staging/lustre/lustre/llite/vvp_io.c   | 131 +++--
 drivers/staging/lustre/lustre/llite/vvp_page.c |   4 +-
 8 files changed, 139 insertions(+), 138 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/file.c 
b/drivers/staging/lustre/lustre/llite/file.c
index 27e7e65..63aa080 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -1135,18 +1135,18 @@ restart:
ll_io_init(io, file, iot == CIT_WRITE);
 
if (cl_io_rw_init(env, io, iot, *ppos, count) == 0) {
-   struct vvp_io *cio = vvp_env_io(env);
+   struct vvp_io *vio = vvp_env_io(env);
int write_mutex_locked = 0;
 
-   cio->cui_fd  = LUSTRE_FPRIVATE(file);
-   cio->cui_io_subtype = args->via_io_subtype;
+   vio->vui_fd  = LUSTRE_FPRIVATE(file);
+   vio->vui_io_subtype = args->via_io_subtype;
 
-   switch (cio->cui_io_subtype) {
+   switch (vio->vui_io_subtype) {
case IO_NORMAL:
-   cio->cui_iter = args->u.normal.via_iter;
-   cio->cui_iocb = args->u.normal.via_iocb;
+   vio->vui_iter = args->u.normal.via_iter;
+   vio->vui_iocb = args->u.normal.via_iocb;
if ((iot == CIT_WRITE) &&
-   !(cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
+   !(vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
if (mutex_lock_interruptible(&lli->
   
lli_write_mutex)) {
result = -ERESTARTSYS;
@@ -1157,11 +1157,11 @@ restart:
down_read(&lli->lli_trunc_sem);
break;
case IO_SPLICE:
-   cio->u.splice.cui_pipe = args->u.splice.via_pipe;
-   cio->u.splice.cui_flags = args->u.splice.via_flags;
+   vio->u.splice.vui_pipe = args->u.splice.via_pipe;
+   vio->u.splice.vui_flags = args->u.splice.via_flags;
break;
default:
-   CERROR("Unknown IO type - %u\n", cio->cui_io_subtype);
+   CERROR("Unknown IO type - %u\n", vio->vui_io_subtype);
LBUG();
}
result = cl_io_loop(env, io);
diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c 
b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
index 9a9d706..630c371 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
@@ -210,19 +210,19 @@ int vvp_io_one_lock_index(const struct lu_env *env, 
struct cl_io *io,
  __u32 enqflags, enum cl_lock_mode mode,
  pgoff_t start, pgoff_t end)
 {
-   struct vvp_io *cio = vvp_env_io(env);
-   struct cl_lock_descr   *descr = &cio->cui_link.cill_descr;
+   struct vvp_io  *vio   = vvp_env_io(env);
+   struct cl_lock_descr   *descr = &vio->vui_link.cill_descr;
struct cl_object   *obj   = io->ci_obj;
 
CLOBINVRNT(env, obj, vvp_object_invariant(obj));
 
CDEBUG(D_VFSTRACE, "lock: %d [%lu, %lu]\n", mode, start, end);
 
-   memset(&cio->cui_link, 0, sizeof(cio->cui_link));
+   memset(&vio->vui_link, 0, sizeof(vio->vui_link));
 
-   if (cio->cui_fd && (cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
+   if (vio->vui_fd && (vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
descr->cld_mode = CLM_GROUP;
-   descr->cld_gid  = cio->cui_fd->fd_grouplock.cg_gid;
+   descr->cld_gid  = vio->vui_fd->fd_grouplock.cg_gid;
} else {
descr->cld_mode  = mode;
}
@@ -231,19 +231,19 @@ int vvp_io_one_lock_index(const struct lu_env *env, 
struct cl_io *io,
descr->cld_end   = end;
descr->cld_enq_flags = enqflags;
 
-   cl_io_lock_add(env, io, &cio->cui_link);
+   cl_io_lock_add(env, io, &vio->vui_link);

[PATCH 24/43] staging/lustre/llite: merge lclient.h into llite/vvp_internal.h

2016-03-30 Thread green
From: "John L. Hammond" 

Move the definition of struct cl_client_cache to
lustre/include/cl_object.h and move the rest of
lustre/include/lclient.h in to lustre/llite/vvp_internal.h.

Signed-off-by: John L. Hammond 
Reviewed-on: http://review.whamcloud.com/12592
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971
Reviewed-by: Jinshan Xiong 
Reviewed-by: James Simmons 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/cl_object.h  |  36 ++
 drivers/staging/lustre/lustre/include/lclient.h| 409 -
 drivers/staging/lustre/lustre/llite/glimpse.c  |   1 -
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   |   2 -
 drivers/staging/lustre/lustre/llite/lcommon_misc.c |   2 +-
 .../staging/lustre/lustre/llite/llite_internal.h   |   2 +-
 drivers/staging/lustre/lustre/llite/vvp_internal.h | 368 +-
 drivers/staging/lustre/lustre/llite/vvp_io.c   |   1 +
 drivers/staging/lustre/lustre/llite/vvp_object.c   |   1 +
 drivers/staging/lustre/lustre/llite/vvp_page.c |   1 +
 drivers/staging/lustre/lustre/lov/lov_obd.c|   1 -
 .../staging/lustre/lustre/osc/osc_cl_internal.h|   1 -
 12 files changed, 408 insertions(+), 417 deletions(-)
 delete mode 100644 drivers/staging/lustre/lustre/include/lclient.h

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h 
b/drivers/staging/lustre/lustre/include/cl_object.h
index e613007..f2bb8f8 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -97,9 +97,12 @@
  * super-class definitions.
  */
 #include "lu_object.h"
+#include 
 #include "linux/lustre_compat25.h"
 #include 
 #include 
+#include 
+#include 
 
 struct inode;
 
@@ -2317,6 +2320,39 @@ void cl_lock_descr_print(const struct lu_env *env, void 
*cookie,
 const struct cl_lock_descr *descr);
 /* @} helper */
 
+/**
+ * Data structure managing a client's cached pages. A count of
+ * "unstable" pages is maintained, and an LRU of clean pages is
+ * maintained. "unstable" pages are pages pinned by the ptlrpc
+ * layer for recovery purposes.
+ */
+struct cl_client_cache {
+   /**
+* # of users (OSCs)
+*/
+   atomic_tccc_users;
+   /**
+* # of threads are doing shrinking
+*/
+   unsigned intccc_lru_shrinkers;
+   /**
+* # of LRU entries available
+*/
+   atomic_tccc_lru_left;
+   /**
+* List of entities(OSCs) for this LRU cache
+*/
+   struct list_headccc_lru;
+   /**
+* Max # of LRU entries
+*/
+   unsigned long   ccc_lru_max;
+   /**
+* Lock to protect ccc_lru list
+*/
+   spinlock_t  ccc_lru_lock;
+};
+
 /** @} cl_page */
 
 /** \defgroup cl_lock cl_lock
diff --git a/drivers/staging/lustre/lustre/include/lclient.h 
b/drivers/staging/lustre/lustre/include/lclient.h
deleted file mode 100644
index 82af8ae..000
--- a/drivers/staging/lustre/lustre/include/lclient.h
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2011, 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * Definitions shared between vvp and liblustre, and other clients in the
- * future.
- *
- *   Author: Oleg Drokin 
- *   Author: Nikita Danilov 
- */
-
-#ifndef LCLIENT_H
-#define LCLIENT_H
-
-blkcnt_t dirty_cnt(struct inode *inode);
-
-int cl_glimpse_size0(struct inode *inode, int agl);
-int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io,
-   struct inode *inode, struct cl_object *clob, int agl);
-
-static inline int cl_glimpse_size(struct inode *inode)
-{
-   return cl_glimpse_size0(inode, 0);
-}
-
-static in

[PATCH 36/43] staging/lustre/llite: rename struct ccc_thread_info to vvp_thread_info

2016-03-30 Thread green
From: John Hammond 

struct ccc_thread_info is used in the VVP parts of llite so rename
it struct vvp_thread_info. Rename supporting functions accordingly.
Move init code from lcommon_cl.c to vvp_dev.c

Signed-off-by: John L. Hammond 
Signed-off-by: Jinshan Xiong 
Reviewed-on: http://review.whamcloud.com/13714
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971
Reviewed-by: Bobi Jam 
Reviewed-by: James Simmons 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/llite/file.c |  6 +--
 drivers/staging/lustre/lustre/llite/glimpse.c  |  6 +--
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   | 48 +-
 drivers/staging/lustre/lustre/llite/lcommon_misc.c |  4 +-
 drivers/staging/lustre/lustre/llite/llite_mmap.c   |  2 +-
 drivers/staging/lustre/lustre/llite/rw.c   |  4 +-
 drivers/staging/lustre/lustre/llite/rw26.c |  2 +-
 drivers/staging/lustre/lustre/llite/vvp_dev.c  | 34 ++-
 drivers/staging/lustre/lustre/llite/vvp_internal.h | 34 +++
 drivers/staging/lustre/lustre/llite/vvp_io.c   |  8 ++--
 10 files changed, 68 insertions(+), 80 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/file.c 
b/drivers/staging/lustre/lustre/llite/file.c
index f7aabac..69b56a8 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -998,7 +998,7 @@ int ll_merge_attr(const struct lu_env *env, struct inode 
*inode)
 {
struct ll_inode_info *lli = ll_i2info(inode);
struct cl_object *obj = lli->lli_clob;
-   struct cl_attr *attr = ccc_env_thread_attr(env);
+   struct cl_attr *attr = vvp_env_thread_attr(env);
s64 atime;
s64 mtime;
s64 ctime;
@@ -1131,7 +1131,7 @@ ll_file_io_generic(const struct lu_env *env, struct 
vvp_io_args *args,
   file->f_path.dentry->d_name.name, iot, *ppos, count);
 
 restart:
-   io = ccc_env_thread_io(env);
+   io = vvp_env_thread_io(env);
ll_io_init(io, file, iot == CIT_WRITE);
 
if (cl_io_rw_init(env, io, iot, *ppos, count) == 0) {
@@ -2612,7 +2612,7 @@ int cl_sync_file_range(struct inode *inode, loff_t start, 
loff_t end,
if (IS_ERR(env))
return PTR_ERR(env);
 
-   io = ccc_env_thread_io(env);
+   io = vvp_env_thread_io(env);
io->ci_obj = ll_i2info(inode)->lli_clob;
io->ci_ignore_layout = ignore_layout;
 
diff --git a/drivers/staging/lustre/lustre/llite/glimpse.c 
b/drivers/staging/lustre/lustre/llite/glimpse.c
index d76fa16..d8ea754 100644
--- a/drivers/staging/lustre/lustre/llite/glimpse.c
+++ b/drivers/staging/lustre/lustre/llite/glimpse.c
@@ -93,7 +93,7 @@ int cl_glimpse_lock(const struct lu_env *env, struct cl_io 
*io,
if (!(lli->lli_flags & LLIF_MDS_SIZE_LOCK)) {
CDEBUG(D_DLMTRACE, "Glimpsing inode " DFID "\n", PFID(fid));
if (lli->lli_has_smd) {
-   struct cl_lock *lock = ccc_env_lock(env);
+   struct cl_lock *lock = vvp_env_lock(env);
struct cl_lock_descr *descr = &lock->cll_descr;
 
/* NOTE: this looks like DLM lock request, but it may
@@ -163,7 +163,7 @@ static int cl_io_get(struct inode *inode, struct lu_env 
**envout,
if (S_ISREG(inode->i_mode)) {
env = cl_env_get(refcheck);
if (!IS_ERR(env)) {
-   io = ccc_env_thread_io(env);
+   io = vvp_env_thread_io(env);
io->ci_obj = clob;
*envout = env;
*ioout  = io;
@@ -238,7 +238,7 @@ int cl_local_size(struct inode *inode)
if (result > 0) {
result = io->ci_result;
} else if (result == 0) {
-   struct cl_lock *lock = ccc_env_lock(env);
+   struct cl_lock *lock = vvp_env_lock(env);
 
lock->cll_descr = whole_file;
lock->cll_descr.cld_enq_flags = CEF_PEEK;
diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c 
b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
index d28546a..5b523e33 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
@@ -65,49 +65,12 @@
  * ccc_ prefix stands for "Common Client Code".
  */
 
-static struct kmem_cache *ccc_thread_kmem;
-
-static struct lu_kmem_descr ccc_caches[] = {
-   {
-   .ckd_cache = &ccc_thread_kmem,
-   .ckd_name  = "ccc_thread_kmem",
-   .ckd_size  = sizeof(struct ccc_thread_info),
-   },
-   {
-   .ckd_cache = NULL
-   }
-};
-
 /*
  *
  * Vvp device and device type functions.
  *
  */
 
-void *ccc_key_init(const struct lu_context *ctx, struct lu_context_key *key)
-{
-   struct ccc_thread_info *info;
-
-   info = kmem_cache_zalloc(ccc_thread_kmem, GFP

[PATCH 37/43] staging/lustre/llite: Remove ccc_global_{init,fini}()

2016-03-30 Thread green
From: John Hammond 

Merge their contents into vvp_global_{init,fini}() and
{init,exit}_lustre_lite().
Rename ccc_inode_fini_* to cl_inode_fini_*.

Signed-off-by: John L. Hammond 
Signed-off-by: Jinshan Xiong 
Reviewed-on: http://review.whamcloud.com/13714
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971
Reviewed-by: Bobi Jam 
Reviewed-by: James Simmons 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   | 53 +-
 .../staging/lustre/lustre/llite/llite_internal.h   |  7 +--
 drivers/staging/lustre/lustre/llite/super25.c  | 14 +-
 drivers/staging/lustre/lustre/llite/vvp_dev.c  | 25 ++
 drivers/staging/lustre/lustre/llite/vvp_internal.h |  4 +-
 5 files changed, 46 insertions(+), 57 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c 
b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
index 5b523e33..164737a 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
@@ -72,49 +72,18 @@
  */
 
 /**
- * An `emergency' environment used by ccc_inode_fini() when cl_env_get()
- * fails. Access to this environment is serialized by ccc_inode_fini_guard
+ * An `emergency' environment used by cl_inode_fini() when cl_env_get()
+ * fails. Access to this environment is serialized by cl_inode_fini_guard
  * mutex.
  */
-static struct lu_env *ccc_inode_fini_env;
+struct lu_env *cl_inode_fini_env;
+int cl_inode_fini_refcheck;
 
 /**
  * A mutex serializing calls to slp_inode_fini() under extreme memory
  * pressure, when environments cannot be allocated.
  */
-static DEFINE_MUTEX(ccc_inode_fini_guard);
-static int dummy_refcheck;
-
-int ccc_global_init(struct lu_device_type *device_type)
-{
-   int result;
-
-   result = lu_device_type_init(device_type);
-   if (result)
-   return result;
-
-   ccc_inode_fini_env = cl_env_alloc(&dummy_refcheck,
- LCT_REMEMBER | LCT_NOREF);
-   if (IS_ERR(ccc_inode_fini_env)) {
-   result = PTR_ERR(ccc_inode_fini_env);
-   goto out_device;
-   }
-
-   ccc_inode_fini_env->le_ctx.lc_cookie = 0x4;
-   return 0;
-out_device:
-   lu_device_type_fini(device_type);
-   return result;
-}
-
-void ccc_global_fini(struct lu_device_type *device_type)
-{
-   if (ccc_inode_fini_env) {
-   cl_env_put(ccc_inode_fini_env, &dummy_refcheck);
-   ccc_inode_fini_env = NULL;
-   }
-   lu_device_type_fini(device_type);
-}
+static DEFINE_MUTEX(cl_inode_fini_guard);
 
 int cl_setattr_ost(struct inode *inode, const struct iattr *attr)
 {
@@ -286,10 +255,10 @@ void cl_inode_fini(struct inode *inode)
env = cl_env_get(&refcheck);
emergency = IS_ERR(env);
if (emergency) {
-   mutex_lock(&ccc_inode_fini_guard);
-   LASSERT(ccc_inode_fini_env);
-   cl_env_implant(ccc_inode_fini_env, &refcheck);
-   env = ccc_inode_fini_env;
+   mutex_lock(&cl_inode_fini_guard);
+   LASSERT(cl_inode_fini_env);
+   cl_env_implant(cl_inode_fini_env, &refcheck);
+   env = cl_inode_fini_env;
}
/*
 * cl_object cache is a slave to inode cache (which, in turn
@@ -301,8 +270,8 @@ void cl_inode_fini(struct inode *inode)
cl_object_put_last(env, clob);
lli->lli_clob = NULL;
if (emergency) {
-   cl_env_unplant(ccc_inode_fini_env, &refcheck);
-   mutex_unlock(&ccc_inode_fini_guard);
+   cl_env_unplant(cl_inode_fini_env, &refcheck);
+   mutex_unlock(&cl_inode_fini_guard);
} else {
cl_env_put(env, &refcheck);
}
diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h 
b/drivers/staging/lustre/lustre/llite/llite_internal.h
index a6ee2fe..993cee8 100644
--- a/drivers/staging/lustre/lustre/llite/llite_internal.h
+++ b/drivers/staging/lustre/lustre/llite/llite_internal.h
@@ -984,9 +984,6 @@ void free_rmtperm_hash(struct hlist_head *hash);
 int ll_update_remote_perm(struct inode *inode, struct mdt_remote_perm *perm);
 int lustre_check_remote_perm(struct inode *inode, int mask);
 
-/* llite/llite_cl.c */
-extern struct lu_device_type vvp_device_type;
-
 /**
  * Common IO arguments for various VFS I/O interfaces.
  */
@@ -1371,4 +1368,8 @@ void ll_xattr_fini(void);
 int ll_page_sync_io(const struct lu_env *env, struct cl_io *io,
struct cl_page *page, enum cl_req_type crt);
 
+/* lcommon_cl.c */
+extern struct lu_env *cl_inode_fini_env;
+extern int cl_inode_fini_refcheck;
+
 #endif /* LLITE_INTERNAL_H */
diff --git a/drivers/staging/lustre/lustre/llite/super25.c 
b/drivers/staging/lustre/lustre/l

[PATCH 30/43] staging/lustre/llite: merge ccc_io and vvp_io

2016-03-30 Thread green
From: "John L. Hammond" 

Move the contents of struct vvp_io into struct ccc_io, delete the
former, and rename the latter to struct vvp_io. Rename various ccc_io
related functions to use vvp rather than ccc.

Signed-off-by: John L. Hammond 
Reviewed-on: http://review.whamcloud.com/13351
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971
Reviewed-by: Lai Siyao 
Reviewed-by: Jinshan Xiong 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/cl_object.h  |   2 +-
 drivers/staging/lustre/lustre/llite/file.c |  13 ++-
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   |  60 +++-
 .../staging/lustre/lustre/llite/llite_internal.h   |  72 ---
 drivers/staging/lustre/lustre/llite/llite_mmap.c   |  12 +--
 drivers/staging/lustre/lustre/llite/rw.c   |   4 +-
 drivers/staging/lustre/lustre/llite/rw26.c |  10 +-
 drivers/staging/lustre/lustre/llite/vvp_dev.c  |   2 +-
 drivers/staging/lustre/lustre/llite/vvp_internal.h |  81 +
 drivers/staging/lustre/lustre/llite/vvp_io.c   | 101 ++---
 drivers/staging/lustre/lustre/llite/vvp_page.c |   2 +-
 11 files changed, 144 insertions(+), 215 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h 
b/drivers/staging/lustre/lustre/include/cl_object.h
index d509f94..104dc9f 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -1461,7 +1461,7 @@ enum cl_io_state {
  * This is usually embedded into layer session data, rather than allocated
  * dynamically.
  *
- * \see vvp_io, lov_io, osc_io, ccc_io
+ * \see vvp_io, lov_io, osc_io
  */
 struct cl_io_slice {
struct cl_io  *cis_io;
diff --git a/drivers/staging/lustre/lustre/llite/file.c 
b/drivers/staging/lustre/lustre/llite/file.c
index bf2a5ee..27e7e65 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -1135,14 +1135,13 @@ restart:
ll_io_init(io, file, iot == CIT_WRITE);
 
if (cl_io_rw_init(env, io, iot, *ppos, count) == 0) {
-   struct vvp_io *vio = vvp_env_io(env);
-   struct ccc_io *cio = ccc_env_io(env);
+   struct vvp_io *cio = vvp_env_io(env);
int write_mutex_locked = 0;
 
cio->cui_fd  = LUSTRE_FPRIVATE(file);
-   vio->cui_io_subtype = args->via_io_subtype;
+   cio->cui_io_subtype = args->via_io_subtype;
 
-   switch (vio->cui_io_subtype) {
+   switch (cio->cui_io_subtype) {
case IO_NORMAL:
cio->cui_iter = args->u.normal.via_iter;
cio->cui_iocb = args->u.normal.via_iocb;
@@ -1158,11 +1157,11 @@ restart:
down_read(&lli->lli_trunc_sem);
break;
case IO_SPLICE:
-   vio->u.splice.cui_pipe = args->u.splice.via_pipe;
-   vio->u.splice.cui_flags = args->u.splice.via_flags;
+   cio->u.splice.cui_pipe = args->u.splice.via_pipe;
+   cio->u.splice.cui_flags = args->u.splice.via_flags;
break;
default:
-   CERROR("Unknown IO type - %u\n", vio->cui_io_subtype);
+   CERROR("Unknown IO type - %u\n", cio->cui_io_subtype);
LBUG();
}
result = cl_io_loop(env, io);
diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c 
b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
index 8884317..9a9d706 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
@@ -68,7 +68,6 @@ static const struct cl_req_operations ccc_req_ops;
  */
 
 static struct kmem_cache *ccc_thread_kmem;
-static struct kmem_cache *ccc_session_kmem;
 static struct kmem_cache *ccc_req_kmem;
 
 static struct lu_kmem_descr ccc_caches[] = {
@@ -78,11 +77,6 @@ static struct lu_kmem_descr ccc_caches[] = {
.ckd_size  = sizeof(struct ccc_thread_info),
},
{
-   .ckd_cache = &ccc_session_kmem,
-   .ckd_name  = "ccc_session_kmem",
-   .ckd_size  = sizeof(struct ccc_session)
-   },
-   {
.ckd_cache = &ccc_req_kmem,
.ckd_name  = "ccc_req_kmem",
.ckd_size  = sizeof(struct ccc_req)
@@ -116,37 +110,12 @@ void ccc_key_fini(const struct lu_context *ctx,
kmem_cache_free(ccc_thread_kmem, info);
 }
 
-void *ccc_session_key_init(const struct lu_context *ctx,
-  struct lu_context_key *key)
-{
-   struct ccc_session *session;
-
-   session = kmem_cache_zalloc(ccc_session_kmem, GFP_NOFS);
-   if (!session)
-   session = ERR_PTR(-ENOMEM);
-   return session;
-}
-
-void ccc_session_key_fini(const struct lu_context *ctx,
-

[PATCH 34/43] staging/lustre/llite: Rename struct ccc_grouplock to ll_grouplock

2016-03-30 Thread green
From: John Hammond 

And move the definition from vvp_internal.h to llite_internal.h.

Signed-off-by: John L. Hammond 
Signed-off-by: Jinshan Xiong 
Reviewed-on: http://review.whamcloud.com/13714
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971
Reviewed-by: Bobi Jam 
Reviewed-by: James Simmons 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/llite/file.c | 16 ++---
 drivers/staging/lustre/lustre/llite/lcommon_misc.c | 26 +++---
 .../staging/lustre/lustre/llite/llite_internal.h   | 14 +++-
 drivers/staging/lustre/lustre/llite/vvp_internal.h | 11 -
 drivers/staging/lustre/lustre/llite/vvp_io.c   |  2 +-
 5 files changed, 35 insertions(+), 34 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/file.c 
b/drivers/staging/lustre/lustre/llite/file.c
index 63aa080..210d1e2 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -278,7 +278,7 @@ static int ll_md_close(struct obd_export *md_exp, struct 
inode *inode,
 
/* clear group lock, if present */
if (unlikely(fd->fd_flags & LL_FILE_GROUP_LOCKED))
-   ll_put_grouplock(inode, file, fd->fd_grouplock.cg_gid);
+   ll_put_grouplock(inode, file, fd->fd_grouplock.lg_gid);
 
if (fd->fd_lease_och) {
bool lease_broken;
@@ -1570,7 +1570,7 @@ ll_get_grouplock(struct inode *inode, struct file *file, 
unsigned long arg)
 {
struct ll_inode_info   *lli = ll_i2info(inode);
struct ll_file_data*fd = LUSTRE_FPRIVATE(file);
-   struct ccc_grouplockgrouplock;
+   struct ll_grouplockgrouplock;
int  rc;
 
if (arg == 0) {
@@ -1584,11 +1584,11 @@ ll_get_grouplock(struct inode *inode, struct file 
*file, unsigned long arg)
spin_lock(&lli->lli_lock);
if (fd->fd_flags & LL_FILE_GROUP_LOCKED) {
CWARN("group lock already existed with gid %lu\n",
- fd->fd_grouplock.cg_gid);
+ fd->fd_grouplock.lg_gid);
spin_unlock(&lli->lli_lock);
return -EINVAL;
}
-   LASSERT(!fd->fd_grouplock.cg_lock);
+   LASSERT(!fd->fd_grouplock.lg_lock);
spin_unlock(&lli->lli_lock);
 
rc = cl_get_grouplock(ll_i2info(inode)->lli_clob,
@@ -1617,7 +1617,7 @@ static int ll_put_grouplock(struct inode *inode, struct 
file *file,
 {
struct ll_inode_info   *lli = ll_i2info(inode);
struct ll_file_data*fd = LUSTRE_FPRIVATE(file);
-   struct ccc_grouplockgrouplock;
+   struct ll_grouplockgrouplock;
 
spin_lock(&lli->lli_lock);
if (!(fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
@@ -1625,11 +1625,11 @@ static int ll_put_grouplock(struct inode *inode, struct 
file *file,
CWARN("no group lock held\n");
return -EINVAL;
}
-   LASSERT(fd->fd_grouplock.cg_lock);
+   LASSERT(fd->fd_grouplock.lg_lock);
 
-   if (fd->fd_grouplock.cg_gid != arg) {
+   if (fd->fd_grouplock.lg_gid != arg) {
CWARN("group lock %lu doesn't match current id %lu\n",
- arg, fd->fd_grouplock.cg_gid);
+ arg, fd->fd_grouplock.lg_gid);
spin_unlock(&lli->lli_lock);
return -EINVAL;
}
diff --git a/drivers/staging/lustre/lustre/llite/lcommon_misc.c 
b/drivers/staging/lustre/lustre/llite/lcommon_misc.c
index 68e3db1..5e3e43f 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_misc.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_misc.c
@@ -42,8 +42,8 @@
 #include "../include/obd.h"
 #include "../include/cl_object.h"
 
-#include "vvp_internal.h"
 #include "../include/lustre_lite.h"
+#include "llite_internal.h"
 
 /* Initialize the default and maximum LOV EA and cookie sizes.  This allows
  * us to make MDS RPCs with large enough reply buffers to hold the
@@ -126,7 +126,7 @@ int cl_ocd_update(struct obd_device *host,
 #define GROUPLOCK_SCOPE "grouplock"
 
 int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock,
-struct ccc_grouplock *cg)
+struct ll_grouplock *cg)
 {
struct lu_env *env;
struct cl_io   *io;
@@ -172,25 +172,25 @@ int cl_get_grouplock(struct cl_object *obj, unsigned long 
gid, int nonblock,
return rc;
}
 
-   cg->cg_env  = cl_env_get(&refcheck);
-   cg->cg_io   = io;
-   cg->cg_lock = lock;
-   cg->cg_gid  = gid;
-   LASSERT(cg->cg_env == env);
+   cg->lg_env  = cl_env_get(&refcheck);
+   cg->lg_io   = io;
+   cg->lg_lock = lock;
+   cg->lg_gid  = gid;
+   LASSERT(cg->lg_env == env);
 
cl_env_unplant(env, &refcheck);
return 0;
 }
 
-void cl_put_grouplock(struct ccc_grouplock *cg)
+void cl_put_grouplock(struct ll_grouplock *cg)
 {
-   struct lu_env  *env  = cg->cg_env;
-   struct cl_io   *io   =

[PATCH 42/43] staging/lustre/ldlm: revert changes to ldlm_cancel_aged_policy()

2016-03-30 Thread green
From: Niu Yawei 

The changes to ldlm_cancel_aged_policy() introduced from LU-4300
was incorrect. This patch revert this part of changes.

Signed-off-by: Niu Yawei 
Reviewed-on: http://review.whamcloud.com/12448
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5727
Reviewed-by: Bobi Jam 
Reviewed-by: Jinshan Xiong 
Reviewed-by: Andreas Dilger 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/ldlm/ldlm_request.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c 
b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index 2f12194..48e9828 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -1240,10 +1240,8 @@ static ldlm_policy_res_t ldlm_cancel_aged_policy(struct 
ldlm_namespace *ns,
 int unused, int added,
 int count)
 {
-   if (added >= count)
-   return LDLM_POLICY_KEEP_LOCK;
-
-   if (time_before(cfs_time_current(),
+   if ((added >= count) &&
+   time_before(cfs_time_current(),
cfs_time_add(lock->l_last_used, ns->ns_max_age)))
return LDLM_POLICY_KEEP_LOCK;
 
-- 
2.1.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 32/43] staging/lustre/llite: move vvp_io functions to vvp_io.c

2016-03-30 Thread green
From: "John L. Hammond" 

Move all vvp_io related functions from lustre/llite/lcommon_cl.c to
the sole file where they are used lustre/llite/vvp_io.c.

Signed-off-by: John L. Hammond 
Reviewed-on: http://review.whamcloud.com/13376
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971
Reviewed-by: Jinshan Xiong 
Reviewed-by: Bobi Jam 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   | 197 
 .../staging/lustre/lustre/llite/llite_internal.h   |   1 -
 drivers/staging/lustre/lustre/llite/vvp_internal.h |  22 +--
 drivers/staging/lustre/lustre/llite/vvp_io.c   | 198 -
 4 files changed, 196 insertions(+), 222 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c 
b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
index 630c371..1b11103 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
@@ -184,192 +184,6 @@ void ccc_global_fini(struct lu_device_type *device_type)
lu_kmem_fini(ccc_caches);
 }
 
-static void vvp_object_size_lock(struct cl_object *obj)
-{
-   struct inode *inode = vvp_object_inode(obj);
-
-   ll_inode_size_lock(inode);
-   cl_object_attr_lock(obj);
-}
-
-static void vvp_object_size_unlock(struct cl_object *obj)
-{
-   struct inode *inode = vvp_object_inode(obj);
-
-   cl_object_attr_unlock(obj);
-   ll_inode_size_unlock(inode);
-}
-
-/*
- *
- * io operations.
- *
- */
-
-int vvp_io_one_lock_index(const struct lu_env *env, struct cl_io *io,
- __u32 enqflags, enum cl_lock_mode mode,
- pgoff_t start, pgoff_t end)
-{
-   struct vvp_io  *vio   = vvp_env_io(env);
-   struct cl_lock_descr   *descr = &vio->vui_link.cill_descr;
-   struct cl_object   *obj   = io->ci_obj;
-
-   CLOBINVRNT(env, obj, vvp_object_invariant(obj));
-
-   CDEBUG(D_VFSTRACE, "lock: %d [%lu, %lu]\n", mode, start, end);
-
-   memset(&vio->vui_link, 0, sizeof(vio->vui_link));
-
-   if (vio->vui_fd && (vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
-   descr->cld_mode = CLM_GROUP;
-   descr->cld_gid  = vio->vui_fd->fd_grouplock.cg_gid;
-   } else {
-   descr->cld_mode  = mode;
-   }
-   descr->cld_obj   = obj;
-   descr->cld_start = start;
-   descr->cld_end   = end;
-   descr->cld_enq_flags = enqflags;
-
-   cl_io_lock_add(env, io, &vio->vui_link);
-   return 0;
-}
-
-void vvp_io_update_iov(const struct lu_env *env,
-  struct vvp_io *vio, struct cl_io *io)
-{
-   size_t size = io->u.ci_rw.crw_count;
-
-   if (!cl_is_normalio(env, io) || !vio->vui_iter)
-   return;
-
-   iov_iter_truncate(vio->vui_iter, size);
-}
-
-int vvp_io_one_lock(const struct lu_env *env, struct cl_io *io,
-   __u32 enqflags, enum cl_lock_mode mode,
-   loff_t start, loff_t end)
-{
-   struct cl_object *obj = io->ci_obj;
-
-   return vvp_io_one_lock_index(env, io, enqflags, mode,
-cl_index(obj, start), cl_index(obj, end));
-}
-
-void vvp_io_end(const struct lu_env *env, const struct cl_io_slice *ios)
-{
-   CLOBINVRNT(env, ios->cis_io->ci_obj,
-  vvp_object_invariant(ios->cis_io->ci_obj));
-}
-
-void vvp_io_advance(const struct lu_env *env,
-   const struct cl_io_slice *ios,
-   size_t nob)
-{
-   struct vvp_io*vio = cl2vvp_io(env, ios);
-   struct cl_io *io  = ios->cis_io;
-   struct cl_object *obj = ios->cis_io->ci_obj;
-
-   CLOBINVRNT(env, obj, vvp_object_invariant(obj));
-
-   if (!cl_is_normalio(env, io))
-   return;
-
-   iov_iter_reexpand(vio->vui_iter, vio->vui_tot_count  -= nob);
-}
-
-/**
- * Helper function that if necessary adjusts file size (inode->i_size), when
- * position at the offset \a pos is accessed. File size can be arbitrary stale
- * on a Lustre client, but client at least knows KMS. If accessed area is
- * inside [0, KMS], set file size to KMS, otherwise glimpse file size.
- *
- * Locking: cl_isize_lock is used to serialize changes to inode size and to
- * protect consistency between inode size and cl_object
- * attributes. cl_object_size_lock() protects consistency between cl_attr's of
- * top-object and sub-objects.
- */
-int ccc_prep_size(const struct lu_env *env, struct cl_object *obj,
- struct cl_io *io, loff_t start, size_t count, int *exceed)
-{
-   struct cl_attr *attr  = ccc_env_thread_attr(env);
-   struct inode   *inode = vvp_object_inode(obj);
-   loff_tpos   = start + count - 1;
-   loff_t kms;
-   int result;
-
-   /*
-* Consistency guarantees: following possibilities exist for the
-* relation between region being accessed and

[PATCH 39/43] staging/lustre/llite: Move several declarations to llite_internal.h

2016-03-30 Thread green
From: John Hammond 

Move several declarations between llite_internal.h and vvp_internal.h
with the goal of reserving the latter header for functions that
pertain to vvp_{device,object,page,...}.

Signed-off-by: John L. Hammond 
Signed-off-by: Jinshan Xiong 
Reviewed-on: http://review.whamcloud.com/13714
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971
Reviewed-by: Bobi Jam 
Reviewed-by: James Simmons 
Signed-off-by: Oleg Drokin 
---
 .../staging/lustre/lustre/llite/llite_internal.h   | 32 +--
 drivers/staging/lustre/lustre/llite/vvp_internal.h | 36 ++
 2 files changed, 32 insertions(+), 36 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h 
b/drivers/staging/lustre/lustre/llite/llite_internal.h
index 993cee8..ba24f09 100644
--- a/drivers/staging/lustre/lustre/llite/llite_internal.h
+++ b/drivers/staging/lustre/lustre/llite/llite_internal.h
@@ -663,6 +663,10 @@ static inline int ll_need_32bit_api(struct ll_sb_info *sbi)
 void ll_ras_enter(struct file *f);
 
 /* llite/lcommon_misc.c */
+int cl_init_ea_size(struct obd_export *md_exp, struct obd_export *dt_exp);
+int cl_ocd_update(struct obd_device *host,
+ struct obd_device *watched,
+ enum obd_notify_event ev, void *owner, void *data);
 int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock,
 struct ll_grouplock *cg);
 void cl_put_grouplock(struct ll_grouplock *cg);
@@ -881,9 +885,6 @@ static inline struct vvp_io_args *ll_env_args(const struct 
lu_env *env,
return via;
 }
 
-int vvp_global_init(void);
-void vvp_global_fini(void);
-
 void ll_queue_done_writing(struct inode *inode, unsigned long flags);
 void ll_close_thread_shutdown(struct ll_close_queue *lcq);
 int ll_close_thread_start(struct ll_close_queue **lcq_ret);
@@ -1089,6 +1090,22 @@ int do_statahead_enter(struct inode *dir, struct dentry 
**dentry,
   int only_unplug);
 void ll_stop_statahead(struct inode *dir, void *key);
 
+blkcnt_t dirty_cnt(struct inode *inode);
+
+int cl_glimpse_size0(struct inode *inode, int agl);
+int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io,
+   struct inode *inode, struct cl_object *clob, int agl);
+
+static inline int cl_glimpse_size(struct inode *inode)
+{
+   return cl_glimpse_size0(inode, 0);
+}
+
+static inline int cl_agl(struct inode *inode)
+{
+   return cl_glimpse_size0(inode, 1);
+}
+
 static inline int ll_glimpse_size(struct inode *inode)
 {
struct ll_inode_info *lli = ll_i2info(inode);
@@ -1369,7 +1386,16 @@ int ll_page_sync_io(const struct lu_env *env, struct 
cl_io *io,
struct cl_page *page, enum cl_req_type crt);
 
 /* lcommon_cl.c */
+int cl_setattr_ost(struct inode *inode, const struct iattr *attr);
+
 extern struct lu_env *cl_inode_fini_env;
 extern int cl_inode_fini_refcheck;
 
+int cl_file_inode_init(struct inode *inode, struct lustre_md *md);
+void cl_inode_fini(struct inode *inode);
+int cl_local_size(struct inode *inode);
+
+__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32);
+__u32 cl_fid_build_gen(const struct lu_fid *fid);
+
 #endif /* LLITE_INTERNAL_H */
diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h 
b/drivers/staging/lustre/lustre/llite/vvp_internal.h
index 06e2726..ce4aeca 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_internal.h
+++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h
@@ -53,25 +53,6 @@ struct obd_device;
 struct obd_export;
 struct page;
 
-blkcnt_t dirty_cnt(struct inode *inode);
-
-int cl_glimpse_size0(struct inode *inode, int agl);
-int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io,
-   struct inode *inode, struct cl_object *clob, int agl);
-
-static inline int cl_glimpse_size(struct inode *inode)
-{
-   return cl_glimpse_size0(inode, 0);
-}
-
-static inline int cl_agl(struct inode *inode)
-{
-   return cl_glimpse_size0(inode, 1);
-}
-
-/**
- * Locking policy for setattr.
- */
 enum ccc_setattr_lock_type {
/** Locking is done by server */
SETATTR_NOLOCK,
@@ -370,23 +351,9 @@ static inline struct vvp_lock *cl2vvp_lock(const struct 
cl_lock_slice *slice)
return container_of(slice, struct vvp_lock, vlk_cl);
 }
 
-int cl_setattr_ost(struct inode *inode, const struct iattr *attr);
-
-int cl_file_inode_init(struct inode *inode, struct lustre_md *md);
-void cl_inode_fini(struct inode *inode);
-int cl_local_size(struct inode *inode);
-
-__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32);
-__u32 cl_fid_build_gen(const struct lu_fid *fid);
-
 # define CLOBINVRNT(env, clob, expr)   \
((void)sizeof(env), (void)sizeof(clob), (void)sizeof(!!(expr)))
 
-int cl_init_ea_size(struct obd_export *md_exp, struct obd_export *dt_exp);
-int cl_ocd_update(struct obd_device *host,
- struct obd_device *watched,
- enum obd_notify_event ev,

[PATCH 33/43] staging/lustre/llite: rename ccc_req to vvp_req

2016-03-30 Thread green
From: "John L. Hammond" 

Rename struct ccc_req to struct vvp_req and move related functions
from lustre/llite/lcommon_cl.c to the new file lustre/llite/vvp_req.c.

Signed-off-by: John L. Hammond 
Reviewed-on: http://review.whamcloud.com/13377
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971
Reviewed-by: Jinshan Xiong 
Reviewed-by: Bobi Jam 
Signed-off-by: Oleg Drokin 
---
 drivers/staging/lustre/lustre/include/cl_object.h  |   2 +-
 drivers/staging/lustre/lustre/llite/Makefile   |   3 +-
 drivers/staging/lustre/lustre/llite/lcommon_cl.c   | 104 --
 drivers/staging/lustre/lustre/llite/vvp_dev.c  |   8 +-
 drivers/staging/lustre/lustre/llite/vvp_internal.h |  18 +--
 drivers/staging/lustre/lustre/llite/vvp_req.c  | 121 +
 6 files changed, 136 insertions(+), 120 deletions(-)
 create mode 100644 drivers/staging/lustre/lustre/llite/vvp_req.c

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h 
b/drivers/staging/lustre/lustre/include/cl_object.h
index 104dc9f..918be65 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -140,7 +140,7 @@ struct cl_device_operations {
 * cl_req_slice_add().
 *
 * \see osc_req_init(), lov_req_init(), lovsub_req_init()
-* \see ccc_req_init()
+* \see vvp_req_init()
 */
int (*cdo_req_init)(const struct lu_env *env, struct cl_device *dev,
struct cl_req *req);
diff --git a/drivers/staging/lustre/lustre/llite/Makefile 
b/drivers/staging/lustre/lustre/llite/Makefile
index 24085e2..2ce10ff 100644
--- a/drivers/staging/lustre/lustre/llite/Makefile
+++ b/drivers/staging/lustre/lustre/llite/Makefile
@@ -5,6 +5,7 @@ lustre-y := dcache.o dir.o file.o llite_close.o llite_lib.o 
llite_nfs.o \
xattr.o xattr_cache.o remote_perm.o llite_rmtacl.o \
rw26.o super25.o statahead.o \
glimpse.o lcommon_cl.o lcommon_misc.o \
-   vvp_dev.o vvp_page.o vvp_lock.o vvp_io.o vvp_object.o lproc_llite.o
+   vvp_dev.o vvp_page.o vvp_lock.o vvp_io.o vvp_object.o vvp_req.o \
+   lproc_llite.o
 
 llite_lloop-y := lloop.o
diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c 
b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
index 1b11103..d28546a 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
@@ -61,14 +61,11 @@
 
 #include "../llite/llite_internal.h"
 
-static const struct cl_req_operations ccc_req_ops;
-
 /*
  * ccc_ prefix stands for "Common Client Code".
  */
 
 static struct kmem_cache *ccc_thread_kmem;
-static struct kmem_cache *ccc_req_kmem;
 
 static struct lu_kmem_descr ccc_caches[] = {
{
@@ -77,11 +74,6 @@ static struct lu_kmem_descr ccc_caches[] = {
.ckd_size  = sizeof(struct ccc_thread_info),
},
{
-   .ckd_cache = &ccc_req_kmem,
-   .ckd_name  = "ccc_req_kmem",
-   .ckd_size  = sizeof(struct ccc_req)
-   },
-   {
.ckd_cache = NULL
}
 };
@@ -116,22 +108,6 @@ struct lu_context_key ccc_key = {
.lct_fini = ccc_key_fini
 };
 
-int ccc_req_init(const struct lu_env *env, struct cl_device *dev,
-struct cl_req *req)
-{
-   struct ccc_req *vrq;
-   int result;
-
-   vrq = kmem_cache_zalloc(ccc_req_kmem, GFP_NOFS);
-   if (vrq) {
-   cl_req_slice_add(req, &vrq->crq_cl, dev, &ccc_req_ops);
-   result = 0;
-   } else {
-   result = -ENOMEM;
-   }
-   return result;
-}
-
 /**
  * An `emergency' environment used by ccc_inode_fini() when cl_env_get()
  * fails. Access to this environment is serialized by ccc_inode_fini_guard
@@ -184,75 +160,6 @@ void ccc_global_fini(struct lu_device_type *device_type)
lu_kmem_fini(ccc_caches);
 }
 
-/*
- *
- * Transfer operations.
- *
- */
-
-void ccc_req_completion(const struct lu_env *env,
-   const struct cl_req_slice *slice, int ioret)
-{
-   struct ccc_req *vrq;
-
-   if (ioret > 0)
-   cl_stats_tally(slice->crs_dev, slice->crs_req->crq_type, ioret);
-
-   vrq = cl2ccc_req(slice);
-   kmem_cache_free(ccc_req_kmem, vrq);
-}
-
-/**
- * Implementation of struct cl_req_operations::cro_attr_set() for ccc
- * layer. ccc is responsible for
- *
- *- o_[mac]time
- *
- *- o_mode
- *
- *- o_parent_seq
- *
- *- o_[ug]id
- *
- *- o_parent_oid
- *
- *- o_parent_ver
- *
- *- o_ioepoch,
- *
- */
-void ccc_req_attr_set(const struct lu_env *env,
- const struct cl_req_slice *slice,
- const struct cl_object *obj,
- struct cl_req_attr *attr, u64 flags)
-{
-   struct inode *inode;
-   struct obdo  *oa;
-   u32   valid_flags;

  1   2   >