Re: [patch] ufs: silence uninitialized warnings

2016-03-22 Thread Evgeniy Dushistov
On Tue, Mar 22, 2016 at 02:40:02PM +0300, Dan Carpenter wrote:
> Static checkers complain that we can use "tmp" without initializing it.
> 
> Signed-off-by: Dan Carpenter 
> 
> diff --git a/fs/ufs/util.h b/fs/ufs/util.h
> index 9541759..8aa8812 100644
> --- a/fs/ufs/util.h
> +++ b/fs/ufs/util.h
> @@ -88,7 +88,7 @@ ufs_get_fs_npsect(struct super_block *sb, struct 
> ufs_super_block_first *usb1,
>  static inline u64
>  ufs_get_fs_qbmask(struct super_block *sb, struct ufs_super_block_third *usb3)
>  {
> - __fs64 tmp;
> + __fs64 tmp = 0;
>  
>   switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
>   case UFS_ST_SUNOS:
> @@ -112,7 +112,7 @@ ufs_get_fs_qbmask(struct super_block *sb, struct 
> ufs_super_block_third *usb3)
>  static inline u64
>  ufs_get_fs_qfmask(struct super_block *sb, struct ufs_super_block_third *usb3)
>  {
> - __fs64 tmp;
> + __fs64 tmp = 0;
>  
>   switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
>   case UFS_ST_SUNOS:

In fact result of this function is saved, but not used.
May be better from cleanup point of view will be remove these two
functions and structure fields where their result was saved.

-- 
/Evgeniy


[PATCH] ads7846: do not ignore pendown-gpio flags

2015-05-20 Thread Evgeniy Dushistov
At current state ads7846 driver ignore GPIO_ACTIVE_LOW,
GPIO_ACTIVE_HIGH flags in such dts expression:
pendown-gpio = <&gpio5 5 GPIO_ACTIVE_HIGH>;

In times of usage arch/arm/.. you can handle this
by get_pendown_state callback passed via platform_data,
but at now with Device Tree it is impossible to handle
1 as interrupt trigger, this patch fixes this.

Test on beagleboard-xm<-SPI->ads7845

It made on top of "ads7846: fix ads7846 driver for work with ads7845",
but can applied with "hunks" on top of Linus's master,
and it independent of "ads7846: fix ads7846 driver for work with
ads7845".

Signed-off-by: Evgeniy A. Dushistov 
---
 drivers/input/touchscreen/ads7846.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/input/touchscreen/ads7846.c 
b/drivers/input/touchscreen/ads7846.c
index 76728d4..0a02364 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -140,6 +140,7 @@ struct ads7846 {
void(*filter_cleanup)(void *data);
int (*get_pendown_state)(void);
int gpio_pendown;
+   boolactive_low;
 
void(*wait_for_sync)(void);
 };
@@ -574,7 +575,7 @@ static int get_pendown_state(struct ads7846 *ts)
if (ts->get_pendown_state)
return ts->get_pendown_state();
 
-   return !gpio_get_value(ts->gpio_pendown);
+   return ts->active_low != (!!gpio_get_value(ts->gpio_pendown));
 }
 
 static void null_wait_for_sync(void)
@@ -1108,11 +1109,13 @@ static const struct of_device_id ads7846_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, ads7846_dt_ids);
 
-static const struct ads7846_platform_data *ads7846_probe_dt(struct device *dev)
+static const struct ads7846_platform_data *
+ads7846_probe_dt(struct device *dev, bool *pen_active_low)
 {
struct ads7846_platform_data *pdata;
struct device_node *node = dev->of_node;
const struct of_device_id *match;
+   enum of_gpio_flags gpio_flags;
 
if (!node) {
dev_err(dev, "Device does not have associated DT data\n");
@@ -1163,12 +1166,16 @@ static const struct ads7846_platform_data 
*ads7846_probe_dt(struct device *dev)
 
pdata->wakeup = of_property_read_bool(node, "linux,wakeup");
 
-   pdata->gpio_pendown = of_get_named_gpio(dev->of_node, "pendown-gpio", 
0);
+   pdata->gpio_pendown = of_get_named_gpio_flags(dev->of_node,
+ "pendown-gpio",
+ 0, &gpio_flags);
+   *pen_active_low = !!(gpio_flags & OF_GPIO_ACTIVE_LOW);
 
return pdata;
 }
 #else
-static const struct ads7846_platform_data *ads7846_probe_dt(struct device *dev)
+static const struct ads7846_platform_data *ads7846_probe_dt(
+   struct device *dev, bool *pen_active_low)
 {
dev_err(dev, "no platform data defined\n");
return ERR_PTR(-EINVAL);
@@ -1183,6 +1190,7 @@ static int ads7846_probe(struct spi_device *spi)
struct input_dev *input_dev;
unsigned long irq_flags;
int err;
+   bool pen_active_low = true;
 
if (!spi->irq) {
dev_dbg(&spi->dev, "no IRQ?\n");
@@ -1226,7 +1234,7 @@ static int ads7846_probe(struct spi_device *spi)
 
pdata = dev_get_platdata(&spi->dev);
if (!pdata) {
-   pdata = ads7846_probe_dt(&spi->dev);
+   pdata = ads7846_probe_dt(&spi->dev, &pen_active_low);
if (IS_ERR(pdata)) {
err = PTR_ERR(pdata);
goto err_free_mem;
@@ -1240,6 +1248,7 @@ static int ads7846_probe(struct spi_device *spi)
 
ts->vref_mv = pdata->vref_mv;
ts->swap_xy = pdata->swap_xy;
+   ts->active_low = pen_active_low;
 
if (pdata->filter != NULL) {
if (pdata->filter_init != NULL) {
-- 
2.3.6

-- 
/Evgeniy
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH][v2] ads7846: fix ads7846 driver for work with ads7845

2015-05-19 Thread Evgeniy Dushistov
Current ads7846 driver do not work with ads7845 device,
it gives completly wrong coordinates. With this fix,
it works as expected. As explained by Anatolij Gustschin,
the main changes in ads7846 driver for support ads7845 device,
was introduced due:

>this was tested, but if I remember correctly, on some ppc board were
>multi-segment SPI transfers didn't work (SPI chip-select disabled by
>controller after first SPI command byte). I do not know any more if it
>was the only reason for this ads7845 specific handling in my commit
>and unfortunately I do not have this board to check it again.

This patch was tested on beagleboard-xm<-SPI->ads7845

Signed-off-by: Evgneiy A. Dushistov 
---
 drivers/input/touchscreen/ads7846.c | 148 +---
 1 file changed, 36 insertions(+), 112 deletions(-)

diff --git a/drivers/input/touchscreen/ads7846.c 
b/drivers/input/touchscreen/ads7846.c
index e4eb8a6..76728d4 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -88,8 +88,6 @@ struct ads7846_packet {
u8  read_x, read_y, read_z1, read_z2, pwrdown;
u16 dummy;  /* for the pwrdown read */
struct ts_event tc;
-   /* for ads7845 with mpc5121 psc spi we use 3-byte buffers */
-   u8  read_x_cmd[3], read_y_cmd[3], pwrdown_cmd[3];
 };
 
 struct ads7846 {
@@ -383,42 +381,6 @@ static int ads7846_read12_ser(struct device *dev, unsigned 
command)
return status;
 }
 
-static int ads7845_read12_ser(struct device *dev, unsigned command)
-{
-   struct spi_device *spi = to_spi_device(dev);
-   struct ads7846 *ts = dev_get_drvdata(dev);
-   struct ads7845_ser_req *req;
-   int status;
-
-   req = kzalloc(sizeof *req, GFP_KERNEL);
-   if (!req)
-   return -ENOMEM;
-
-   spi_message_init(&req->msg);
-
-   req->command[0] = (u8) command;
-   req->xfer[0].tx_buf = req->command;
-   req->xfer[0].rx_buf = req->sample;
-   req->xfer[0].len = 3;
-   spi_message_add_tail(&req->xfer[0], &req->msg);
-
-   mutex_lock(&ts->lock);
-   ads7846_stop(ts);
-   status = spi_sync(spi, &req->msg);
-   ads7846_restart(ts);
-   mutex_unlock(&ts->lock);
-
-   if (status == 0) {
-   /* BE12 value, then padding */
-   status = be16_to_cpu(*((u16 *)&req->sample[1]));
-   status = status >> 3;
-   status &= 0x0fff;
-   }
-
-   kfree(req);
-   return status;
-}
-
 #if IS_ENABLED(CONFIG_HWMON)
 
 #define SHOW(name, var, adjust) static ssize_t \
@@ -671,15 +633,12 @@ static int ads7846_get_value(struct ads7846 *ts, struct 
spi_message *m)
struct spi_transfer *t =
list_entry(m->transfers.prev, struct spi_transfer, 
transfer_list);
 
-   if (ts->model == 7845) {
-   return be16_to_cpup((__be16 *)&(((char*)t->rx_buf)[1])) >> 3;
-   } else {
-   /*
-* adjust:  on-wire is a must-ignore bit, a BE12 value, then
-* padding; built from two 8 bit values written msb-first.
-*/
-   return be16_to_cpup((__be16 *)t->rx_buf) >> 3;
-   }
+
+   /*
+* adjust:  on-wire is a must-ignore bit, a BE12 value, then
+* padding; built from two 8 bit values written msb-first.
+*/
+   return (be16_to_cpup((__be16 *)t->rx_buf) >> 3) & 0xfff;
 }
 
 static void ads7846_update_value(struct spi_message *m, int val)
@@ -755,14 +714,12 @@ static void ads7846_report_state(struct ads7846 *ts)
 * from on-the-wire format as part of debouncing to get stable
 * readings.
 */
+   x = packet->tc.x;
+   y = packet->tc.y;
if (ts->model == 7845) {
-   x = *(u16 *)packet->tc.x_buf;
-   y = *(u16 *)packet->tc.y_buf;
z1 = 0;
z2 = 0;
} else {
-   x = packet->tc.x;
-   y = packet->tc.y;
z1 = packet->tc.z1;
z2 = packet->tc.z2;
}
@@ -993,26 +950,16 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
spi_message_init(m);
m->context = ts;
 
-   if (ts->model == 7845) {
-   packet->read_y_cmd[0] = READ_Y(vref);
-   packet->read_y_cmd[1] = 0;
-   packet->read_y_cmd[2] = 0;
-   x->tx_buf = &packet->read_y_cmd[0];
-   x->rx_buf = &packet->tc.y_buf[0];
-   x->len = 3;
-   spi_message_add_tail(x, m);
-   } else {
-   /* y- still on; turn on only y+ (and ADC) */
-   packet->read_y = READ_Y(vref);
-   x->tx_buf = &packet->read_y;
-   x->len = 1;
-   spi_message_add_tail(x, m);
+   /* y- still on; turn on only y+ (and ADC) */
+   packet->read_y = READ_Y(vref);
+   x->tx_buf = &packet->read_y;
+   x->len = 1;
+

[PATCH] [RFC] ads7846: force driver to work with ads7845

2015-05-18 Thread Evgeniy Dushistov
CC me please, I'm not subscribed to any linux-kernel list.

Hi,
recently I have ads7845 device connected to my beagleboard,
and I try to use ads7846 to work with it.
But it fails, it show completely wrong x/y.

But, after I disabled almost all code that related to ads7845 ("== 7845"),
except determination of amount of pressure force,
all start works as expected,
I found such commit:

>commit 3eac5c7e44f35eb07f0ecb28ce60f15b2dda1932
>Author: Anatolij Gustschin 
>...
>ADS7845 is a controller for 5-wire touch screens and somewhat
>different from 7846. It requires three serial communications to
>accomplish one complete conversion.
>...

But according to datasheets:
http://www.ti.com/lit/ds/symlink/ads7846.pdf
http://www.ti.com/lit/ds/symlink/ads7845.pdf

ads7845(page 8) and ads7846 (page 12) have
identical digital interfaces, I attach quotes
from them in text from to this email.

So why spi negotiation for ads7845 require special code,
except
>Z1-/Z2- position measurement

Was this commit tested? May be you test
in some special mode, like 15 vs 16 bits?

Here is working for me patch (it against 3.16,
but applied to Linus's git master also).

ads7846: fix to force ads7846 driver works with ads7845
 device

Signed-off-by: Evgneiy A. Dushistov 
---
 drivers/input/touchscreen/ads7846.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/input/touchscreen/ads7846.c 
b/drivers/input/touchscreen/ads7846.c
index da201b8..27f4796 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -17,6 +17,9 @@
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
  */
+#define VERBOSE_DEBUG
+#define DEBUG
+
 #include 
 #include 
 #include 
@@ -671,14 +674,14 @@ static int ads7846_get_value(struct ads7846 *ts, struct 
spi_message *m)
struct spi_transfer *t =
list_entry(m->transfers.prev, struct spi_transfer, 
transfer_list);
 
-   if (ts->model == 7845) {
+   if (0/*ts->model == 7845*/) {
return be16_to_cpup((__be16 *)&(((char*)t->rx_buf)[1])) >> 3;
} else {
/*
 * adjust:  on-wire is a must-ignore bit, a BE12 value, then
 * padding; built from two 8 bit values written msb-first.
 */
-   return be16_to_cpup((__be16 *)t->rx_buf) >> 3;
+   return (be16_to_cpup((__be16 *)t->rx_buf) & 0x7fff) >> 3;
}
 }
 
@@ -755,14 +758,12 @@ static void ads7846_report_state(struct ads7846 *ts)
 * from on-the-wire format as part of debouncing to get stable
 * readings.
 */
+   x = packet->tc.x;
+   y = packet->tc.y;
if (ts->model == 7845) {
-   x = *(u16 *)packet->tc.x_buf;
-   y = *(u16 *)packet->tc.y_buf;
z1 = 0;
z2 = 0;
} else {
-   x = packet->tc.x;
-   y = packet->tc.y;
z1 = packet->tc.z1;
z2 = packet->tc.z2;
}
@@ -995,7 +996,7 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
spi_message_init(m);
m->context = ts;
 
-   if (ts->model == 7845) {
+   if (0/*ts->model == 7845*/) {
packet->read_y_cmd[0] = READ_Y(vref);
packet->read_y_cmd[1] = 0;
packet->read_y_cmd[2] = 0;
@@ -1040,7 +1041,7 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
spi_message_init(m);
m->context = ts;
 
-   if (ts->model == 7845) {
+   if (0/*ts->model == 7845*/) {
x++;
packet->read_x_cmd[0] = READ_X(vref);
packet->read_x_cmd[1] = 0;
@@ -1149,7 +1150,7 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
spi_message_init(m);
m->context = ts;
 
-   if (ts->model == 7845) {
+   if (0/*ts->model == 7845*/) {
x++;
packet->pwrdown_cmd[0] = PWRDOWN;
packet->pwrdown_cmd[1] = 0;
@@ -1408,7 +1409,7 @@ static int ads7846_probe(struct spi_device *spi)
 * Take a first sample, leaving nPENIRQ active and vREF off; avoid
 * the touchscreen, in case it's not connected.
 */
-   if (ts->model == 7845)
+   if (0/*ts->model == 7845*/)
ads7845_read12_ser(&spi->dev, PWRDOWN);
else
(void) ads7846_read12_ser(&spi->dev, READ_12BIT_SER(vaux));
-- 
2.3.6

-- 
/Evgeniy
ads7845(page 8):

Figure 5 shows the typical operation of the ADS7845’s digital
interface. This diagram assumes that the source of the digital signals
is a microcontroller or digital signal processor with a basic serial
interface. Each communication between the processor and the converter
consists of 8 clock cycles. 

One complete conversion can be accomplished
with three serial communications, for a total of 24 clock cycles on the
DCLK input.  

The first 8 clock cycles are 

Re: [PATCH 3/3] max7359_keypad: implement DT bindings

2015-05-17 Thread Evgeniy Dushistov
On Fri, May 15, 2015 at 11:00:02PM +0200, Dmitry Torokhov wrote:
> On Thu, May 14, 2015 at 05:38:03AM +0300, Evgeniy Dushistov wrote:
> > +   maxim,debounce_reg = /bits/ 8 <0x5F>;
> > +   maxim,ports_reg = /bits/ 8 <0xFF>;
> 
> Specifying exact size for properties is quite uncommon; I think the
> usual recommendation is is to use the "standard" u32 and validate the
> range in parser function.
> 

Using of u8 has advantages, it is possible on compilation stage
(dts->dtb) check that you enter right value, but
because of DT validation tools are not part of mainline,
I replace u8 with u32 as you suggest, see patch bellow.

> > +   MATRIX_KEY(0, 7, KEY_RESERVED)
> > +   ...
> 
> 
> Indent one more level? Also, maybe fill with something other than
> KEY_RESERVED?
> 

Fixed, see patch bellow.

> 
> 
 
> > dev_dbg(&client->dev, "keys FIFO is 0x%02x\n", ret);
> > +   if (!keymap_data) {
> > +   error = max7359_parse_dt(&client->dev, &init_state);
> > +   if (error) {
> > +   dev_err(&client->dev, "platform data null, and no DT 
> > data\n");
> > +   return error;
> 
> Both debounce and ports values are optional and we'll fail building
> keymap if there are no platform data nor device tree data, so I would
> drop this check and the stub for max7359_parse_dt() as well - we have
> stubs for property parsing anyway.
> 

Because of u32/u8 check at now max7359_parse_dt can return not 0.

> -- 
> Dmitry
> 

Thanks, for review. 

Please add me to CC, because of I'm not the part
of any mailing list (too huge traffic for me).
Here patch with fixes mentioned above:


max7359_keypad: implement DT bindings

Signed-off-by: Evgeniy A. Dushistov 
---
 .../devicetree/bindings/input/max7359-keypad.txt   | 33 ++
 drivers/input/keyboard/max7359_keypad.c| 70 +-
 2 files changed, 100 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/max7359-keypad.txt

diff --git a/Documentation/devicetree/bindings/input/max7359-keypad.txt 
b/Documentation/devicetree/bindings/input/max7359-keypad.txt
new file mode 100644
index 000..5bd4a4f
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/max7359-keypad.txt
@@ -0,0 +1,33 @@
+* MAX7359 keypda device tree bindings
+
+Required Properties:
+- compatible:  Should be "maxim,max7359"
+- linux,keymap:The definition can be found at
+   bindings/input/matrix-keymap.txt
+
+Optional Properties:
+- maxim,debounce_reg: u32, in short allow control debounce,
+see max7359 datasheet for details
+- maxim,ports_reg: u32, in short allow control what pin used,
+and what pins should be configured as GPIO
+
+Example:
+max7359_keypad@38 {
+   compatible = "maxim,max7359";
+   reg = <0x38>;
+   interrupts = <28 IRQ_TYPE_LEVEL_LOW>;/*gpio_156*/
+   interrupt-parent = <&gpio5>;
+   maxim,debounce_reg = <0x5F>;
+   maxim,ports_reg = <0xFF>;
+   linux,keymap = <
+   MATRIX_KEY(0, 0, KEY_F1)
+   MATRIX_KEY(0, 1, KEY_RESERVED)
+   MATRIX_KEY(0, 2, KEY_F2)
+   MATRIX_KEY(0, 3, KEY_RESERVED)
+   MATRIX_KEY(0, 4, KEY_M)
+   MATRIX_KEY(0, 5, KEY_L)
+   MATRIX_KEY(0, 6, KEY_P)
+   MATRIX_KEY(0, 7, KEY_ESC)
+   ...
+   >;
+};
diff --git a/drivers/input/keyboard/max7359_keypad.c 
b/drivers/input/keyboard/max7359_keypad.c
index 5091133..60b4d29 100644
--- a/drivers/input/keyboard/max7359_keypad.c
+++ b/drivers/input/keyboard/max7359_keypad.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define MAX7359_MAX_KEY_ROWS   8
 #define MAX7359_MAX_KEY_COLS   8
@@ -64,6 +65,11 @@ struct max7359_keypad {
struct i2c_client *client;
 };
 
+struct max7359_initial_state {
+   u8 debounce_val;
+   u8 ports_val;
+};
+
 static int max7359_write_reg(struct i2c_client *client, u8 reg, u8 val)
 {
int ret = i2c_smbus_write_byte_data(client, reg, val);
@@ -143,24 +149,64 @@ static void max7359_close(struct input_dev *dev)
max7359_fall_deepsleep(keypad->client);
 }
 
-static void max7359_initialize(struct i2c_client *client)
+static void max7359_initialize(struct i2c_client *client,
+  const struct max7359_initial_state *init_state)
 {
max7359_write_reg(client, MAX7359_REG_CONFIG,
MAX7359_CFG_KEY_RELEASE | /* Key release enable */
MAX7359_CFG_WAKEUP); /* Key press wakeup enable */
 
/* Full key-scan functionality */
-   max7359_write_reg(client, MAX7359_REG_DEBOUNCE, 0x1F);
+   max7359_write_reg(client, MAX7359_REG_DEBOUNCE,
+ init_state->debou

[PATCH 3/3] max7359_keypad: implement DT bindings

2015-05-13 Thread Evgeniy Dushistov
max7359_keypad: implement DT bindings

Signed-off-by: Evgeniy A. Dushistov 
---
 .../devicetree/bindings/input/max7359-keypad.txt   | 33 
 drivers/input/keyboard/max7359_keypad.c| 60 --
 2 files changed, 90 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/max7359-keypad.txt

diff --git a/Documentation/devicetree/bindings/input/max7359-keypad.txt 
b/Documentation/devicetree/bindings/input/max7359-keypad.txt
new file mode 100644
index 000..0a3c381
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/max7359-keypad.txt
@@ -0,0 +1,33 @@
+* MAX7359 keypda device tree bindings
+
+Required Properties:
+- compatible:  Should be "maxim,max7359"
+- linux,keymap:The definition can be found at
+   bindings/input/matrix-keymap.txt
+
+Optional Properties:
+- maxim,debounce_reg: u8, in short allow control debounce,
+see max7359 datasheet for details
+- maxim,ports_reg: u8, in short allow control what pin used,
+and what pins should be configured as GPIO
+
+Example:
+   max7359_keypad@38 {
+   compatible = "maxim,max7359";
+   reg = <0x38>;
+   interrupts = <28 IRQ_TYPE_LEVEL_LOW>;/*gpio_156*/
+   interrupt-parent = <&gpio5>;
+   maxim,debounce_reg = /bits/ 8 <0x5F>;
+   maxim,ports_reg = /bits/ 8 <0xFF>;
+   linux,keymap = <
+   MATRIX_KEY(0, 0, KEY_RESERVED) /*row 0 not used*/
+   MATRIX_KEY(0, 1, KEY_RESERVED)
+   MATRIX_KEY(0, 2, KEY_RESERVED)
+   MATRIX_KEY(0, 3, KEY_RESERVED)
+   MATRIX_KEY(0, 4, KEY_RESERVED)
+   MATRIX_KEY(0, 5, KEY_RESERVED)
+   MATRIX_KEY(0, 6, KEY_RESERVED)
+   MATRIX_KEY(0, 7, KEY_RESERVED)
+   ...
+   >;
+   };
diff --git a/drivers/input/keyboard/max7359_keypad.c 
b/drivers/input/keyboard/max7359_keypad.c
index 5091133..0164f2e 100644
--- a/drivers/input/keyboard/max7359_keypad.c
+++ b/drivers/input/keyboard/max7359_keypad.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define MAX7359_MAX_KEY_ROWS   8
 #define MAX7359_MAX_KEY_COLS   8
@@ -64,6 +65,11 @@ struct max7359_keypad {
struct i2c_client *client;
 };
 
+struct max7359_initial_state {
+   u8 debounce_val;
+   u8 ports_val;
+};
+
 static int max7359_write_reg(struct i2c_client *client, u8 reg, u8 val)
 {
int ret = i2c_smbus_write_byte_data(client, reg, val);
@@ -143,24 +149,54 @@ static void max7359_close(struct input_dev *dev)
max7359_fall_deepsleep(keypad->client);
 }
 
-static void max7359_initialize(struct i2c_client *client)
+static void max7359_initialize(struct i2c_client *client,
+  const struct max7359_initial_state *init_state)
 {
max7359_write_reg(client, MAX7359_REG_CONFIG,
MAX7359_CFG_KEY_RELEASE | /* Key release enable */
MAX7359_CFG_WAKEUP); /* Key press wakeup enable */
 
/* Full key-scan functionality */
-   max7359_write_reg(client, MAX7359_REG_DEBOUNCE, 0x1F);
+   max7359_write_reg(client, MAX7359_REG_DEBOUNCE,
+ init_state->debounce_val);
 
/* nINT asserts every debounce cycles */
max7359_write_reg(client, MAX7359_REG_INTERRUPT, 0x01);
+   max7359_write_reg(client, MAX7359_REG_PORTS, init_state->ports_val);
 
max7359_fall_deepsleep(client);
 }
 
+#ifdef CONFIG_OF
+static int max7359_parse_dt(struct device *dev,
+   struct max7359_initial_state *init_state)
+{
+   struct device_node *np = dev->of_node;
+   u8 prop;
+
+   if (!of_property_read_u8(np, "maxim,debounce_reg", &prop))
+   init_state->debounce_val = prop;
+
+   if (!of_property_read_u8(np, "maxim,ports_reg", &prop))
+   init_state->ports_val = prop;
+
+   return 0;
+}
+#else
+static inline int max7359_parse_dt(struct device *dev,
+  struct max7359_initial_state *init_state)
+{
+   return -EINVAL;
+}
+#endif
+
 static int max7359_probe(struct i2c_client *client,
const struct i2c_device_id *id)
 {
+   struct max7359_initial_state init_state = {
+   .debounce_val = 0x1F,
+   .ports_val = 0xFE,
+   };
const struct matrix_keymap_data *keymap_data =
dev_get_platdata(&client->dev);
struct max7359_keypad *keypad;
@@ -181,6 +217,15 @@ static int max7359_probe(struct i2c_client *client,
}
 
dev_dbg(&client->dev, "keys FIFO is 0x%02x\n", ret);
+   if (!keymap_data) {
+   error = max7359_parse_dt(&client->dev, &init_state);
+   if (error) {
+   dev_err(&client->dev, "platform data null, and no DT 
data\n");
+   return error;
+   }
+   

[PATCH 2/3] max7359_keypad: remove code duplication

2015-05-13 Thread Evgeniy Dushistov
max7359_keypad: remove code duplication,
 max7359_build_keycode do the same thing as matrix_keypad_build_keymap, but
 matrix_keypad_build_keymap can also handle DT bindings, so remove
 max7359_build_keycode and use matrix_keypad_build_keymap instead. Tested on
 beagleboard-xm.

Signed-off-by: Evgeniy A. Dushistov 
---
 drivers/input/keyboard/Kconfig  |  1 +
 drivers/input/keyboard/max7359_keypad.c | 30 +-
 2 files changed, 10 insertions(+), 21 deletions(-)

diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 106fbac..4d75062 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -367,6 +367,7 @@ config KEYBOARD_MAPLE
 
 config KEYBOARD_MAX7359
tristate "Maxim MAX7359 Key Switch Controller"
+   select INPUT_MATRIXKMAP
depends on I2C
help
  If you say yes here you get support for the Maxim MAX7359 Key
diff --git a/drivers/input/keyboard/max7359_keypad.c 
b/drivers/input/keyboard/max7359_keypad.c
index 4e35904..5091133 100644
--- a/drivers/input/keyboard/max7359_keypad.c
+++ b/drivers/input/keyboard/max7359_keypad.c
@@ -84,26 +84,6 @@ static int max7359_read_reg(struct i2c_client *client, int 
reg)
return ret;
 }
 
-static void max7359_build_keycode(struct max7359_keypad *keypad,
-   const struct matrix_keymap_data *keymap_data)
-{
-   struct input_dev *input_dev = keypad->input_dev;
-   int i;
-
-   for (i = 0; i < keymap_data->keymap_size; i++) {
-   unsigned int key = keymap_data->keymap[i];
-   unsigned int row = KEY_ROW(key);
-   unsigned int col = KEY_COL(key);
-   unsigned int scancode = MATRIX_SCAN_CODE(row, col,
-   MAX7359_ROW_SHIFT);
-   unsigned short keycode = KEY_VAL(key);
-
-   keypad->keycodes[scancode] = keycode;
-   __set_bit(keycode, input_dev->keybit);
-   }
-   __clear_bit(KEY_RESERVED, input_dev->keybit);
-}
-
 /* runs in an IRQ thread -- can (and will!) sleep */
 static irqreturn_t max7359_interrupt(int irq, void *dev_id)
 {
@@ -232,7 +212,15 @@ static int max7359_probe(struct i2c_client *client,
input_set_capability(input_dev, EV_MSC, MSC_SCAN);
input_set_drvdata(input_dev, keypad);
 
-   max7359_build_keycode(keypad, keymap_data);
+   error = matrix_keypad_build_keymap(keymap_data, NULL,
+  MAX7359_MAX_KEY_ROWS,
+  MAX7359_MAX_KEY_COLS,
+  keypad->keycodes,
+  input_dev);
+   if (error) {
+   dev_err(&client->dev, "failed to build keymap\n");
+   return error;
+   }
 
error = devm_request_threaded_irq(&client->dev, client->irq, NULL,
  max7359_interrupt,
-- 
2.3.6

-- 
/Evgeniy
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] max7359_keypad: Do not set MAX7359_CFG_INTERRUPT flag

2015-05-13 Thread Evgeniy Dushistov
max7359_keypad: Do not set MAX7359_CFG_INTERRUPT flag. 
In datasheet of max7359, there is description of this flag:
0 - INT cleared when FIFO empty,
1 - INT cleared after host read. In this mode, I2C should read
 FIFO until interrupt condition removed, or further INT may be lost.

So, if we set this flag, we have to read FIFO until it become
empty. But in interrupt we read FIFO just once.
This lead to "keyboard" hang until reboot, if we press
several keys, because of interrupt handler read just one
"press" from FIFO and clear interrupt.

Signed-off-by: Evgeniy A. Dushistov 
---
 drivers/input/keyboard/max7359_keypad.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/input/keyboard/max7359_keypad.c 
b/drivers/input/keyboard/max7359_keypad.c
index faa6da5..4e35904 100644
--- a/drivers/input/keyboard/max7359_keypad.c
+++ b/drivers/input/keyboard/max7359_keypad.c
@@ -166,7 +166,6 @@ static void max7359_close(struct input_dev *dev)
 static void max7359_initialize(struct i2c_client *client)
 {
max7359_write_reg(client, MAX7359_REG_CONFIG,
-   MAX7359_CFG_INTERRUPT | /* Irq clears after host read */
MAX7359_CFG_KEY_RELEASE | /* Key release enable */
MAX7359_CFG_WAKEUP); /* Key press wakeup enable */
 
-- 
2.3.6

-- 
/Evgeniy
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] ufs: [bl]e*_add_cpu conversion

2008-02-19 Thread Evgeniy Dushistov
On Tue, Feb 19, 2008 at 06:45:42PM +0100, Marcin Slusarz wrote:
> On Tue, Feb 19, 2008 at 12:22:19AM +0100, Roel Kluin wrote:
> > Andrew Morton wrote:
> > > On Wed, 13 Feb 2008 10:41:44 +0100 Roel Kluin <[EMAIL PROTECTED]> wrote:
> > > 
> > >> you may also want these:
> > >> ---
> > >> [bl]e_add_cpu conversion in return
> > 
> > > upsets powerpc (at least):
> > > 
> > > fs/ufs/swab.h: In function `fs64_add':
> > > fs/ufs/swab.h:47: warning: passing arg 1 of `le64_add_cpu' from 
> > > incompatible pointer type
> > > fs/ufs/swab.h:49: warning: passing arg 1 of `be64_add_cpu' from 
> > > incompatible pointer type
> > > fs/ufs/swab.h: In function `fs64_sub':
> > > fs/ufs/swab.h:58: warning: passing arg 1 of `le64_add_cpu' from 
> > > incompatible pointer type
> > > fs/ufs/swab.h:60: warning: passing arg 1 of `be64_add_cpu' from 
> > > incompatible pointer type
> > 
> > sorry for this. Is it correct to cast like the patch below does?
> I don't think so. Their prototypes are wrong. We can:
> a) remove fs64_add and fs64_sub as nobody use them
> b) fix them - change second parameter do __fs64 (and convert to 
> [bl]e64_add_cpu)
> 
> Evgeniy?
> 

I vote for removing unused code.

-- 
/Evgeniy

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] fs/ufs/util.h 2nd parameter of fs32_to_cpu is not boolean

2008-02-16 Thread Evgeniy Dushistov
On Sat, Feb 16, 2008 at 08:38:15PM +0100, Roel Kluin wrote:
> from: fs/befs/endian.h +33
> static inline u32
> fs32_to_cpu(const struct super_block *sb, fs32 n)
> {
> if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE)
> return le32_to_cpu((__force __le32)n);
> else
> return be32_to_cpu((__force __be32)n);
> }
> 
> The 2nd parameter is not boolean
> ---
> Test the return value, rather than passing a boolean
> 
> Signed-off-by: Roel Kluin <[EMAIL PROTECTED]>
> ---
> diff --git a/fs/ufs/util.h b/fs/ufs/util.h
> index b26fc4d..23ceed8 100644
> --- a/fs/ufs/util.h
> +++ b/fs/ufs/util.h
> @@ -58,7 +58,7 @@ ufs_set_fs_state(struct super_block *sb, struct 
> ufs_super_block_first *usb1,
>  {
>   switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
>   case UFS_ST_SUNOS:
> - if (fs32_to_cpu(sb, usb3->fs_postblformat == UFS_42POSTBLFMT)) {
> + if (fs32_to_cpu(sb, usb3->fs_postblformat) == UFS_42POSTBLFMT) {
>   usb1->fs_u0.fs_sun.fs_state = cpu_to_fs32(sb, value);
>   break;
>   }

Yeah, in origin patch, which introduced this code was the similar
misprint. It is sad that after review only one was fixed,
and the second go to mainline.

Acked-by: Evgeniy Dushistov <[EMAIL PROTECTED]>

-- 
/Evgeniy

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [GIT PATCH] SCSI bug fixes for 2.6.24-rc3

2008-01-08 Thread Evgeniy Dushistov
On Sun, Nov 25, 2007 at 01:24:25PM +0200, James Bottomley wrote:
> This is a bit of a rash of bug fixes.  The qla1280 is actually a bug fix
> (in spite of the title---it's actually correcting an existing problem
> with the qla1280 implementation of accessors that broke the current
> driver).
> 

Recently I build last Linus's git tree, and got:
‘req_cnt’ is used uninitialized in this function,
and see bellow
> The patch is available here:
> 
> master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6.git
> 
> The short changelog is:
...
> Jes Sorensen (1):
>   qla1280: convert to use the data buffer accessors
> 
...
>  scsi/qla1280.c |  387 
> +
...
>   /* Calculate number of entries and segments required. */
> - req_cnt = 1;
> 

Initilization of req_cnt was removed, but in this function
there are places like 
req_cnt += (seg_cnt - 4) / 7;
or
req_cnt++;
This is should be so?

-- 
/Evgeniy

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: fsx failure on ufs2

2008-01-02 Thread Evgeniy Dushistov
Hi, sorry for delay.

On Fri, Dec 14, 2007 at 05:21:31PM +0100, Jean-Marc Saffroy wrote:
> For an embedded system, I'm currently evaluating the robustness of ufs2 
> write support on Linux, and my very first test, with fsx, shows serious 
> problems.
>
> My test bed is a single CPU PC with a single IDE disk, that boots FreeBSD 
> 6.2 and Ubuntu 7.10. The kernel on Ubuntu is a vanilla 2.6.23.9 with UFS2 
> write support. fsx is from the freebsd cvs (with a small patch to build on 
> Linux, see after my sig):
>   http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/fsx/
>

Can you try this patch (see attachment)?

-- 
/Evgeniy
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index f63a09c..572b145 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -404,6 +404,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 
fragment,
if (tmp) {
UFSD("EXIT (ALREADY ALLOCATED)\n");
unlock_super(sb);
+   *err = 0;
return 0;
}
}
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 4320782..34ce4fb 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -273,6 +273,8 @@ repeat:
tmp = ufs_new_fragments(inode, p, fragment - blockoff,
goal, uspi->s_fpb, err,
phys != NULL ? locked_page : NULL);
+   if (!tmp && ufs_data_ptr_to_cpu(sb, p))
+   goto repeat;
}
if (!tmp) {
if ((!blockoff && ufs_data_ptr_to_cpu(sb, p)) ||
@@ -423,10 +425,13 @@ int ufs_getfrag_block(struct inode *inode, sector_t 
fragment, struct buffer_head
u64 phys64 = 0;

if (!create) {
-   phys64 = ufs_frag_map(inode, fragment);
-   UFSD("phys64 = %llu\n", (unsigned long long)phys64);
-   if (phys64)
-   map_bh(bh_result, sb, phys64);
+   if (fragment < UFS_I(inode)->i_lastfrag) {
+   phys64 = ufs_frag_map(inode, fragment);
+   if (phys64)
+   map_bh(bh_result, sb, phys64);
+   }
+   UFSD("fragment %llu, phys64 = %llu\n",
+(unsigned long long)fragment, (unsigned long long)phys64);
return 0;
}
 
@@ -502,6 +507,7 @@ out:
map_bh(bh_result, sb, phys);
 abort:
unlock_kernel();
+   UFSD("EXIT: err %d, new %d\n", err, new);
return err;
 
 abort_negative:
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c
index 311ded3..ef09426 100644
--- a/fs/ufs/truncate.c
+++ b/fs/ufs/truncate.c
@@ -390,6 +390,7 @@ static int ufs_alloc_lastblock(struct inode *inode)
u64 phys64;
 
lastfrag = (i_size_read(inode) + uspi->s_fsize - 1) >> uspi->s_fshift;
+   UFSD("BEGIN lastfrag %llu\n", (unsigned long long)lastfrag);
 
if (!lastfrag)
goto out;
@@ -418,13 +419,13 @@ static int ufs_alloc_lastblock(struct inode *inode)
   clear_buffer_new(bh);
   unmap_underlying_metadata(bh->b_bdev,
 bh->b_blocknr);
-  /*
-   * we do not zeroize fragment, because of
-   * if it maped to hole, it already contains zeroes
-   */
-  set_buffer_uptodate(bh);
-  mark_buffer_dirty(bh);
-  set_page_dirty(lastpage);
+  if (!buffer_dirty(bh)) {
+  zero_user_page(lastpage, end * sb->s_blocksize,
+ sb->s_blocksize, KM_USER0);
+  set_buffer_uptodate(bh);
+  mark_buffer_dirty(bh);
+  set_page_dirty(lastpage);
+  }   
}
 
if (lastfrag >= UFS_IND_FRAGMENT) {


[PATCH]: ufs: fix symlink creation on ufs2

2008-01-02 Thread Evgeniy Dushistov
If create symlink on UFS2 filesystem under Linux,
it looks wrong under other OSes, because of max symlink length
field was not initialized properly, and data blocks were not
used to save short symlink names.

Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>
Cc: Steven <[EMAIL PROTECTED]>

---

diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 0072cb3..14605c0 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -131,6 +131,8 @@ static void ufs_print_super_stuff(struct super_block *sb,
printk(KERN_INFO"  cs_nffree(Num of free frags): %llu\n",
   (unsigned long long)
   fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nffree));
+   printk(KERN_INFO"  fs_maxsymlinklen: %u\n",
+  usb3->fs_un2.fs_44.fs_maxsymlinklen);
} else {
printk(" sblkno:  %u\n", fs32_to_cpu(sb, usb1->fs_sblkno));
printk(" cblkno:  %u\n", fs32_to_cpu(sb, usb1->fs_cblkno));
@@ -1060,8 +1062,8 @@ magic_found:
uspi->s_bpf = uspi->s_fsize << 3;
uspi->s_bpfshift = uspi->s_fshift + 3;
uspi->s_bpfmask = uspi->s_bpf - 1;
-   if ((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) ==
-   UFS_MOUNT_UFSTYPE_44BSD)
+   if ((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_44BSD ||
+   (sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_UFS2)
uspi->s_maxsymlinklen =
fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_maxsymlinklen);
 
-- 
/Evgeniy

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: fsx failure on ufs2

2007-12-16 Thread Evgeniy Dushistov
On Fri, Dec 14, 2007 at 05:21:31PM +0100, Jean-Marc Saffroy wrote:
> For an embedded system, I'm currently evaluating the robustness of ufs2 
> write support on Linux, and my very first test, with fsx, shows serious 
> problems.
>
> My test bed is a single CPU PC with a single IDE disk, that boots FreeBSD 
> 6.2 and Ubuntu 7.10. The kernel on Ubuntu is a vanilla 2.6.23.9 with UFS2 
> write support. fsx is from the freebsd cvs (with a small patch to build on 
> Linux, see after my sig):
>   http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/fsx/
>

I used fsx-linux.c from ext3-tools project, but ran it with
different options.

>
> Can anyone else confirm this problem?
>
Using your options I am able to reproduce this bug.
Looks like problem in ufs_alloc_lastblock, last page in file
contains zeros, but because of ufs_readpage, it can be contains 
garbage. I will look at next week how it can be fixed.

-- 
/Evgeniy

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] ufs: fix nexstep dir block size

2007-12-01 Thread Evgeniy Dushistov
This patch fixes regression, introduced since 2.6.16.
NextStep variant of UFS as OpenStep uses directory block size
equals to 1024. Without this change, ufs_check_page fails in many
cases.

Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>
Cc: Dave Bailey <[EMAIL PROTECTED]>

---

diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 30f8c2b..e4263c1 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -179,7 +179,7 @@ bad_entry:
goto fail;
 Eend:
p = (struct ufs_dir_entry *)(kaddr + offs);
-   ufs_error (sb, "ext2_check_page",
+   ufs_error (sb, __FUNCTION__,
   "entry in directory #%lu spans the page boundary"
   "offset=%lu",
   dir->i_ino, (page->index<s_fsize = block_size = 1024;
uspi->s_fmask = ~(1024 - 1);
uspi->s_fshift = 10;
uspi->s_sbsize = super_block_size = 2048;
uspi->s_sbbase = 0;
+   uspi->s_dirblksize = 1024;
flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
if (!(sb->s_flags & MS_RDONLY)) {
if (!silent)
@@ -771,13 +771,13 @@ static int ufs_fill_super(struct super_block *sb, void 
*data, int silent)
break;

case UFS_MOUNT_UFSTYPE_NEXTSTEP_CD:
-   /*TODO: check may be we need set special dir block size?*/
UFSD("ufstype=nextstep-cd\n");
uspi->s_fsize = block_size = 2048;
uspi->s_fmask = ~(2048 - 1);
uspi->s_fshift = 11;
uspi->s_sbsize = super_block_size = 2048;
uspi->s_sbbase = 0;
+   uspi->s_dirblksize = 1024;
flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
if (!(sb->s_flags & MS_RDONLY)) {
if (!silent)

-- 
/Evgeniy

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Problem with ufs nextstep in 2.6.18 (debian)

2007-11-21 Thread Evgeniy Dushistov
On Tue, Nov 20, 2007 at 12:29:03PM -0800, Dave Bailey wrote:
> This problem has been around since kernel 2.6.16, and I see it in
> 2.6.23.1-10.fc7. It occurs in the ufs_check_page function of ufs/dir.c
> at the Espan test, which seems unnecessary for NextStep/OpenStep
> files systems. The following patch preserves the test for other file
> systems and makes the mount useful for NextStep/OpenStep:
> (against the 2.6.23.1-10.fc7 source tree)
>
> [EMAIL PROTECTED] diff dir.c dir.c.orig
> 108,110d107
> <   unsigned mnext = UFS_SB(sb)->s_mount_opt &
> < (UFS_MOUNT_UFSTYPE_NEXTSTEP || UFS_MOUNT_UFSTYPE_NEXTSTEP_CD ||
> <  UFS_MOUNT_UFSTYPE_OPENSTEP);
> 131c128
> <   if ((mnext == 0) & (((offs + rec_len - 1) ^ offs) & 
> ~chunk_mask))
> ---
> >   if (((offs + rec_len - 1) ^ offs) & ~chunk_mask)

This fixes only symptom, not illness.
This check represent what code think about filesystem layout.
On what actually kind of UFS system did you test this patch?
When I sometime ago fixed similar issue for openstep ufs,
actully this was darwin's ufs which has the same layout,
I just set s_dirblksize to right value, may be for 
UFS_MOUNT_UFSTYPE_NEXTSTEP, UFS_MOUNT_UFSTYPE_NEXTSTEP_CD you need
do the same, see TODO items in fs/ufs/super.c.

-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 49/59] fs/ufs: Add missing "space"

2007-11-21 Thread Evgeniy Dushistov
On Mon, Nov 19, 2007 at 05:53:36PM -0800, Joe Perches wrote:
> 
> Signed-off-by: Joe Perches <[EMAIL PROTECTED]>
> ---
>  fs/ufs/dir.c |2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
> index 30f8c2b..d19dfe8 100644
> --- a/fs/ufs/dir.c
> +++ b/fs/ufs/dir.c
> @@ -180,7 +180,7 @@ bad_entry:
>  Eend:
>   p = (struct ufs_dir_entry *)(kaddr + offs);
>   ufs_error (sb, "ext2_check_page",

If you touch this code, it will be good,
if you also replace "ext2_check_page" with something like __FUNCTION__.

> -"entry in directory #%lu spans the page boundary"
> +"entry in directory #%lu spans the page boundary "
>  "offset=%lu",
>  dir->i_ino, (page->index<  fail:
> -- 
> 1.5.3.5.652.gf192c

-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] 82596: free nonexistent resource fix

2007-11-04 Thread Evgeniy Dushistov
During booting of last vanilla kernel I got:
Trying to free nonexistent resource...

This because of if "ENABLE_APRICOT" is on we do:
request_region(ioaddr,...)
if (checksum test failed)
  goto out1;
dev->base_addr = ioaddr;//<-here mistake

out1:
release_region(dev->base_addr,...)

Here patch which fixes this bug for me.

Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>

---

diff --git a/drivers/net/82596.c b/drivers/net/82596.c
index bb30d5b..2797da7 100644
--- a/drivers/net/82596.c
+++ b/drivers/net/82596.c
@@ -1192,6 +1192,8 @@ struct net_device * __init i82596_probe(int unit)
goto out;
}
 
+   dev->base_addr = ioaddr;
+
for (i = 0; i < 8; i++) {
eth_addr[i] = inb(ioaddr + 8 + i);
checksum += eth_addr[i];
@@ -1209,7 +1211,6 @@ struct net_device * __init i82596_probe(int unit)
goto out1;
}
 
-   dev->base_addr = ioaddr;
dev->irq = 10;
}
 #endif

-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 106/327] ufs: Fix mount check in ufs_fill_super()

2007-10-27 Thread Evgeniy Dushistov
On Tue, Oct 16, 2007 at 11:26:53PM -0700, [EMAIL PROTECTED] wrote:
> From: Satyam Sharma <[EMAIL PROTECTED]>
> 
> The current code skips the check to verify whether the filesystem was
> previously cleanly unmounted, if (flags & UFS_ST_MASK) == UFS_ST_44BSD or
> UFS_ST_OLD.  This looks like an inadvertent bug that slipped in due to
> parantheses in the compound conditional to me, especially given that
> ufs_get_fs_state() handles the UFS_ST_44BSD case perfectly well.  So, let's
> fix the compound condition appropriately.
> 

I wonder on what type of UFS do you test this patch?
NetBSD and FreeBSD do not use "fs_state", they use "fs_clean" flag,
only Solaris does check like this: fs_state + fs_time == FSOK.

That's why parentheses was like that.

At now with linux-2.6.24-rc1-git1, I get: fs need fsck,
but NetBSD's fsck says that's all ok.

I suggest revert this patch.

> Signed-off-by: Satyam Sharma <[EMAIL PROTECTED]>
> Cc: Evgeniy Dushistov <[EMAIL PROTECTED]>
> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
> ---
> 
>  fs/ufs/super.c |   15 ---
>  1 file changed, 8 insertions(+), 7 deletions(-)
> 
> diff -puN fs/ufs/super.c~ufs-fix-sun-state-fix-mount-check-in-ufs_fill_super 
> fs/ufs/super.c
> --- a/fs/ufs/super.c~ufs-fix-sun-state-fix-mount-check-in-ufs_fill_super
> +++ a/fs/ufs/super.c
> @@ -933,19 +933,20 @@ magic_found:
>   goto again;
>   }
>  
> - sbi->s_flags = flags;/*after that line some functions use s_flags*/
> + /* Set sbi->s_flags here, used by ufs_get_fs_state() below */
> + sbi->s_flags = flags;
>   ufs_print_super_stuff(sb, usb1, usb2, usb3);
>  
>   /*
>* Check, if file system was correctly unmounted.
>* If not, make it read only.
>*/
> - if (((flags & UFS_ST_MASK) == UFS_ST_44BSD) ||
> -   ((flags & UFS_ST_MASK) == UFS_ST_OLD) ||
> -   (((flags & UFS_ST_MASK) == UFS_ST_SUN || 
> - (flags & UFS_ST_MASK) == UFS_ST_SUNOS ||
> -   (flags & UFS_ST_MASK) == UFS_ST_SUNx86) && 
> -   (ufs_get_fs_state(sb, usb1, usb3) == (UFS_FSOK - fs32_to_cpu(sb, 
> usb1->fs_time) {
> + if flags & UFS_ST_MASK) == UFS_ST_44BSD)||
> +  ((flags & UFS_ST_MASK) == UFS_ST_OLD)  ||
> +  ((flags & UFS_ST_MASK) == UFS_ST_SUN)  ||
> +  ((flags & UFS_ST_MASK) == UFS_ST_SUNOS)||
> +  ((flags & UFS_ST_MASK) == UFS_ST_SUNx86))  &&
> + (ufs_get_fs_state(sb, usb1, usb3) == (UFS_FSOK - fs32_to_cpu(sb, 
> usb1->fs_time {
>   switch(usb1->fs_clean) {
>   case UFS_FSCLEAN:
>   UFSD("fs is clean\n");
> _

-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] ufs fix sun state

2007-08-19 Thread Evgeniy Dushistov
Different types of ufs hold state in different places,
to hide complexity of this, there is ufs_get_fs_state,
it returns state according to "UFS_SB(sb)->s_flags",
but during mount ufs_get_fs_state is called,
before setting s_flags, this cause message for
ufs types like sun ufs: "fs need fsck",
and remount in readonly state.

This patch depend on other patches that now in -mm branch.


Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>

---

Index: linux-2.6.23-rc3-git1/fs/ufs/super.c
===
--- linux-2.6.23-rc3-git1.orig/fs/ufs/super.c
+++ linux-2.6.23-rc3-git1/fs/ufs/super.c
@@ -934,7 +934,7 @@ magic_found:
flags |=  UFS_ST_SUN;
}
 
-
+   sbi->s_flags = flags;/*after that line some functions use s_flags*/
ufs_print_super_stuff(sb, usb1, usb2, usb3);
 
/*
@@ -1065,8 +1065,6 @@ magic_found:
UFS_MOUNT_UFSTYPE_44BSD)
uspi->s_maxsymlinklen =
fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_maxsymlinklen);
-   
-   sbi->s_flags = flags;
 
inode = iget(sb, UFS_ROOTINO);
if (!inode || is_bad_inode(inode))

-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] ufs: move non-layout parts of ufs_fs.h to fs/ufs/

2007-08-04 Thread Evgeniy Dushistov
Move prototypes and in-core structures to fs/ufs/ similar to what most
other filesystems already do.

I made little modifications: move also ufs debug macros and
mount options constants into fs/ufs/ufs.h, this stuff
also private for ufs.

 
Signed-off-by: Christoph Hellwig <[EMAIL PROTECTED]>
Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>

---

Index: linux-2.6.23-rc2/fs/ufs/balloc.c
===
--- linux-2.6.23-rc2.orig/fs/ufs/balloc.c
+++ linux-2.6.23-rc2/fs/ufs/balloc.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 
+#include "ufs.h"
 #include "swab.h"
 #include "util.h"
 
Index: linux-2.6.23-rc2/fs/ufs/cylinder.c
===
--- linux-2.6.23-rc2.orig/fs/ufs/cylinder.c
+++ linux-2.6.23-rc2/fs/ufs/cylinder.c
@@ -17,6 +17,7 @@
 
 #include 
 
+#include "ufs.h"
 #include "swab.h"
 #include "util.h"
 
Index: linux-2.6.23-rc2/fs/ufs/dir.c
===
--- linux-2.6.23-rc2.orig/fs/ufs/dir.c
+++ linux-2.6.23-rc2/fs/ufs/dir.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 
+#include "ufs.h"
 #include "swab.h"
 #include "util.h"
 
Index: linux-2.6.23-rc2/fs/ufs/file.c
===
--- linux-2.6.23-rc2.orig/fs/ufs/file.c
+++ linux-2.6.23-rc2/fs/ufs/file.c
@@ -27,6 +27,9 @@
 #include 
 #include  /* for sync_mapping_buffers() */
 
+#include "ufs.h"
+
+
 static int ufs_sync_file(struct file *file, struct dentry *dentry, int 
datasync)
 {
struct inode *inode = dentry->d_inode;
Index: linux-2.6.23-rc2/fs/ufs/ialloc.c
===
--- linux-2.6.23-rc2.orig/fs/ufs/ialloc.c
+++ linux-2.6.23-rc2/fs/ufs/ialloc.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 
+#include "ufs.h"
 #include "swab.h"
 #include "util.h"
 
Index: linux-2.6.23-rc2/fs/ufs/inode.c
===
--- linux-2.6.23-rc2.orig/fs/ufs/inode.c
+++ linux-2.6.23-rc2/fs/ufs/inode.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 
+#include "ufs.h"
 #include "swab.h"
 #include "util.h"
 
Index: linux-2.6.23-rc2/fs/ufs/namei.c
===
--- linux-2.6.23-rc2.orig/fs/ufs/namei.c
+++ linux-2.6.23-rc2/fs/ufs/namei.c
@@ -31,7 +31,7 @@
 #include 
 #include 
 #include 
-#include "swab.h"  /* will go away - see comment in mknod() */
+#include "ufs.h"
 #include "util.h"
 
 static inline int ufs_add_nondir(struct dentry *dentry, struct inode *inode)
@@ -110,7 +110,6 @@ static int ufs_mknod (struct inode * dir
err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
init_special_inode(inode, mode, rdev);
-   /* NOTE: that'll go when we get wide dev_t */
ufs_set_inode_dev(inode->i_sb, UFS_I(inode), rdev);
mark_inode_dirty(inode);
lock_kernel();
Index: linux-2.6.23-rc2/fs/ufs/super.c
===
--- linux-2.6.23-rc2.orig/fs/ufs/super.c
+++ linux-2.6.23-rc2/fs/ufs/super.c
@@ -91,6 +91,7 @@
 #include 
 #include 
 
+#include "ufs.h"
 #include "swab.h"
 #include "util.h"
 
Index: linux-2.6.23-rc2/fs/ufs/symlink.c
===
--- linux-2.6.23-rc2.orig/fs/ufs/symlink.c
+++ linux-2.6.23-rc2/fs/ufs/symlink.c
@@ -28,6 +28,8 @@
 #include 
 #include 
 #include 
+#include "ufs.h"
+
 
 static void *ufs_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
Index: linux-2.6.23-rc2/fs/ufs/truncate.c
===
--- linux-2.6.23-rc2.orig/fs/ufs/truncate.c
+++ linux-2.6.23-rc2/fs/ufs/truncate.c
@@ -46,6 +46,7 @@
 #include 
 #include 
 
+#include "ufs.h"
 #include "swab.h"
 #include "util.h"
 
Index: linux-2.6.23-rc2/fs/ufs/ufs.h
===
--- /dev/null
+++ linux-2.6.23-rc2/fs/ufs/ufs.h
@@ -0,0 +1,157 @@
+#ifndef _UFS_UFS_H
+#define _UFS_UFS_H 1
+
+#define UFS_MAX_GROUP_LOADED 8
+#define UFS_CGNO_EMPTY ((unsigned)-1)
+
+struct ufs_sb_private_info;
+struct ufs_cg_private_info;
+struct ufs_csum;
+
+struct ufs_sb_info {
+   struct ufs_sb_private_info * s_uspi;
+   struct ufs_csum * s_csp;
+   unsigned s_bytesex;
+   unsigned s_flags;
+   struct buffer_head ** s_ucg;
+   struct ufs_cg_private_info * s_ucpi[UFS_MAX_GROUP_LOADED];
+   unsigned s_cgno[UFS_MAX_GROUP_LOADED];
+   unsigned short s_cg_loaded;
+   unsigned s_mount_opt;
+};
+
+struct ufs_inode_info {
+   union {
+   __fs

[PATCH] ufs: implement show_options

2007-07-30 Thread Evgeniy Dushistov
This patch contains implementation of show_options method for UFS,
it depend on add-in-sunos-41x-compatible-mode-for-ufs.patch and
add-in-sunos-41x-compatible-mode-for-ufs-fix.patch.


Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>

---

Index: linux-2.6.23-rc1/fs/ufs/super.c
===
--- linux-2.6.23-rc1.orig/fs/ufs/super.c
+++ linux-2.6.23-rc1/fs/ufs/super.c
@@ -88,6 +88,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include "swab.h"
 #include "util.h"
@@ -286,10 +288,21 @@ void ufs_warning (struct super_block * s
 }
 
 enum {
-   Opt_type_old, Opt_type_sunx86, Opt_type_sun, Opt_type_sunos, 
Opt_type_44bsd,
-   Opt_type_ufs2, Opt_type_hp, Opt_type_nextstepcd, Opt_type_nextstep,
-   Opt_type_openstep, Opt_onerror_panic, Opt_onerror_lock,
-   Opt_onerror_umount, Opt_onerror_repair, Opt_err
+   Opt_type_old = UFS_MOUNT_UFSTYPE_OLD,
+   Opt_type_sunx86 = UFS_MOUNT_UFSTYPE_SUNx86,
+   Opt_type_sun = UFS_MOUNT_UFSTYPE_SUN,
+   Opt_type_sunos = UFS_MOUNT_UFSTYPE_SUNOS,
+   Opt_type_44bsd = UFS_MOUNT_UFSTYPE_44BSD,
+   Opt_type_ufs2 = UFS_MOUNT_UFSTYPE_UFS2,
+   Opt_type_hp = UFS_MOUNT_UFSTYPE_HP,
+   Opt_type_nextstepcd = UFS_MOUNT_UFSTYPE_NEXTSTEP_CD,
+   Opt_type_nextstep = UFS_MOUNT_UFSTYPE_NEXTSTEP,
+   Opt_type_openstep = UFS_MOUNT_UFSTYPE_OPENSTEP,
+   Opt_onerror_panic = UFS_MOUNT_ONERROR_PANIC,
+   Opt_onerror_lock = UFS_MOUNT_ONERROR_LOCK,
+   Opt_onerror_umount = UFS_MOUNT_ONERROR_UMOUNT,
+   Opt_onerror_repair = UFS_MOUNT_ONERROR_REPAIR,
+   Opt_err
 };
 
 static match_table_t tokens = {
@@ -304,6 +317,7 @@ static match_table_t tokens = {
{Opt_type_nextstepcd, "ufstype=nextstep-cd"},
{Opt_type_nextstep, "ufstype=nextstep"},
{Opt_type_openstep, "ufstype=openstep"},
+/*end of possible ufs types */
{Opt_onerror_panic, "onerror=panic"},
{Opt_onerror_lock, "onerror=lock"},
{Opt_onerror_umount, "onerror=umount"},
@@ -1209,6 +1223,26 @@ static int ufs_remount (struct super_blo
return 0;
 }
 
+static int ufs_show_options(struct seq_file *seq, struct vfsmount *vfs)
+{
+   struct ufs_sb_info *sbi = UFS_SB(vfs->mnt_sb);
+   unsigned mval = sbi->s_mount_opt & UFS_MOUNT_UFSTYPE;
+   struct match_token *tp = tokens;
+
+   while (tp->token != Opt_onerror_panic && tp->token != mval)
+   ++tp;
+   BUG_ON(tp->token == Opt_onerror_panic);
+   seq_printf(seq, ",%s", tp->pattern);
+
+   mval = sbi->s_mount_opt & UFS_MOUNT_ONERROR;
+   while (tp->token != Opt_err && tp->token != mval)
+   ++tp;
+   BUG_ON(tp->token == Opt_err);
+   seq_printf(seq, ",%s", tp->pattern);
+
+   return 0;
+}
+
 static int ufs_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
struct super_block *sb = dentry->d_sb;
@@ -1301,6 +1335,7 @@ static const struct super_operations ufs
.write_super= ufs_write_super,
.statfs = ufs_statfs,
.remount_fs = ufs_remount,
+   .show_options   = ufs_show_options,
 #ifdef CONFIG_QUOTA
.quota_read = ufs_quota_read,
.quota_write= ufs_quota_write,

-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Add in SunOS 4.1.x compatible mode for UFS

2007-07-25 Thread Evgeniy Dushistov
Looks good.

Just a few minor things:

On Wed, Jul 25, 2007 at 06:27:46PM +0100, Mark Fortescue wrote:
> Macros have been put in to alow suport for the old static table Cylinder 
> Groups
> but this implementation does not use them yet.

But why add them to patch?
 
> + /* Sort out mod used on SunOS 4.1.3 for fs_state */
> + uspi->s_postblformat = fs32_to_cpu(sb, usb3->fs_postblformat);
> + if (((flags & UFS_ST_MASK) == UFS_ST_SUNOS) &&
> + (uspi->s_postblformat != UFS_42POSTBLFMT))
> + {
> + flags &= ~UFS_ST_MASK;
> + flags |=  UFS_ST_SUN;
> + }
> +
>  

Documentation/CodingStyle: if () {

>   switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
> + case UFS_ST_SUNOS:
> + if (fs32_to_cpu(sb, usb3->fs_postblformat == UFS_42POSTBLFMT))

Really should be so?
May be you mean:
fs32_to_cpu(sb, usb3->fs_postblformat) == UFS_42POSTBLFMT ?
 ^


-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH]is_power_of_2-ufs/super.c

2007-06-14 Thread Evgeniy Dushistov
On Thu, Jun 14, 2007 at 01:39:18PM +0530, vignesh babu wrote:
> 
> 
> Replacing (n & (n-1)) in the context of power of 2 checks
> with is_power_of_2
> 
> Signed-off-by: vignesh babu <[EMAIL PROTECTED]>

Acked-by: Evgeniy Dushistov <[EMAIL PROTECTED]>

> --- 
> diff --git a/fs/ufs/super.c b/fs/ufs/super.c
> index 22ff6ed..2b30116 100644
> --- a/fs/ufs/super.c
> +++ b/fs/ufs/super.c
> @@ -87,6 +87,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "swab.h"
>  #include "util.h"
> @@ -854,7 +855,7 @@ magic_found:
>   uspi->s_fmask = fs32_to_cpu(sb, usb1->fs_fmask);
>   uspi->s_fshift = fs32_to_cpu(sb, usb1->fs_fshift);
>  
> - if (uspi->s_fsize & (uspi->s_fsize - 1)) {
> + if (!is_power_of_2(uspi->s_fsize)) {
>   printk(KERN_ERR "ufs_read_super: fragment size %u is not a 
> power of 2\n",
>   uspi->s_fsize);
>   goto failed;
> @@ -869,7 +870,7 @@ magic_found:
>   uspi->s_fsize);
>   goto failed;
>   }
> - if (uspi->s_bsize & (uspi->s_bsize - 1)) {
> + if (!is_power_of_2(uspi->s_bsize)) {
>   printk(KERN_ERR "ufs_read_super: block size %u is not a power 
> of 2\n",
>   uspi->s_bsize);
>   goto failed;
> 
> -- 
> Vignesh Babu BM 
> _ 
> "Why is it that every time I'm with you, makes me believe in magic?"
> 
> 
> 
> The information contained in this electronic message and any attachments to 
> this message are intended for the exclusive use of the addressee(s) and may 
> contain proprietary, confidential or privileged information. If you are not 
> the intended recipient, you should not disseminate, distribute or copy this 
> e-mail. Please notify the sender immediately and destroy all copies of this 
> message and any attachments. 
> 
> WARNING: Computer viruses can be transmitted via email. The recipient should 
> check this email and any attachments for the presence of viruses. The company 
> accepts no liability for any damage caused by any virus transmitted by this 
> email.
>  
> www.wipro.com

-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Problem with ufs nextstep in 2.6.18 (debian)

2007-04-16 Thread Evgeniy Dushistov
>The error also happens in 2.6.19, same as in 2.6.18.
>I extracted this from syslog: 
>Apr 17 00:14:15 kdev kernel: UFS-fs error (device loop0):
>ufs_check_page: bad entry

Is this happened also with this patch:
http://lkml.org/lkml/diff/2007/2/5/75/1
?

-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH]: ufs proper handling of zero link case

2007-04-15 Thread Evgeniy Dushistov
This patch should fix or partly fix this bug:
http://bugzilla.kernel.org/show_bug.cgi?id=8276

The problem is:
- if we see "zero link case" during reading inode operation,
we call ufs_error(which remount fs readonly), but not "mark" inode as
bad (1)
- in readonly case we do not fill some data structures, which are used
in read and write case (2)
- VFS call ufs_delete_inode if link count is zero (3)

so (1)->(3)->(2) cause oops, this patch should fix such scenario

Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>
Cc: Jim Paris <[EMAIL PROTECTED]>

---

Index: linux-2.6.21-rc6/fs/ufs/inode.c
===
--- linux-2.6.21-rc6.orig/fs/ufs/inode.c
+++ linux-2.6.21-rc6/fs/ufs/inode.c
@@ -601,7 +601,7 @@ static void ufs_set_inode_ops(struct ino
   ufs_get_inode_dev(inode->i_sb, 
UFS_I(inode)));
 }
 
-static void ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode)
+static int ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode)
 {
struct ufs_inode_info *ufsi = UFS_I(inode);
struct super_block *sb = inode->i_sb;
@@ -613,8 +613,10 @@ static void ufs1_read_inode(struct inode
 */
inode->i_mode = mode = fs16_to_cpu(sb, ufs_inode->ui_mode);
inode->i_nlink = fs16_to_cpu(sb, ufs_inode->ui_nlink);
-   if (inode->i_nlink == 0)
+   if (inode->i_nlink == 0) {
ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink\n", 
inode->i_ino);
+   return -1;
+   }

/*
 * Linux now has 32-bit uid and gid, so we can support EFT.
@@ -643,9 +645,10 @@ static void ufs1_read_inode(struct inode
for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++)
ufsi->i_u1.i_symlink[i] = 
ufs_inode->ui_u2.ui_symlink[i];
}
+   return 0;
 }
 
-static void ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode)
+static int ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode)
 {
struct ufs_inode_info *ufsi = UFS_I(inode);
struct super_block *sb = inode->i_sb;
@@ -658,8 +661,10 @@ static void ufs2_read_inode(struct inode
 */
inode->i_mode = mode = fs16_to_cpu(sb, ufs2_inode->ui_mode);
inode->i_nlink = fs16_to_cpu(sb, ufs2_inode->ui_nlink);
-   if (inode->i_nlink == 0)
+   if (inode->i_nlink == 0) {
ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink\n", 
inode->i_ino);
+   return -1;
+   }
 
 /*
  * Linux now has 32-bit uid and gid, so we can support EFT.
@@ -690,6 +695,7 @@ static void ufs2_read_inode(struct inode
for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++)
ufsi->i_u1.i_symlink[i] = 
ufs2_inode->ui_u2.ui_symlink[i];
}
+   return 0;
 }
 
 void ufs_read_inode(struct inode * inode)
@@ -698,6 +704,7 @@ void ufs_read_inode(struct inode * inode
struct super_block * sb;
struct ufs_sb_private_info * uspi;
struct buffer_head * bh;
+   int err;
 
UFSD("ENTER, ino %lu\n", inode->i_ino);
 
@@ -720,14 +727,17 @@ void ufs_read_inode(struct inode * inode
if ((UFS_SB(sb)->s_flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) {
struct ufs2_inode *ufs2_inode = (struct ufs2_inode *)bh->b_data;
 
-   ufs2_read_inode(inode,
-   ufs2_inode + ufs_inotofsbo(inode->i_ino));
+   err = ufs2_read_inode(inode,
+ ufs2_inode + ufs_inotofsbo(inode->i_ino));
} else {
struct ufs_inode *ufs_inode = (struct ufs_inode *)bh->b_data;
 
-   ufs1_read_inode(inode, ufs_inode + ufs_inotofsbo(inode->i_ino));
+   err = ufs1_read_inode(inode,
+ ufs_inode + ufs_inotofsbo(inode->i_ino));
}
 
+   if (err)
+   goto bad_inode;
inode->i_version++;
ufsi->i_lastfrag =
(inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift;
@@ -888,6 +898,8 @@ void ufs_delete_inode (struct inode * in
loff_t old_i_size;
 
truncate_inode_pages(&inode->i_data, 0);
+   if (is_bad_inode(inode))
+   goto no_delete;
/*UFS_I(inode)->i_dtime = CURRENT_TIME;*/
lock_kernel();
mark_inode_dirty(inode);
@@ -898,4 +910,7 @@ void ufs_delete_inode (struct inode * in
ufs_warning(inode->i_sb, __FUNCTION__, "ufs_truncate failed\n");
ufs_free_inode (inode);
unlock_kernel();
+   return;
+no_delete:
+   clear_inode(inode); /* We must guarantee clearing of inode... */
 }

-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/4]: ufs: zeroize the rest of block in truncate

2007-03-10 Thread Evgeniy Dushistov
This patch fix behaviour in such test scenario:

lseek(fd, BIG_OFFSET)
write(fd, buf, sizeof(buf))
truncate(BIG_OFFSET)
truncate(BIG_OFFSET + sizeof(buf))
read(fd, buf...)

Because of if file big enough(BIG_OFFSET) we start allocate
space by block, ordinary block size > page size,
so we should zeroize the rest of block in truncate(except last framgnet,
about which VFS should care), to not get garbage,
when we extend file.

Also patch corrects conversation
from pointer to block to physical block number,
this helps in case of not common used UFS types.

And add to debug output inode number.

Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>

---

Index: linux-2.6.21-rc3-git6/fs/ufs/truncate.c
===
--- linux-2.6.21-rc3-git6.orig/fs/ufs/truncate.c
+++ linux-2.6.21-rc3-git6/fs/ufs/truncate.c
@@ -74,7 +74,7 @@ static int ufs_trunc_direct(struct inode
unsigned i, tmp;
int retry;

-   UFSD("ENTER\n");
+   UFSD("ENTER: ino %lu\n", inode->i_ino);
 
sb = inode->i_sb;
uspi = UFS_SB(sb)->s_uspi;
@@ -96,8 +96,8 @@ static int ufs_trunc_direct(struct inode
block2 = ufs_fragstoblks (frag3);
}
 
-   UFSD("frag1 %llu, frag2 %llu, block1 %llu, block2 %llu, frag3 %llu,"
-" frag4 %llu\n",
+   UFSD("ino %lu, frag1 %llu, frag2 %llu, block1 %llu, block2 %llu,"
+" frag3 %llu, frag4 %llu\n", inode->i_ino,
 (unsigned long long)frag1, (unsigned long long)frag2,
 (unsigned long long)block1, (unsigned long long)block2,
 (unsigned long long)frag3, (unsigned long long)frag4);
@@ -163,7 +163,7 @@ next1:
mark_inode_dirty(inode);
  next3:
 
-   UFSD("EXIT\n");
+   UFSD("EXIT: ino %lu\n", inode->i_ino);
return retry;
 }
 
@@ -248,7 +248,7 @@ static int ufs_trunc_indirect(struct ino
}
ubh_brelse (ind_ubh);

-   UFSD("EXIT\n");
+   UFSD("EXIT: ino %lu\n", inode->i_ino);

return retry;
 }
@@ -262,7 +262,7 @@ static int ufs_trunc_dindirect(struct in
void *dind;
int retry = 0;

-   UFSD("ENTER\n");
+   UFSD("ENTER: ino %lu\n", inode->i_ino);

sb = inode->i_sb;
uspi = UFS_SB(sb)->s_uspi;
@@ -312,7 +312,7 @@ static int ufs_trunc_dindirect(struct in
}
ubh_brelse (dind_bh);

-   UFSD("EXIT\n");
+   UFSD("EXIT: ino %lu\n", inode->i_ino);

return retry;
 }
@@ -327,7 +327,7 @@ static int ufs_trunc_tindirect(struct in
void *tind, *p;
int retry;

-   UFSD("ENTER\n");
+   UFSD("ENTER: ino %lu\n", inode->i_ino);
 
retry = 0;

@@ -372,19 +372,21 @@ static int ufs_trunc_tindirect(struct in
}
ubh_brelse (tind_bh);

-   UFSD("EXIT\n");
+   UFSD("EXIT: ino %lu\n", inode->i_ino);
return retry;
 }
 
 static int ufs_alloc_lastblock(struct inode *inode)
 {
int err = 0;
+   struct super_block *sb = inode->i_sb;
struct address_space *mapping = inode->i_mapping;
-   struct ufs_sb_private_info *uspi = UFS_SB(inode->i_sb)->s_uspi;
+   struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
unsigned i, end;
sector_t lastfrag;
struct page *lastpage;
struct buffer_head *bh;
+   u64 phys64;
 
lastfrag = (i_size_read(inode) + uspi->s_fsize - 1) >> uspi->s_fshift;
 
@@ -424,6 +426,20 @@ static int ufs_alloc_lastblock(struct in
   set_page_dirty(lastpage);
}
 
+   if (lastfrag >= UFS_IND_FRAGMENT) {
+  end = uspi->s_fpb - ufs_fragnum(lastfrag) - 1;
+  phys64 = bh->b_blocknr + 1;
+  for (i = 0; i < end; ++i) {
+  bh = sb_getblk(sb, i + phys64);
+  lock_buffer(bh);
+  memset(bh->b_data, 0, sb->s_blocksize);
+  set_buffer_uptodate(bh);
+  mark_buffer_dirty(bh);
+  unlock_buffer(bh);
+  sync_dirty_buffer(bh);
+  brelse(bh);
+  }
+   }
 out_unlock:
ufs_put_locked_page(lastpage);
 out:
Index: linux-2.6.21-rc3-git6/fs/ufs/inode.c
===
--- linux-2.6.21-rc3-git6.orig/fs/ufs/inode.c
+++ linux-2.6.21-rc3-git6/fs/ufs/inode.c
@@ -212,7 +212,7 @@ repeat:
brelse (result);
goto repeat;
} else {
-   *phys = tmp + blockoff;
+   *phys = uspi->s_sbbase + tmp + blockoff;
re

[PATCH 4/4]: ufs2 tindirect truncate fix

2007-03-10 Thread Evgeniy Dushistov
During modification of code to support UFS2 writing,
the case with "three indirect" blocks in truncate path was missed,
this patch fixes this situation.

Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>

---

Index: linux-2.6.21-rc3-git6/fs/ufs/truncate.c
===
--- linux-2.6.21-rc3-git6.orig/fs/ufs/truncate.c
+++ linux-2.6.21-rc3-git6/fs/ufs/truncate.c
@@ -348,7 +348,7 @@ static int ufs_trunc_tindirect(struct in
}
 
for (i = tindirect_block ; i < uspi->s_apb ; i++) {
-   tind = ubh_get_addr32 (tind_bh, i);
+   tind = ubh_get_data_ptr(uspi, tind_bh, i);
retry |= ufs_trunc_dindirect(inode, UFS_NDADDR + 
uspi->s_apb + ((i + 1) << uspi->s_2apbshift), tind);
ubh_mark_buffer_dirty(tind_bh);
-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/4]: ufs2 more correct work with time

2007-03-10 Thread Evgeniy Dushistov
This patch corrects work with time in UFS2 case.

1)According to UFS2 disk layout modification/access and so on "time"
should be hold in two variables one 64bit for seconds and another
32bit for nanoseconds,

at now for some unknown reason we suppose
that "inode time" holds in three variables 32bit for seconds, 32bit for
milliseconds and 32bit for nanoseconds.

2)We set amount of nanoseconds in "VFS inode" to 0 during read, instead
of getting values from "on disk inode"(this should close
http://bugzilla.kernel.org/show_bug.cgi?id=7991).

Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>
Cc: Björn Jacke<[EMAIL PROTECTED]>

---

Index: linux-2.6.21-rc3-git6/fs/ufs/inode.c
===
--- linux-2.6.21-rc3-git6.orig/fs/ufs/inode.c
+++ linux-2.6.21-rc3-git6/fs/ufs/inode.c
@@ -668,12 +668,12 @@ static void ufs2_read_inode(struct inode
inode->i_gid = fs32_to_cpu(sb, ufs2_inode->ui_gid);
 
inode->i_size = fs64_to_cpu(sb, ufs2_inode->ui_size);
-   inode->i_atime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_atime.tv_sec);
-   inode->i_ctime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_ctime.tv_sec);
-   inode->i_mtime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_mtime.tv_sec);
-   inode->i_mtime.tv_nsec = 0;
-   inode->i_atime.tv_nsec = 0;
-   inode->i_ctime.tv_nsec = 0;
+   inode->i_atime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_atime);
+   inode->i_ctime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_ctime);
+   inode->i_mtime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_mtime);
+   inode->i_atime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_atimensec);
+   inode->i_ctime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_ctimensec);
+   inode->i_mtime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_mtimensec);
inode->i_blocks = fs64_to_cpu(sb, ufs2_inode->ui_blocks);
inode->i_generation = fs32_to_cpu(sb, ufs2_inode->ui_gen);
ufsi->i_flags = fs32_to_cpu(sb, ufs2_inode->ui_flags);
@@ -803,12 +803,12 @@ static void ufs2_update_inode(struct ino
ufs_inode->ui_gid = cpu_to_fs32(sb, inode->i_gid);
 
ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size);
-   ufs_inode->ui_atime.tv_sec = cpu_to_fs32(sb, inode->i_atime.tv_sec);
-   ufs_inode->ui_atime.tv_usec = 0;
-   ufs_inode->ui_ctime.tv_sec = cpu_to_fs32(sb, inode->i_ctime.tv_sec);
-   ufs_inode->ui_ctime.tv_usec = 0;
-   ufs_inode->ui_mtime.tv_sec = cpu_to_fs32(sb, inode->i_mtime.tv_sec);
-   ufs_inode->ui_mtime.tv_usec = 0;
+   ufs_inode->ui_atime = cpu_to_fs64(sb, inode->i_atime.tv_sec);
+   ufs_inode->ui_atimensec = cpu_to_fs32(sb, inode->i_atime.tv_nsec);
+   ufs_inode->ui_ctime = cpu_to_fs64(sb, inode->i_ctime.tv_sec);
+   ufs_inode->ui_ctimensec = cpu_to_fs32(sb, inode->i_ctime.tv_nsec);
+   ufs_inode->ui_mtime = cpu_to_fs64(sb, inode->i_mtime.tv_sec);
+   ufs_inode->ui_mtimensec = cpu_to_fs32(sb, inode->i_mtime.tv_nsec);
 
ufs_inode->ui_blocks = cpu_to_fs64(sb, inode->i_blocks);
ufs_inode->ui_flags = cpu_to_fs32(sb, ufsi->i_flags);
Index: linux-2.6.21-rc3-git6/fs/ufs/ialloc.c
===
--- linux-2.6.21-rc3-git6.orig/fs/ufs/ialloc.c
+++ linux-2.6.21-rc3-git6/fs/ufs/ialloc.c
@@ -343,9 +343,8 @@ cg_found:
lock_buffer(bh);
ufs2_inode = (struct ufs2_inode *)bh->b_data;
ufs2_inode += ufs_inotofsbo(inode->i_ino);
-   ufs2_inode->ui_birthtime.tv_sec =
-   cpu_to_fs32(sb, CURRENT_TIME_SEC.tv_sec);
-   ufs2_inode->ui_birthtime.tv_usec = 0;
+   ufs2_inode->ui_birthtime = cpu_to_fs64(sb, CURRENT_TIME.tv_sec);
+   ufs2_inode->ui_birthnsec = cpu_to_fs32(sb, 
CURRENT_TIME.tv_nsec);
mark_buffer_dirty(bh);
unlock_buffer(bh);
if (sb->s_flags & MS_SYNCHRONOUS)
Index: linux-2.6.21-rc3-git6/include/linux/ufs_fs.h
===
--- linux-2.6.21-rc3-git6.orig/include/linux/ufs_fs.h
+++ linux-2.6.21-rc3-git6/include/linux/ufs_fs.h
@@ -649,10 +649,10 @@ struct ufs2_inode {
__fs32 ui_blksize; /*  12: Inode blocksize. */
__fs64 ui_size;/*  16: File byte count. */
__fs64 ui_blocks;  /*  24: Bytes actually held. */
-   struct ufs_timeval   ui_atime;   /*  32: Last access time. */
-   struct ufs_timeval   ui_mtime;   /*  40: Last modified time. */
-   struct ufs_timeval   ui_ctime;   /*  48: Last inode change time. */
-   struct ufs_timeval   ui_birthtime;   /*  56: Inode creation time. */
+   __fs64  

[PATCH 2/4]: ufs: prepare write + change blocks on the fly

2007-03-10 Thread Evgeniy Dushistov
This patch fixes "change blocks numbers on the fly"
in case when "prepare write page" is in the call chain,
in this case some buffers may be not uptodate and not mapped,
we should care to map them and load from disk.

This patch was tested with:
ufs regressions simple tests
fsx-linux
ltp(20060306)
untar and build kernel

Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>

---

Index: linux-2.6.21-rc3-git6/fs/ufs/balloc.c
===
--- linux-2.6.21-rc3-git6.orig/fs/ufs/balloc.c
+++ linux-2.6.21-rc3-git6/fs/ufs/balloc.c
@@ -244,62 +244,87 @@ failed:
  * We can come here from ufs_writepage or ufs_prepare_write,
  * locked_page is argument of these functions, so we already lock it.
  */
-static void ufs_change_blocknr(struct inode *inode, unsigned int beg,
-  unsigned int count, unsigned int oldb,
-  unsigned int newb, struct page *locked_page)
+static void ufs_change_blocknr(struct inode *inode, sector_t beg,
+  unsigned int count, sector_t oldb,
+  sector_t newb, struct page *locked_page)
 {
-   const unsigned mask = (1 << (PAGE_CACHE_SHIFT - inode->i_blkbits)) - 1;
+   const unsigned blks_per_page =
+   1 << (PAGE_CACHE_SHIFT - inode->i_blkbits);
+   const unsigned mask = blks_per_page - 1;
struct address_space * const mapping = inode->i_mapping;
-   pgoff_t index, cur_index;
-   unsigned end, pos, j;
+   pgoff_t index, cur_index, last_index;
+   unsigned pos, j, lblock;
+   sector_t end, i;
struct page *page;
struct buffer_head *head, *bh;
 
-   UFSD("ENTER, ino %lu, count %u, oldb %u, newb %u\n",
- inode->i_ino, count, oldb, newb);
+   UFSD("ENTER, ino %lu, count %u, oldb %llu, newb %llu\n",
+ inode->i_ino, count,
+(unsigned long long)oldb, (unsigned long long)newb);
 
BUG_ON(!locked_page);
BUG_ON(!PageLocked(locked_page));
 
cur_index = locked_page->index;
-
-   for (end = count + beg; beg < end; beg = (beg | mask) + 1) {
-   index = beg >> (PAGE_CACHE_SHIFT - inode->i_blkbits);
+   end = count + beg;
+   last_index = end >> (PAGE_CACHE_SHIFT - inode->i_blkbits);
+   for (i = beg; i < end; i = (i | mask) + 1) {
+   index = i >> (PAGE_CACHE_SHIFT - inode->i_blkbits);
 
if (likely(cur_index != index)) {
page = ufs_get_locked_page(mapping, index);
-   if (!page || IS_ERR(page)) /* it was truncated or EIO */
+   if (!page)/* it was truncated */
+   continue;
+   if (IS_ERR(page)) {/* or EIO */
+   ufs_error(inode->i_sb, __FUNCTION__,
+ "read of page %llu failed\n",
+ (unsigned long long)index);
continue;
+   }
} else
page = locked_page;
 
head = page_buffers(page);
bh = head;
-   pos = beg & mask;
+   pos = i & mask;
for (j = 0; j < pos; ++j)
bh = bh->b_this_page;
-   j = 0;
+
+
+   if (unlikely(index == last_index))
+   lblock = end & mask;
+   else
+   lblock = blks_per_page;
+
do {
-   if (buffer_mapped(bh)) {
-   pos = bh->b_blocknr - oldb;
-   if (pos < count) {
-   UFSD(" change from %llu to %llu\n",
-(unsigned long long)pos + oldb,
-(unsigned long long)pos + newb);
-   bh->b_blocknr = newb + pos;
-   unmap_underlying_metadata(bh->b_bdev,
- 
bh->b_blocknr);
-   mark_buffer_dirty(bh);
-   ++j;
+   if (j >= lblock)
+   break;
+   pos = (i - beg) + j;
+
+   if (!buffer_mapped(bh))
+   map_bh(bh, inode->i_sb, oldb + pos);
+   if (!buffer_uptodate(bh)) {
+   ll_rw_block(READ, 1, &bh);
+   wait_on_buffer(bh);
+   if (!buffer_uptodate(bh)) {
+   

[PATCH]: ufs: restore back support of openstep

2007-02-05 Thread Evgeniy Dushistov
This is a fix of regression, which triggered by ~2.6.16.

Patch with name ufs-directory-and-page-cache-from-blocks-to-pages.patch:
in additional to conversation from block to page cache
mechanism added new checks of directory integrity,
one of them that directory entry do not across directory chunks.

But some kinds of UFS: OpenStep UFS and Apple UFS (looks like these
are the same filesystems) have different directory chunk size,
then common UFSes(BSD and Solaris UFS).

So this patch adds ability to works with variable size of directory chunks,
and set it for ufstype=openstep to right size.

Tested on darwin ufs.

This patch designed to be on top of UFS patches which are situated 
in -mm branch, after applying it, other 3 patches(UFS2 write support)
will produce warnings like: HUNK succeeded, but I tested,
they works as expected,
should I resend them?

Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>

---

Index: linux-2.6.20-rc7/fs/ufs/dir.c
===
--- linux-2.6.20-rc7.orig/fs/ufs/dir.c
+++ linux-2.6.20-rc7/fs/ufs/dir.c
@@ -106,12 +106,13 @@ static void ufs_check_page(struct page *
char *kaddr = page_address(page);
unsigned offs, rec_len;
unsigned limit = PAGE_CACHE_SIZE;
+   const unsigned chunk_mask = UFS_SB(sb)->s_uspi->s_dirblksize - 1;
struct ufs_dir_entry *p;
char *error;
 
if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) {
limit = dir->i_size & ~PAGE_CACHE_MASK;
-   if (limit & (UFS_SECTOR_SIZE - 1))
+   if (limit & chunk_mask)
goto Ebadsize;
if (!limit)
goto out;
@@ -126,7 +127,7 @@ static void ufs_check_page(struct page *
goto Ealign;
if (rec_len < UFS_DIR_REC_LEN(ufs_get_de_namlen(sb, p)))
goto Enamelen;
-   if (((offs + rec_len - 1) ^ offs) & ~(UFS_SECTOR_SIZE-1))
+   if (((offs + rec_len - 1) ^ offs) & ~chunk_mask)
goto Espan;
if (fs32_to_cpu(sb, p->d_ino) > (UFS_SB(sb)->s_uspi->s_ipg *
  UFS_SB(sb)->s_uspi->s_ncg))
@@ -310,6 +311,7 @@ int ufs_add_link(struct dentry *dentry, 
int namelen = dentry->d_name.len;
struct super_block *sb = dir->i_sb;
unsigned reclen = UFS_DIR_REC_LEN(namelen);
+   const unsigned int chunk_size = UFS_SB(sb)->s_uspi->s_dirblksize;
unsigned short rec_len, name_len;
struct page *page = NULL;
struct ufs_dir_entry *de;
@@ -342,8 +344,8 @@ int ufs_add_link(struct dentry *dentry, 
if ((char *)de == dir_end) {
/* We hit i_size */
name_len = 0;
-   rec_len = UFS_SECTOR_SIZE;
-   de->d_reclen = cpu_to_fs16(sb, UFS_SECTOR_SIZE);
+   rec_len = chunk_size;
+   de->d_reclen = cpu_to_fs16(sb, chunk_size);
de->d_ino = 0;
goto got_it;
}
@@ -431,7 +433,7 @@ ufs_readdir(struct file *filp, void *dir
unsigned int offset = pos & ~PAGE_CACHE_MASK;
unsigned long n = pos >> PAGE_CACHE_SHIFT;
unsigned long npages = ufs_dir_pages(inode);
-   unsigned chunk_mask = ~(UFS_SECTOR_SIZE - 1);
+   unsigned chunk_mask = ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1);
int need_revalidate = filp->f_version != inode->i_version;
unsigned flags = UFS_SB(sb)->s_flags;
 
@@ -511,7 +513,7 @@ int ufs_delete_entry(struct inode *inode
struct super_block *sb = inode->i_sb;
struct address_space *mapping = page->mapping;
char *kaddr = page_address(page);
-   unsigned from = ((char*)dir - kaddr) & ~(UFS_SECTOR_SIZE - 1);
+   unsigned from = ((char*)dir - kaddr) & 
~(UFS_SB(sb)->s_uspi->s_dirblksize - 1);
unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen);
struct ufs_dir_entry *pde = NULL;
struct ufs_dir_entry *de = (struct ufs_dir_entry *) (kaddr + from);
@@ -556,6 +558,7 @@ int ufs_make_empty(struct inode * inode,
struct super_block * sb = dir->i_sb;
struct address_space *mapping = inode->i_mapping;
struct page *page = grab_cache_page(mapping, 0);
+   const unsigned int chunk_size = UFS_SB(sb)->s_uspi->s_dirblksize;
struct ufs_dir_entry * de;
char *base;
int err;
@@ -563,7 +566,7 @@ int ufs_make_empty(struct inode * inode,
if (!page)
return -ENOMEM;
kmap(page);
-   err = mapping->a_ops->prepare_write(NULL, page, 0, UFS_SECTOR_SIZ

[PATCH] MAINTAINERS: ufs entry

2007-02-02 Thread Evgeniy Dushistov
Mark ufs file system as maintainable, and add me as maintainer,
to help people find appropriate person to assign bugs.

Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>

---

Index: linux-2.6.20-rc7/MAINTAINERS
===
--- linux-2.6.20-rc7.orig/MAINTAINERS
+++ linux-2.6.20-rc7/MAINTAINERS
@@ -3599,6 +3599,12 @@ M:   [EMAIL PROTECTED]
 W: http://uclinux-h8.sourceforge.jp/
 S: Supported
 
+UFS FILESYSTEM
+P: Evgeniy Dushistov
+M: [EMAIL PROTECTED]
+L: linux-kernel@vger.kernel.org
+S: Maintained
+
 USB DIAMOND RIO500 DRIVER
 P: Cesar Miquel
 M: [EMAIL PROTECTED]

-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: fs/ufs/inode.c:817: warning: array subscript is above array bounds

2007-02-01 Thread Evgeniy Dushistov
On Wed, Jan 31, 2007 at 01:24:32PM -0800, Andrew Morton wrote:
> On Wed, 31 Jan 2007 23:10:57 +0300
> "Tomasz Kvarsin" <[EMAIL PROTECTED]> wrote:
> 
> > d binderman wrote:
> > >Hello there,
> > >
> > >I just tried to compile Linux kernel 2.6.19.2 with the
> > >new GNU C compiler version 4.3 snapshot 20070126.
> > >
> > >The compiler said
> > >
> > >fs/ufs/inode.c:817: warning: array subscript is above array bounds
> > >
> > >The source code is
> > >
> > >for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++)
> > >ufs_inode->ui_u2.ui_addr.ui_db[i] = ufsi->i_u1.i_data[i];
> > >
> > >but
> > >
> > >./include/linux/ufs_fs.h:   __fs32  
> > >ui_db[UFS_NDADDR];/*
> > >0x28 data blocks */
> > >./include/linux/ufs_fs.h:   __fs64
> > >ui_db[UFS_NDADDR]; /* 112: Direct disk blocks. */
> > >
> > >and
> > >
> > >__fs32  i_data[15];
> > >
> > >and
> > >
> > >#define UFS_NDADDR 12
> > >#define UFS_NINDIR 3
> > >
> > >so the kernel seems to be trying to write fifteen bytes into an array only
> > >twelve
> > >bytes in size. Suggest code rework.

Actually, this is not a _real_ bug,
yes, 
for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++)
ufs_inode->ui_u2.ui_addr.ui_db[i]

and ui_db only ui_db[UFS_NDADDR], but if look on more high level,
then:
union {
struct {
 __fs64 ui_db[UFS_NDADDR]; /* 112: Direct disk blocks. */
  __fs64 ui_ib[UFS_NINDIR];/* 208: Indirect disk blocks.*/
} ui_addr;
} ui_u2;

have no idea, why array splited on two parts,
may be some macros used this feature.

-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC] [PATCH 3/3] ufs2 write: block allocation update

2007-01-29 Thread Evgeniy Dushistov
Patch adds ability to work with 64bit metadata,
this made by replacing work with 32bit pointers by
inline functions.

Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>

---

Index: linux-2.6.20-rc5/fs/ufs/balloc.c
===
--- linux-2.6.20-rc5.orig/fs/ufs/balloc.c
+++ linux-2.6.20-rc5/fs/ufs/balloc.c
@@ -4,6 +4,8 @@
  * Copyright (C) 1998
  * Daniel Pirkl <[EMAIL PROTECTED]>
  * Charles University, Faculty of Mathematics and Physics
+ *
+ * UFS2 write support Evgeniy Dushistov <[EMAIL PROTECTED]>, 2007
  */
 
 #include 
@@ -21,38 +23,42 @@
 #include "swab.h"
 #include "util.h"
 
-static unsigned ufs_add_fragments (struct inode *, unsigned, unsigned, 
unsigned, int *);
-static unsigned ufs_alloc_fragments (struct inode *, unsigned, unsigned, 
unsigned, int *);
-static unsigned ufs_alloccg_block (struct inode *, struct ufs_cg_private_info 
*, unsigned, int *);
-static unsigned ufs_bitmap_search (struct super_block *, struct 
ufs_cg_private_info *, unsigned, unsigned);
+#define INVBLOCK ((u64)-1L)
+
+static u64 ufs_add_fragments(struct inode *, u64, unsigned, unsigned, int *);
+static u64 ufs_alloc_fragments(struct inode *, unsigned, u64, unsigned, int *);
+static u64 ufs_alloccg_block(struct inode *, struct ufs_cg_private_info *, 
u64, int *);
+static u64 ufs_bitmap_search (struct super_block *, struct ufs_cg_private_info 
*, u64, unsigned);
 static unsigned char ufs_fragtable_8fpb[], ufs_fragtable_other[];
 static void ufs_clusteracct(struct super_block *, struct ufs_cg_private_info 
*, unsigned, int);
 
 /*
  * Free 'count' fragments from fragment number 'fragment'
  */
-void ufs_free_fragments(struct inode *inode, unsigned fragment, unsigned count)
+void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count)
 {
struct super_block * sb;
struct ufs_sb_private_info * uspi;
struct ufs_super_block_first * usb1;
struct ufs_cg_private_info * ucpi;
struct ufs_cylinder_group * ucg;
-   unsigned cgno, bit, end_bit, bbase, blkmap, i, blkno, cylno;
+   unsigned cgno, bit, end_bit, bbase, blkmap, i;
+   u64 blkno;

sb = inode->i_sb;
uspi = UFS_SB(sb)->s_uspi;
usb1 = ubh_get_usb_first(uspi);

-   UFSD("ENTER, fragment %u, count %u\n", fragment, count);
+   UFSD("ENTER, fragment %llu, count %u\n",
+(unsigned long long)fragment, count);

if (ufs_fragnum(fragment) + count > uspi->s_fpg)
ufs_error (sb, "ufs_free_fragments", "internal error");

lock_super(sb);

-   cgno = ufs_dtog(fragment);
-   bit = ufs_dtogd(fragment);
+   cgno = ufs_dtog(uspi, fragment);
+   bit = ufs_dtogd(uspi, fragment);
if (cgno >= uspi->s_ncg) {
ufs_panic (sb, "ufs_free_fragments", "freeing blocks are 
outside device");
goto failed;
@@ -101,9 +107,13 @@ void ufs_free_fragments(struct inode *in
fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1);
uspi->cs_total.cs_nbfree++;
fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1);
-   cylno = ufs_cbtocylno (bbase);
-   fs16_add(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(bbase)), 1);
-   fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1);
+   if (uspi->fs_magic != UFS2_MAGIC) {
+   unsigned cylno = ufs_cbtocylno (bbase);
+
+   fs16_add(sb, &ubh_cg_blks(ucpi, cylno,
+ ufs_cbtorpos(bbase)), 1);
+   fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1);
+   }
}

ubh_mark_buffer_dirty (USPI_UBH(uspi));
@@ -127,24 +137,27 @@ failed:
 /*
  * Free 'count' fragments from fragment number 'fragment' (free whole blocks)
  */
-void ufs_free_blocks(struct inode *inode, unsigned fragment, unsigned count)
+void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count)
 {
struct super_block * sb;
struct ufs_sb_private_info * uspi;
struct ufs_super_block_first * usb1;
struct ufs_cg_private_info * ucpi;
struct ufs_cylinder_group * ucg;
-   unsigned overflow, cgno, bit, end_bit, blkno, i, cylno;
+   unsigned overflow, cgno, bit, end_bit, i;
+   u64 blkno;

sb = inode->i_sb;
uspi = UFS_SB(sb)->s_uspi;
usb1 = ubh_get_usb_first(uspi);
 
-   UFSD("ENTER, fragment %u, count %u\n", fragment, count);
+   UFSD("ENTER, fragment %llu, count %u\n",
+(unsigned long long)fragment, count);

if ((fragment & uspi->s_fpbmask) || (count & uspi->s_fpbmask)) {
ufs_erro

[RFC] [PATCH 1/3] ufs2 write: mount as rw

2007-01-29 Thread Evgeniy Dushistov
These series of patches add UFS2 write-support.
UFS2 - is default file system for recent versions of FreeBSD.

The main differences from UFS1 from write support point of view
are:
1)Not all inodes are allocated during formatation of disk.
2)All meta-data(pointer to data blocks) are 64bit(in UFS1 they
are 32bit).

So patch series consist of
1)make possible mount UFS2 in read-write mode
2)code to write ufs2 inodes and code to initialize inodes chunks.
3)work with 64bit meta-data

I made simple testing like create/deleting/writing/reading/truncating,
also I ran fsx-linux and untar and build kernel on UFS1 and UFS2,
after that FreeBSD fsck do not find any errors in fs.

This patch makes possible to mount ufs2 "rw", and updates
UFS2 documentation: remove note about bug(it fixed by reallocate
blocks on the fly patch) and add me in the list of people who
want receive bug reports.

Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>

---

Index: linux-2.6.20-rc5/fs/ufs/super.c
===
--- linux-2.6.20-rc5.orig/fs/ufs/super.c
+++ linux-2.6.20-rc5/fs/ufs/super.c
@@ -61,6 +61,8 @@
  * UFS2 (of FreeBSD 5.x) support added by
  * Niraj Kumar <[EMAIL PROTECTED]>, Jan 2004
  *
+ * UFS2 write support added by
+ * Evgeniy Dushistov <[EMAIL PROTECTED]>, 2007
  */
 
 
@@ -674,10 +676,6 @@ static int ufs_fill_super(struct super_b
uspi->s_sbsize = super_block_size = 1536;
uspi->s_sbbase =  0;
flags |= UFS_TYPE_UFS2 | UFS_DE_44BSD | UFS_UID_44BSD | 
UFS_ST_44BSD | UFS_CG_44BSD;
-   if (!(sb->s_flags & MS_RDONLY)) {
-   printk(KERN_INFO "ufstype=ufs2 is supported 
read-only\n");
-   sb->s_flags |= MS_RDONLY;
-   }
break;

case UFS_MOUNT_UFSTYPE_SUN:
@@ -1153,7 +1151,8 @@ static int ufs_remount (struct super_blo
 #else
if (ufstype != UFS_MOUNT_UFSTYPE_SUN && 
ufstype != UFS_MOUNT_UFSTYPE_44BSD &&
-   ufstype != UFS_MOUNT_UFSTYPE_SUNx86) {
+   ufstype != UFS_MOUNT_UFSTYPE_SUNx86 &&
+   ufstype != UFS_MOUNT_UFSTYPE_UFS2) {
printk("this ufstype is read-only supported\n");
return -EINVAL;
}
Index: linux-2.6.20-rc5/Documentation/filesystems/ufs.txt
===
--- linux-2.6.20-rc5.orig/Documentation/filesystems/ufs.txt
+++ linux-2.6.20-rc5/Documentation/filesystems/ufs.txt
@@ -21,7 +21,7 @@ ufstype=type_of_ufs
supported as read-write
 
ufs2used in FreeBSD 5.x
-   supported as read-only
+   supported as read-write
 
5xbsd   synonym for ufs2
 
@@ -50,12 +50,11 @@ ufstype=type_of_ufs
 POSSIBLE PROBLEMS
 =
 
-There is still bug in reallocation of fragment, in file fs/ufs/balloc.c, 
-line 364. But it seems working on current buffer cache configuration.
+See next section, if you have any.
 
 
 BUG REPORTS
 ===
 
-Any ufs bug report you can send to [EMAIL PROTECTED] (do not send 
-partition tables bug reports.)
+Any ufs bug report you can send to [EMAIL PROTECTED] or
+to [EMAIL PROTECTED] (do not send partition tables bug reports).
-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC] [PATCH 2/3] ufs2 write: inodes write

2007-01-29 Thread Evgeniy Dushistov
This patch adds into write inode path function to write
UFS2 inode,
and modifys allocate inode path to allocate and init additional
inode chunks.

Also some cleanups:
- remove not used parameters in some functions
- remove i_gen field from ufs_inode_info structure,
there is i_generation in inode structure with same purposes.

Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>

---

Index: linux-2.6.20-rc5/fs/ufs/inode.c
===
--- linux-2.6.20-rc5.orig/fs/ufs/inode.c
+++ linux-2.6.20-rc5/fs/ufs/inode.c
@@ -616,8 +616,8 @@ static void ufs1_read_inode(struct inode
inode->i_atime.tv_nsec = 0;
inode->i_ctime.tv_nsec = 0;
inode->i_blocks = fs32_to_cpu(sb, ufs_inode->ui_blocks);
+   inode->i_generation = fs32_to_cpu(sb, ufs_inode->ui_gen);
ufsi->i_flags = fs32_to_cpu(sb, ufs_inode->ui_flags);
-   ufsi->i_gen = fs32_to_cpu(sb, ufs_inode->ui_gen);
ufsi->i_shadow = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_shadow);
ufsi->i_oeftflag = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_oeftflag);
 
@@ -661,8 +661,8 @@ static void ufs2_read_inode(struct inode
inode->i_atime.tv_nsec = 0;
inode->i_ctime.tv_nsec = 0;
inode->i_blocks = fs64_to_cpu(sb, ufs2_inode->ui_blocks);
+   inode->i_generation = fs32_to_cpu(sb, ufs2_inode->ui_gen);
ufsi->i_flags = fs32_to_cpu(sb, ufs2_inode->ui_flags);
-   ufsi->i_gen = fs32_to_cpu(sb, ufs2_inode->ui_gen);
/*
ufsi->i_shadow = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_shadow);
ufsi->i_oeftflag = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_oeftflag);
@@ -731,34 +731,11 @@ bad_inode:
make_bad_inode(inode);
 }
 
-static int ufs_update_inode(struct inode * inode, int do_sync)
+static void ufs1_update_inode(struct inode *inode, struct ufs_inode *ufs_inode)
 {
-   struct ufs_inode_info *ufsi = UFS_I(inode);
-   struct super_block * sb;
-   struct ufs_sb_private_info * uspi;
-   struct buffer_head * bh;
-   struct ufs_inode * ufs_inode;
-   unsigned i;
-   unsigned flags;
-
-   UFSD("ENTER, ino %lu\n", inode->i_ino);
-
-   sb = inode->i_sb;
-   uspi = UFS_SB(sb)->s_uspi;
-   flags = UFS_SB(sb)->s_flags;
-
-   if (inode->i_ino < UFS_ROOTINO || 
-   inode->i_ino > (uspi->s_ncg * uspi->s_ipg)) {
-   ufs_warning (sb, "ufs_read_inode", "bad inode number (%lu)\n", 
inode->i_ino);
-   return -1;
-   }
-
-   bh = sb_bread(sb, ufs_inotofsba(inode->i_ino));
-   if (!bh) {
-   ufs_warning (sb, "ufs_read_inode", "unable to read inode 
%lu\n", inode->i_ino);
-   return -1;
-   }
-   ufs_inode = (struct ufs_inode *) (bh->b_data + 
ufs_inotofsbo(inode->i_ino) * sizeof(struct ufs_inode));
+   struct super_block *sb = inode->i_sb;
+   struct ufs_inode_info *ufsi = UFS_I(inode);
+   unsigned i;
 
ufs_inode->ui_mode = cpu_to_fs16(sb, inode->i_mode);
ufs_inode->ui_nlink = cpu_to_fs16(sb, inode->i_nlink);
@@ -775,9 +752,9 @@ static int ufs_update_inode(struct inode
ufs_inode->ui_mtime.tv_usec = 0;
ufs_inode->ui_blocks = cpu_to_fs32(sb, inode->i_blocks);
ufs_inode->ui_flags = cpu_to_fs32(sb, ufsi->i_flags);
-   ufs_inode->ui_gen = cpu_to_fs32(sb, ufsi->i_gen);
+   ufs_inode->ui_gen = cpu_to_fs32(sb, inode->i_generation);
 
-   if ((flags & UFS_UID_MASK) == UFS_UID_EFT) {
+   if ((UFS_SB(sb)->s_flags & UFS_UID_MASK) == UFS_UID_EFT) {
ufs_inode->ui_u3.ui_sun.ui_shadow = cpu_to_fs32(sb, 
ufsi->i_shadow);
ufs_inode->ui_u3.ui_sun.ui_oeftflag = cpu_to_fs32(sb, 
ufsi->i_oeftflag);
}
@@ -796,6 +773,78 @@ static int ufs_update_inode(struct inode
 
if (!inode->i_nlink)
memset (ufs_inode, 0, sizeof(struct ufs_inode));
+}
+
+static void ufs2_update_inode(struct inode *inode, struct ufs2_inode 
*ufs_inode)
+{
+   struct super_block *sb = inode->i_sb;
+   struct ufs_inode_info *ufsi = UFS_I(inode);
+   unsigned i;
+
+   UFSD("ENTER\n");
+   ufs_inode->ui_mode = cpu_to_fs16(sb, inode->i_mode);
+   ufs_inode->ui_nlink = cpu_to_fs16(sb, inode->i_nlink);
+
+   ufs_inode->ui_uid = cpu_to_fs32(sb, inode->i_uid);
+   ufs_inode->ui_gid = cpu_to_fs32(sb, inode->i_gid);
+
+   ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size);
+   ufs_inode->ui_atime.tv_sec = cpu_to_fs32(sb, inode->i_atime.tv_sec);
+   ufs_inode->ui_atime.tv_usec = 0;
+   ufs_inode->ui_ctime.tv_sec = cpu_to_fs32(sb, inode->i_ctime.tv_sec);
+   ufs_inode->ui_ctime.tv_usec =

Re: [PATCH 3/3] ufs: rellocation fix

2007-01-25 Thread Evgeniy Dushistov
On Wed, Jan 24, 2007 at 08:21:07PM -0800, Andrew Morton wrote:
> On Mon, 22 Jan 2007 18:07:51 +0300
> Evgeniy Dushistov <[EMAIL PROTECTED]> wrote:
> 
> > -   for (i = 0; i < count; i += blk_per_page) {
> > +   for (i = 0; i < count; i = (i | mask) + 1) {
> 
> This is a funny looking thing.  As far as I can tell, this is a more
> complicated way of doing the same thing as the old code did.
> 
> Am I missing something?
> 

No, you right, thanks, work should be done with baseblk+i, not with i.
(It is imposible to catch on my test enviroment: size of page 4096
and baseblk always point to begin of data block which size of 
>=4096 and power of 2).

Here is patch for patch, it also contains typo fixing in previous
patch which lead to compilation failure if ufs debug turn on.

May be it is possible to integrate this patch into previous one,
or resend new version of last patch?

---

Index: linux-2.6.20-rc5/fs/ufs/balloc.c
===
--- linux-2.6.20-rc5.orig/fs/ufs/balloc.c
+++ linux-2.6.20-rc5/fs/ufs/balloc.c
@@ -227,14 +227,14 @@ failed:
  * We can come here from ufs_writepage or ufs_prepare_write,
  * locked_page is argument of these functions, so we already lock it.
  */
-static void ufs_change_blocknr(struct inode *inode, unsigned int baseblk,
+static void ufs_change_blocknr(struct inode *inode, unsigned int beg,
   unsigned int count, unsigned int oldb,
   unsigned int newb, struct page *locked_page)
 {
const unsigned mask = (1 << (PAGE_CACHE_SHIFT - inode->i_blkbits)) - 1;
struct address_space * const mapping = inode->i_mapping;
pgoff_t index, cur_index;
-   unsigned i, pos, j;
+   unsigned end, pos, j;
struct page *page;
struct buffer_head *head, *bh;
 
@@ -246,8 +246,8 @@ static void ufs_change_blocknr(struct in
 
cur_index = locked_page->index;
 
-   for (i = 0; i < count; i = (i | mask) + 1) {
-   index = (baseblk+i) >> (PAGE_CACHE_SHIFT - inode->i_blkbits);
+   for (end = count + beg; beg < end; beg = (beg | mask) + 1) {
+   index = beg >> (PAGE_CACHE_SHIFT - inode->i_blkbits);
 
if (likely(cur_index != index)) {
page = ufs_get_locked_page(mapping, index);
@@ -258,7 +258,7 @@ static void ufs_change_blocknr(struct in
 
head = page_buffers(page);
bh = head;
-   pos = i & mask;
+   pos = beg & mask;
for (j = 0; j < pos; ++j)
bh = bh->b_this_page;
j = 0;
@@ -267,7 +267,7 @@ static void ufs_change_blocknr(struct in
pos = bh->b_blocknr - oldb;
if (pos < count) {
UFSD(" change from %llu to %llu\n",
-(unsigned long long)pos + odlb,
+(unsigned long long)pos + oldb,
 (unsigned long long)pos + newb);
bh->b_blocknr = newb + pos;
unmap_underlying_metadata(bh->b_bdev,

-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/3] ufs: rellocation fix

2007-01-22 Thread Evgeniy Dushistov
In blocks reallocation function sometimes does not update some
of buffer_head::b_blocknr, which may and cause data damage.

Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>

---

Index: linux-2.6.20-rc5/fs/ufs/balloc.c
===
--- linux-2.6.20-rc5.orig/fs/ufs/balloc.c
+++ linux-2.6.20-rc5/fs/ufs/balloc.c
@@ -231,10 +231,10 @@ static void ufs_change_blocknr(struct in
   unsigned int count, unsigned int oldb,
   unsigned int newb, struct page *locked_page)
 {
-   unsigned int blk_per_page = 1 << (PAGE_CACHE_SHIFT - inode->i_blkbits);
-   struct address_space *mapping = inode->i_mapping;
+   const unsigned mask = (1 << (PAGE_CACHE_SHIFT - inode->i_blkbits)) - 1;
+   struct address_space * const mapping = inode->i_mapping;
pgoff_t index, cur_index;
-   unsigned int i, j;
+   unsigned i, pos, j;
struct page *page;
struct buffer_head *head, *bh;
 
@@ -246,7 +246,7 @@ static void ufs_change_blocknr(struct in
 
cur_index = locked_page->index;
 
-   for (i = 0; i < count; i += blk_per_page) {
+   for (i = 0; i < count; i = (i | mask) + 1) {
index = (baseblk+i) >> (PAGE_CACHE_SHIFT - inode->i_blkbits);
 
if (likely(cur_index != index)) {
@@ -256,21 +256,32 @@ static void ufs_change_blocknr(struct in
} else
page = locked_page;
 
-   j = i;
head = page_buffers(page);
bh = head;
+   pos = i & mask;
+   for (j = 0; j < pos; ++j)
+   bh = bh->b_this_page;
+   j = 0;
do {
-   if (likely(bh->b_blocknr == j + oldb && j < count)) {
-   unmap_underlying_metadata(bh->b_bdev,
- bh->b_blocknr);
-   bh->b_blocknr = newb + j++;
-   mark_buffer_dirty(bh);
+   if (buffer_mapped(bh)) {
+   pos = bh->b_blocknr - oldb;
+   if (pos < count) {
+   UFSD(" change from %llu to %llu\n",
+(unsigned long long)pos + odlb,
+(unsigned long long)pos + newb);
+   bh->b_blocknr = newb + pos;
+   unmap_underlying_metadata(bh->b_bdev,
+ 
bh->b_blocknr);
+   mark_buffer_dirty(bh);
+   ++j;
+   }
}
 
bh = bh->b_this_page;
} while (bh != head);
 
-   set_page_dirty(page);
+   if (j)
+   set_page_dirty(page);
 
if (likely(cur_index != index))
ufs_put_locked_page(page);
@@ -418,14 +429,14 @@ unsigned ufs_new_fragments(struct inode 
}
result = ufs_alloc_fragments (inode, cgno, goal, request, err);
if (result) {
+   ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
+   locked_page != NULL);
ufs_change_blocknr(inode, fragment - oldcount, oldcount, tmp,
   result, locked_page);
 
*p = cpu_to_fs32(sb, result);
*err = 0;
UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, 
fragment + count);
-   ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
-   locked_page != NULL);
unlock_super(sb);
if (newcount < request)
ufs_free_fragments (inode, result + newcount, request - 
newcount);
-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/3] ufs: truncate negative to unsigned fix

2007-01-22 Thread Evgeniy Dushistov

During ufs_trunc_direct which is subroutine of ufs::truncate,
we try the first of all free parts of block and then whole blocks.
But we calculate size of block's part to free in the wrong way.

This may cause bad update of used blocks and fragments statistic,
and you can got report that you have free 32T on 1Gb partition.

Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>

---

Index: linux-2.6.20-rc5/fs/ufs/truncate.c
===
--- linux-2.6.20-rc5.orig/fs/ufs/truncate.c
+++ linux-2.6.20-rc5/fs/ufs/truncate.c
@@ -109,10 +109,10 @@ static int ufs_trunc_direct (struct inod
tmp = fs32_to_cpu(sb, *p);
if (!tmp )
ufs_panic (sb, "ufs_trunc_direct", "internal error");
+   frag2 -= frag1;
frag1 = ufs_fragnum (frag1);
-   frag2 = ufs_fragnum (frag2);
 
-   ufs_free_fragments (inode, tmp + frag1, frag2 - frag1);
+   ufs_free_fragments(inode, tmp + frag1, frag2);
mark_inode_dirty(inode);
frag_to_free = tmp + frag1;
 
-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3]: ufs: alloc metadata null page fix

2007-01-22 Thread Evgeniy Dushistov
These series of patches result of 
UFS1 write support stress testing, like running
fsx-linux, untar and build linux kernel etc


We pass from ufs::get_block_t to levels below:
pointer to the current page, to make possible things like
reallocation of blocks on the fly, and we also uses this pointer
for indication, what actually we allocate data block or 
meta data block,
but currently we make decision about what we allocate on
the wrong level, this may and cause oops if we allocate
blocks in some special order.

Signed-off-by: Evgeniy Dushistov <[EMAIL PROTECTED]>
  

  
--- 

Index: linux-2.6.20-rc5/fs/ufs/balloc.c
===
--- linux-2.6.20-rc5.orig/fs/ufs/balloc.c
+++ linux-2.6.20-rc5/fs/ufs/balloc.c
@@ -233,7 +233,7 @@ static void ufs_change_blocknr(struct in
 {
unsigned int blk_per_page = 1 << (PAGE_CACHE_SHIFT - inode->i_blkbits);
struct address_space *mapping = inode->i_mapping;
-   pgoff_t index, cur_index = locked_page->index;
+   pgoff_t index, cur_index;
unsigned int i, j;
struct page *page;
struct buffer_head *head, *bh;
@@ -241,8 +241,11 @@ static void ufs_change_blocknr(struct in
UFSD("ENTER, ino %lu, count %u, oldb %u, newb %u\n",
  inode->i_ino, count, oldb, newb);
 
+   BUG_ON(!locked_page);
BUG_ON(!PageLocked(locked_page));
 
+   cur_index = locked_page->index;
+
for (i = 0; i < count; i += blk_per_page) {
index = (baseblk+i) >> (PAGE_CACHE_SHIFT - inode->i_blkbits);
 
Index: linux-2.6.20-rc5/fs/ufs/inode.c
===
--- linux-2.6.20-rc5.orig/fs/ufs/inode.c
+++ linux-2.6.20-rc5/fs/ufs/inode.c
@@ -242,7 +242,8 @@ repeat:
goal = tmp + uspi->s_fpb;
tmp = ufs_new_fragments (inode, p, fragment - blockoff, 
 goal, required + blockoff,
-err, locked_page);
+err,
+phys != NULL ? locked_page : NULL);
}
/*
 * We will extend last allocated block
@@ -250,7 +251,7 @@ repeat:
else if (lastblock == block) {
tmp = ufs_new_fragments(inode, p, fragment - (blockoff - 
lastblockoff),
fs32_to_cpu(sb, *p), required +  
(blockoff - lastblockoff),
-   err, locked_page);
+   err, phys != NULL ? locked_page : NULL);
} else /* (lastblock > block) */ {
/*
 * We will allocate new block before last allocated block
@@ -261,7 +262,8 @@ repeat:
goal = tmp + uspi->s_fpb;
}
tmp = ufs_new_fragments(inode, p, fragment - blockoff,
-   goal, uspi->s_fpb, err, locked_page);
+   goal, uspi->s_fpb, err,
+   phys != NULL ? locked_page : NULL);
}
if (!tmp) {
if ((!blockoff && *p) || 
@@ -438,9 +440,11 @@ int ufs_getfrag_block(struct inode *inod
 * it much more readable:
 */
 #define GET_INODE_DATABLOCK(x) \
-   ufs_inode_getfrag(inode, x, fragment, 1, &err, &phys, &new, 
bh_result->b_page)
+   ufs_inode_getfrag(inode, x, fragment, 1, &err, &phys, &new,\
+ bh_result->b_page)
 #define GET_INODE_PTR(x) \
-   ufs_inode_getfrag(inode, x, fragment, uspi->s_fpb, &err, NULL, NULL, 
NULL)
+   ufs_inode_getfrag(inode, x, fragment, uspi->s_fpb, &err, NULL, NULL,\
+ bh_result->b_page)
 #define GET_INDIRECT_DATABLOCK(x) \
ufs_inode_getblock(inode, bh, x, fragment,  \
  &err, &phys, &new, bh_result->b_page)
-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [BUG] [PATCH] [RFC] garbage instead of zeroes in UFS

2006-12-28 Thread Evgeniy Dushistov
[sorry for delay with answer]

On Wed, Dec 20, 2006 at 09:35:55PM -0800, Andrew Morton wrote:
> I know nothing of UFS, but here goes..
> 
> > Looks like this is the problem, which point Al Viro some time ago:
> > when we allocate block(in this situation 16K) we mark as new
> > only one fragment(in this situation 2K), 
> 
> Do you mean:
> 
>  ufs's get_block callback allocates 16k of disk at a time, and links that
>  entire 16k into the file's metadata.  But because get_block is called for
>  only a single buffer_head (a 2k buffer_head in this case?) we are only
>  able to tell the VFS that this 2k is buffer_new().
> 
>  So when ufs_getfrag_block() is later called to map some more data in the
>  file, and when that data resides within the remaining 14k of this
>  fragment, ufs_getfrag_block() will incorrectly return a !buffer_new()
>  buffer_head.
> 
Yes.

> If that is correct, it seems like a fairly easy-to-trigger bug.  Perhaps
> it only happens when we're filling in file holes for some reason?
> 
when we filling file hole with size >=16K(in this case),
or extend big enough file(big - we use indirect, double indirect and so
on blocks).

> Or perhaps this bad data can be accessed simply by extending the file with
> ftruncate and then reading shortly beyond the previous end-of-file?
> 
> > I don't see _right_ way to do nullification of whole block,
> > if use inode page cache, some pages may be outside of inode limits
> > (inode size),
> > and will be lost;
> 
> Using the per-inode pagecache is certainly more efficient than perfroming
> synchronous writes via blockdev pagecache and then reading the blocks back
> into the inode pagecache!
> 
> It'd be fairly straightforward to do this for blocks which are inside
> i_size (ie: filling in file holes): populate pagecache, zero it, mark it
> dirty.
> 
> For pages which are presently outside i_size things are a bit more risky -
> they're not really legal and can't in theory be written out.  Or might not
> be written out.  Although from a quick look at the writeback code, it might
> all just work.
> 
> However a cleaner solution might be to remember, on a per-inode basis, what
> the filesystem's view is of the current file size.  Then implement
> inode_operations.setattr() and if someone extends the file, we know that
> this will expose the uninitialised blocks outside the old file-size to
> reads, so now is the time to instantiate that dirty, zero-filled pagecache
> to cover the tail of the last fragment.
> 
> Is all a bit tricky.
> 

I see the two places:
inode_ops.setattr and
address_space_operations.commit_write,
where inode size can be changed, and we should say
"hey, we have pages outside of inode lets fill them with zeroes".

But there is one problem, as can I see(may be I missed something?):
functions from ufs address_space_operations like prepare_write,
writepage are called with page in locked state,
and deadlock may appear, when for example msync will be called
for page "0" and another msync will be called for page "1",
and prepare_write for "0" will try nullify pages "0", "1", "2" and "3"
(The similar code[populate cache and modify pages],
used for reallocate fragments, but due to nature of ufs such situation
is impossible).

So it will be funny implement, debug and use such code.

> > if use blockdev page cache it is possible to zeroize real data,
> > if later inode page cache will be used.
> > 
> > The simpliest way, as can I see usage of block device page cache,
> > but not only mark dirty, but also sync it during "nullification".
> 
> That'll work.  How bad is this change from a performance point-of-view?

You suggest any particular benchmark?
I use my simple tests collection, which I used for check
that create,open,write,read,close works on ufs, and I see that
this patch makes ufs code 18% slower then before.

-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [BUG] [PATCH] [RFC] garbage instead of zeroes in UFS

2006-12-20 Thread Evgeniy Dushistov
On Wed, Dec 20, 2006 at 03:09:55AM -0800, Andrew Morton wrote:
> On Wed, 20 Dec 2006 14:04:06 +0300
> "Tomasz Kvarsin" <[EMAIL PROTECTED]> wrote:
> 
> > Forgot to say I use linux-2.6.20-rc1-mm1
> > 
> > On 12/20/06, Tomasz Kvarsin <[EMAIL PROTECTED]> wrote:
> > > I have some problems with write support of UFS.
> > > Here is script which demonstrate problem:
> > >
> > > #create image
> > > mkdir /tmp/ufs-expirements && cd /tmp/ufs-expirements/
> > > for ((i=0; i<1024*1024*2; ++i)); do printf "z"; done > image
> > >
> > > #build ufs tools
> > > wget 
> > > 'http://heanet.dl.sourceforge.net/sourceforge/ufs-linux/ufs-tools-0.1.tar.bz2'
> > > && tar xjf ufs-tools-0.1.tar.bz2 && cd ufs-tools-0.1
> > > wget http://lkml.org/lkml/diff/2006/5/20/48/1 -O build.patch
> > > patch -p1 < build.patch && make
> > >
> > > #create UFS file system on image
> > > ./mkufs -O 1 -b 16384 -f 2048 ../image
> > > cd .. && mkdir root
> > > mount -t ufs image root -o loop,ufstype=44bsd
> > > cd root/
> > > touch a.txt
> > > echo "END" > end.txt
> > > dd if=./end.txt of=./a.txt bs=16384 seek=1
> > >
> > > and at the end content of "a.txt" not only  "END" and zeroes,
> > > "a.txt" also contains "z".
> > >
> > > The real situation happened when I deleted big file,
> > > and create new one with holes. This script just easy way to reproduce bug.
> > >
> 
> Does 2.6.20-rc1 have the same problem?

Looks like this is the problem, which point Al Viro some time ago:
when we allocate block(in this situation 16K) we mark as new
only one fragment(in this situation 2K), 
I don't see _right_ way to do nullification of whole block,
if use inode page cache, some pages may be outside of inode limits
(inode size),
and will be lost;
if use blockdev page cache it is possible to zeroize real data,
if later inode page cache will be used.

The simpliest way, as can I see usage of block device page cache,
but not only mark dirty, but also sync it during "nullification".

Patch bellow properly handle Tomasz's test case for me(Tomasz can you try it?),
but I am not sure is this _right_ solution.
Any ideas?

---

Index: linux-2.6.20-rc1-mm1/fs/ufs/inode.c
===
--- linux-2.6.20-rc1-mm1.orig/fs/ufs/inode.c
+++ linux-2.6.20-rc1-mm1/fs/ufs/inode.c
@@ -156,36 +156,6 @@ out:
return ret;
 }
 
-static void ufs_clear_frag(struct inode *inode, struct buffer_head *bh)
-{
-   lock_buffer(bh);
-   memset(bh->b_data, 0, inode->i_sb->s_blocksize);
-   set_buffer_uptodate(bh);
-   mark_buffer_dirty(bh);
-   unlock_buffer(bh);
-   if (IS_SYNC(inode))
-   sync_dirty_buffer(bh);
-}
-
-static struct buffer_head *
-ufs_clear_frags(struct inode *inode, sector_t beg,
-   unsigned int n, sector_t want)
-{
-   struct buffer_head *res = NULL, *bh;
-   sector_t end = beg + n;
-
-   for (; beg < end; ++beg) {
-   bh = sb_getblk(inode->i_sb, beg);
-   ufs_clear_frag(inode, bh);
-   if (want != beg)
-   brelse(bh);
-   else
-   res = bh;
-   }
-   BUG_ON(!res);
-   return res;
-}
-
 /**
  * ufs_inode_getfrag() - allocate new fragment(s)
  * @inode - pointer to inode
@@ -302,7 +272,7 @@ repeat:
}
 
if (!phys) {
-   result = ufs_clear_frags(inode, tmp, required, tmp + blockoff);
+   result = sb_getblk(sb, tmp + blockoff);
} else {
*phys = tmp + blockoff;
result = NULL;
@@ -403,8 +373,7 @@ repeat:
 
 
if (!phys) {
-   result = ufs_clear_frags(inode, tmp, uspi->s_fpb,
-tmp + blockoff);
+   result = sb_getblk(sb, tmp + blockoff);
} else {
*phys = tmp + blockoff;
*new = 1;
@@ -471,13 +440,13 @@ int ufs_getfrag_block(struct inode *inod
 #define GET_INODE_DATABLOCK(x) \
ufs_inode_getfrag(inode, x, fragment, 1, &err, &phys, &new, 
bh_result->b_page)
 #define GET_INODE_PTR(x) \
-   ufs_inode_getfrag(inode, x, fragment, uspi->s_fpb, &err, NULL, NULL, 
bh_result->b_page)
+   ufs_inode_getfrag(inode, x, fragment, uspi->s_fpb, &err, NULL, NULL, 
NULL)
 #define GET_INDIRECT_DATABLOCK(x) \
ufs_inode_getblock(inode, bh, x, fragment,  \
- &err, &phys, &new, bh_result->b_page);
+ &err, &phys, &new, bh_result->b_page)
 #define GET_INDIRECT_PTR(x) \
ufs_inode_getblock(inode, bh, x, fragment,  \
- &err, NULL, NULL, bh_result->b_page);
+ &err, NULL, NULL, NULL)
 
if (ptr < UFS_NDIR_FRAGMENT) {
bh = GET_INODE_DATABLOCK(ptr);
Index: linux-2.6.20-rc1-mm1/fs/ufs/balloc.c
===
--- linux-2.6.20-rc1-mm1.orig/fs/ufs/balloc.c
+++ linux-2.6.20-rc1-mm1/fs/ufs/balloc.c
@@ -275,6 +275,25 @@ sta