Whamcloud - gitweb
LU-12447 utils: specify correct size for lfs project buffer
[fs/lustre-release.git] / lustre / utils / lfs_project.c
index a2e9eb2..f16d825 100644 (file)
@@ -69,16 +69,48 @@ lfs_project_item_alloc(struct list_head *head, const char *pathname)
                return -ENOMEM;
        }
 
-       strncpy(lpi->lpi_pathname, pathname, sizeof(lpi->lpi_pathname));
+       strncpy(lpi->lpi_pathname, pathname, sizeof(lpi->lpi_pathname) - 1);
        list_add_tail(&lpi->lpi_list, head);
 
        return 0;
 }
 
-static int project_get_xattr(const char *pathname, struct fsxattr *fsx)
+static const char *mode_to_type(mode_t mode)
+{
+       switch (mode & S_IFMT) {
+       case S_IFDIR:   return "dir";
+       case S_IFREG:   return "regular";
+       case S_IFLNK:   return "symlink";
+       case S_IFCHR:   return "char device";
+       case S_IFBLK:   return "block device";
+       case S_IFIFO:   return "fifo";
+       case S_IFSOCK:  return "sock";
+       }
+
+       return "unknown";
+}
+
+static int project_get_xattr(const char *pathname, struct fsxattr *fsx,
+                            struct stat *st)
 {
        int ret, fd;
 
+       ret = lstat(pathname, st);
+       if (ret) {
+               fprintf(stderr, "%s: failed to stat '%s': %s\n",
+                       progname, pathname, strerror(errno));
+               return -errno;
+       }
+
+       /* currently, only file and dir supported */
+       if (!S_ISREG(st->st_mode) && !S_ISDIR(st->st_mode)) {
+               errno = ENOTSUP;
+               fprintf(stderr, "%s: unable to get xattr for %s '%s': %s\n",
+                               progname, mode_to_type(st->st_mode), pathname,
+                               strerror(errno));
+               return -errno;
+       }
+
        fd = open(pathname, O_RDONLY | O_NOCTTY | O_NDELAY);
        if (fd < 0) {
                fprintf(stderr, "%s: failed to open '%s': %s\n",
@@ -90,6 +122,7 @@ static int project_get_xattr(const char *pathname, struct fsxattr *fsx)
        if (ret) {
                fprintf(stderr, "%s: failed to get xattr for '%s': %s\n",
                        progname, pathname, strerror(errno));
+               close(fd);
                return -errno;
        }
        return fd;
@@ -99,17 +132,10 @@ static int
 project_check_one(const char *pathname, struct project_handle_control *phc)
 {
        struct fsxattr fsx;
-       struct stat st;
        int ret;
+       struct stat st;
 
-       ret = stat(pathname, &st);
-       if (ret) {
-               fprintf(stderr, "%s: failed to stat '%s': %s\n",
-                       progname, pathname, strerror(errno));
-               return -errno;
-       }
-
-       ret = project_get_xattr(pathname, &fsx);
+       ret = project_get_xattr(pathname, &fsx, &st);
        if (ret < 0)
                return ret;
 
@@ -119,7 +145,8 @@ project_check_one(const char *pathname, struct project_handle_control *phc)
                phc->projid = fsx.fsx_projid;
        }
 
-       if (!(fsx.fsx_xflags & FS_XFLAG_PROJINHERIT)) {
+       if (!(fsx.fsx_xflags & FS_XFLAG_PROJINHERIT) &&
+           S_ISDIR(st.st_mode)) {
                if (!phc->newline) {
                        printf("%s%c", pathname, '\0');
                        goto out;
@@ -145,9 +172,10 @@ static int
 project_list_one(const char *pathname, struct project_handle_control *phc)
 {
        struct fsxattr fsx;
+       struct stat st;
        int ret;
 
-       ret = project_get_xattr(pathname, &fsx);
+       ret = project_get_xattr(pathname, &fsx, &st);
        if (ret < 0)
                return ret;
 
@@ -163,9 +191,10 @@ static int
 project_set_one(const char *pathname, struct project_handle_control *phc)
 {
        struct fsxattr fsx;
+       struct stat st;
        int fd, ret = 0;
 
-       fd = project_get_xattr(pathname, &fsx);
+       fd = project_get_xattr(pathname, &fsx, &st);
        if (fd < 0)
                return fd;
 
@@ -191,9 +220,10 @@ static int
 project_clear_one(const char *pathname, struct project_handle_control *phc)
 {
        struct fsxattr fsx;
+       struct stat st;
        int ret = 0, fd;
 
-       fd = project_get_xattr(pathname, &fsx);
+       fd = project_get_xattr(pathname, &fsx, &st);
        if (fd < 0)
                return fd;
 
@@ -261,10 +291,6 @@ lfs_project_handle_dir(struct list_head *head, const char *pathname,
                }
        }
 
-       if (ret)
-               fprintf(stderr, "%s: failed to handle dir '%s': %s\n",
-                       progname, pathname, strerror(errno));
-
        closedir(dir);
        return ret;
 }
@@ -304,12 +330,10 @@ static int lfs_project_iterate(const char *pathname,
        while (!list_empty(&head)) {
                lpi = list_entry(head.next, struct lfs_project_item, lpi_list);
                list_del(&lpi->lpi_list);
-               if (rc == 0) {
-                       rc = lfs_project_handle_dir(&head, lpi->lpi_pathname,
-                                                    phc, func);
-                       if (!ret && rc)
-                               ret = rc;
-               }
+               rc = lfs_project_handle_dir(&head, lpi->lpi_pathname,
+                                            phc, func);
+               if (!ret && rc)
+                       ret = rc;
                free(lpi);
        }