Pushed to git, thanks

Jean-Pierre

Richard W.M. Jones wrote:
> However deny discard if the partition is not aligned to the underlying
> discard block size.
> ---
>   libntfs-3g/ioctl.c | 140 
> ++++++++++++++++++++++++++---------------------------
>   1 file changed, 68 insertions(+), 72 deletions(-)
>
> diff --git a/libntfs-3g/ioctl.c b/libntfs-3g/ioctl.c
> index bbbceb9..eb7c8e7 100644
> --- a/libntfs-3g/ioctl.c
> +++ b/libntfs-3g/ioctl.c
> @@ -66,8 +66,6 @@
>   #include <linux/fs.h>
>   #endif
>   
> -#include <dirent.h>
> -
>   #include "compat.h"
>   #include "debug.h"
>   #include "bitmap.h"
> @@ -135,17 +133,14 @@ static int read_u64(const char *path, u64 *n)
>   }
>   
>   /* Find discard limits for current backing device.
> - * XXX Kernel makes this a pain in the neck.
>    */
> -static int fstrim_limits(ntfs_volume *vol, u64 *discard_granularity,
> +static int fstrim_limits(ntfs_volume *vol,
> +                     u64 *discard_alignment,
> +                     u64 *discard_granularity,
>                       u64 *discard_max_bytes)
>   {
>       struct stat statbuf;
> -     DIR *dir;
> -     struct dirent *d;
> -     char path[80];
> -     char line[64];
> -     char dev[64];
> +     char path1[80], path2[80];
>       int ret;
>   
>       /* Stat the backing device.  Caller has ensured it is a block device. */
> @@ -155,82 +150,78 @@ static int fstrim_limits(ntfs_volume *vol, u64 
> *discard_granularity,
>               return -errno;
>       }
>   
> -     /* Now look for a /sys/block/<dev>/dev file which contains
> -      * "major:minor\n".
> +     /* For whole devices,
> +      * /sys/dev/block/MAJOR:MINOR/discard_alignment
> +      * /sys/dev/block/MAJOR:MINOR/queue/discard_granularity
> +      * /sys/dev/block/MAJOR:MINOR/queue/discard_max_bytes
> +      * will exist.
> +      * For partitions, we also need to check the parent device:
> +      * /sys/dev/block/MAJOR:MINOR/../queue/discard_granularity
> +      * /sys/dev/block/MAJOR:MINOR/../queue/discard_max_bytes
>        */
> -     snprintf(dev, sizeof dev, "%d:%d\n",
> +     snprintf(path1, sizeof path1, "/sys/dev/block/%d:%d",
>               major(statbuf.st_rdev), minor(statbuf.st_rdev));
>   
> -     dir = opendir("/sys/block");
> -     if (dir == NULL) {
> -             ntfs_log_debug("fstrim_limits: could not open /sys/block\n");
> -             return -errno;
> +     snprintf(path2, sizeof path2, "%s/discard_alignment", path1);
> +     ret = read_u64(path2, discard_alignment);
> +     if (ret) {
> +             if (ret != -ENOENT)
> +                     return ret;
> +             else
> +                     /* We would expect this file to exist on all
> +                      * modern kernels.  But for the sake of very
> +                      * old kernels:
> +                      */
> +                     goto not_found;
>       }
> -     for (;;) {
> -             errno = 0;
> -             d = readdir(dir);
> -             if (!d) break;
>   
> -             snprintf(path, sizeof path, "/sys/block/%s/dev", d->d_name);
> -             ret = read_line(path, line, sizeof line);
> -             if (ret)
> -                     continue;
> -             if (strcmp(line, dev) == 0)
> -                     goto found;
> +     snprintf(path2, sizeof path2, "%s/queue/discard_granularity", path1);
> +     ret = read_u64(path2, discard_granularity);
> +     if (ret) {
> +             if (ret != -ENOENT)
> +                     return ret;
> +             else {
> +                     snprintf(path2, sizeof path2,
> +                             "%s/../queue/discard_granularity", path1);
> +                     ret = read_u64(path2, discard_granularity);
> +                     if (ret) {
> +                             if (ret != -ENOENT)
> +                                     return ret;
> +                             else
> +                                     goto not_found;
> +                     }
> +             }
>       }
>   
> -     /* Check readdir didn't fail. */
> -     if (errno != 0) {
> -             ret = -errno;
> -             ntfs_log_debug("fstrim_limits: readdir failed\n");
> -             goto out;
> +     snprintf(path2, sizeof path2, "%s/queue/discard_max_bytes", path1);
> +     ret = read_u64(path2, discard_max_bytes);
> +     if (ret) {
> +             if (ret != -ENOENT)
> +                     return ret;
> +             else {
> +                     snprintf(path2, sizeof path2,
> +                             "%s/../queue/discard_max_bytes", path1);
> +                     ret = read_u64(path2, discard_max_bytes);
> +                     if (ret) {
> +                             if (ret != -ENOENT)
> +                                     return ret;
> +                             else
> +                                     goto not_found;
> +                     }
> +             }
>       }
>   
> +     return 0;
> +
> +not_found:
>       /* If we reach here then we didn't find the device.  This is
>        * not an error, but set discard_max_bytes = 0 to indicate
>        * that discard is not available.
>        */
> +     *discard_alignment = 0;
>       *discard_granularity = 0;
>       *discard_max_bytes = 0;
> -     ntfs_log_debug("fstrim_limits: /sys/block entry corresponding to device 
> %s not found\n",
> -             vol->dev->d_name);
> -     ret = 0;
> -     goto out;
> -
> -found:
> -     /* Found the device at /sys/block/ + d->d_name */
> -     snprintf (path, sizeof path,
> -             "/sys/block/%s/queue/discard_granularity",
> -             d->d_name);
> -     ret = read_u64(path, discard_granularity);
> -     if (ret) {
> -             ntfs_log_debug("fstrim_limits: could not read %s\n", path);
> -             goto out;
> -     }
> -
> -     snprintf (path, sizeof path,
> -             "/sys/block/%s/queue/discard_max_bytes",
> -             d->d_name);
> -     ret = read_u64(path, discard_max_bytes);
> -     if (ret) {
> -             ntfs_log_debug("fstrim_limits: could not read %s\n", path);
> -             goto out;
> -     }
> -
> -     ntfs_log_debug("fstrim_limits: device %s discard granularity = %llu 
> max_bytes = %llu\n",
> -             d->d_name,
> -             (unsigned long long) *discard_granularity,
> -             (unsigned long long) *discard_max_bytes);
> -
> -     ret = 0;
> -out:
> -     if (closedir (dir) == -1) {
> -             ret = -errno;
> -             ntfs_log_debug("fstrim_limits: closedir failed\n");
> -             return ret;
> -     }
> -
> -     return ret;
> +     return 0;
>   }
>   
>   #define FSTRIM_BUFSIZ 4096
> @@ -247,7 +238,7 @@ static int fstrim(ntfs_volume *vol, void *data)
>       u64 start = range->start;
>       u64 len = range->len;
>       u64 minlen = range->minlen;
> -     u64 discard_granularity, discard_max_bytes;
> +     u64 discard_alignment, discard_granularity, discard_max_bytes;
>       u8 *buf = NULL;
>       LCN start_buf;
>       int ret;
> @@ -279,9 +270,14 @@ static int fstrim(ntfs_volume *vol, void *data)
>               return -EOPNOTSUPP;
>       }
>   
> -     ret = fstrim_limits(vol, &discard_granularity, &discard_max_bytes);
> +     ret = fstrim_limits(vol, &discard_alignment,
> +                     &discard_granularity, &discard_max_bytes);
>       if (ret)
>               return ret;
> +     if (discard_alignment != 0) {
> +             ntfs_log_debug("fstrim: backing device is not aligned for 
> discards\n");
> +             return -EOPNOTSUPP;
> +     }
>       if (discard_granularity > vol->cluster_size) {
>               ntfs_log_debug("fstrim: discard granularity of backing device 
> is larger than cluster size\n");
>               return -EOPNOTSUPP;


------------------------------------------------------------------------------
Infragistics Professional
Build stunning WinForms apps today!
Reboot your WinForms applications with our WinForms controls. 
Build a bridge from your legacy apps to the future.
http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk
_______________________________________________
ntfs-3g-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ntfs-3g-devel

Reply via email to