home *** CD-ROM | disk | FTP | other *** search
/ ftp.parl.clemson.edu / 2015-02-07.ftp.parl.clemson.edu.tar / ftp.parl.clemson.edu / pub / pvfs2 / orangefs-2.8.3-20110323.tar.gz / orangefs-2.8.3-20110323.tar / orangefs / patches / posix-ext / posix-direntplus-lite.patch next >
Text File  |  2008-01-07  |  14KB  |  442 lines

  1. diff -Naur --exclude-from=/home/vilayann/redhat/BUILD/kernel-2.6.16/exclude vanilla/arch/i386/kernel/syscall_table.S vanilla-new/arch/i386/kernel/syscall_table.S
  2. --- vanilla/arch/i386/kernel/syscall_table.S    2006-08-29 17:56:17.000000000 -0500
  3. +++ vanilla-new/arch/i386/kernel/syscall_table.S    2006-09-04 05:03:44.000000000 -0500
  4. @@ -322,3 +322,5 @@
  5.      .long sys_getdents64_plus /* 320 */
  6.      .long sys_readx
  7.      .long sys_writex
  8. +    .long sys_getdents_plus_lite
  9. +    .long sys_getdents64_plus_lite
  10. diff -Naur --exclude-from=/home/vilayann/redhat/BUILD/kernel-2.6.16/exclude vanilla/fs/readdir.c vanilla-new/fs/readdir.c
  11. --- vanilla/fs/readdir.c    2006-05-24 16:19:07.000000000 -0500
  12. +++ vanilla-new/fs/readdir.c    2006-09-04 04:49:14.000000000 -0500
  13. @@ -69,6 +69,33 @@
  14.  
  15.  EXPORT_SYMBOL_GPL(vfs_readdirplus);
  16.  
  17. +int vfs_readdirplus_lite(struct file *file, unsigned long lite_mask,
  18. +        filldirpluslite_t fillerpluslite, void *buf)
  19. +{
  20. +    struct inode *inode = file->f_dentry->d_inode;
  21. +    int res = -ENOTDIR;
  22. +    if (!file->f_op || !file->f_op->readdirplus_lite)
  23. +        goto out;
  24. +
  25. +    res = security_file_permission(file, MAY_READ);
  26. +    if (res)
  27. +        goto out;
  28. +
  29. +    mutex_lock(&inode->i_mutex);
  30. +    res = -ENOENT;
  31. +    if (!IS_DEADDIR(inode)) {
  32. +        res = file->f_op->readdirplus_lite(file, lite_mask, buf, fillerpluslite);
  33. +        file_accessed(file);
  34. +    }
  35. +    mutex_unlock(&inode->i_mutex);
  36. +out:
  37. +    if (file->f_op && file->f_op->readdir && !file->f_op->readdirplus_lite)
  38. +        res = -EOPNOTSUPP;
  39. +    return res;
  40. +}
  41. +
  42. +EXPORT_SYMBOL_GPL(vfs_readdirplus_lite);
  43. +
  44.  /*
  45.   * Traditional linux readdir() handling..
  46.   *
  47. @@ -343,6 +370,112 @@
  48.      return error;
  49.  }
  50.  
  51. +/* getdents_plus_lite implementation */
  52. +#define DIRENT_OFFSET(de) ((unsigned long) &((de)->dp_dirent) - (unsigned long) (char __user *) (de))
  53. +
  54. +struct linux_dirent_plus_lite {
  55. +    struct stat_lite     dp_stat_lite;
  56. +    int                  dp_stat_lite_err;
  57. +    struct linux_dirent  dp_dirent;
  58. +};
  59. +
  60. +struct getdentspluslite_callback {
  61. +    struct linux_dirent_plus_lite __user * current_dir;
  62. +    struct linux_dirent_plus_lite __user * previous;
  63. +    int count;
  64. +    int error;
  65. +};
  66. +
  67. +static int filldirpluslite(void * __buf, const char * name, int namlen, loff_t offset,
  68. +           ino_t ino, unsigned int d_type, struct kstat_lite *statp)
  69. +{
  70. +    struct linux_dirent __user *de;
  71. +    struct linux_dirent_plus_lite __user * dirent;
  72. +    struct getdentspluslite_callback * buf = (struct getdentspluslite_callback *) __buf;
  73. +    int err, reclen = ROUND_UP(NAME_OFFSET(de) + namlen + DIRENT_OFFSET(dirent) + 2);
  74. +
  75. +    buf->error = -EINVAL;    /* only used if we fail.. */
  76. +    if (reclen > buf->count)
  77. +        return -EINVAL;
  78. +    dirent = buf->previous;
  79. +    if (dirent) {
  80. +        if (__put_user(offset, &dirent->dp_dirent.d_off))
  81. +            goto efault;
  82. +    }
  83. +    dirent = buf->current_dir;
  84. +    err = 0;
  85. +    if (IS_ERR(statp)) {
  86. +        err = PTR_ERR(statp);
  87. +        if (__put_user(err, &dirent->dp_stat_lite_err))
  88. +            goto efault;
  89. +    }
  90. +    else {
  91. +        if (__put_user(err, &dirent->dp_stat_lite_err))
  92. +            goto efault;
  93. +        if (cp_new_statlite(statp, &dirent->dp_stat_lite))
  94. +            goto efault;
  95. +    }
  96. +    if (__put_user(ino, &dirent->dp_dirent.d_ino))
  97. +        goto efault;
  98. +    if (__put_user(reclen, &dirent->dp_dirent.d_reclen))
  99. +        goto efault;
  100. +    if (copy_to_user(dirent->dp_dirent.d_name, name, namlen))
  101. +        goto efault;
  102. +    if (__put_user(0, dirent->dp_dirent.d_name + namlen))
  103. +        goto efault;
  104. +    if (__put_user(d_type, (char __user *) dirent + reclen - 1))
  105. +        goto efault;
  106. +    buf->previous = dirent;
  107. +    dirent = (void __user *)dirent + reclen;
  108. +    buf->current_dir = dirent;
  109. +    buf->count -= reclen;
  110. +    return 0;
  111. +efault:
  112. +    buf->error = -EFAULT;
  113. +    return -EFAULT;
  114. +}
  115. +
  116. +asmlinkage long sys_getdents_plus_lite(unsigned int fd, unsigned long lite_mask, 
  117. +        struct linux_dirent_plus_lite __user * dirent, unsigned int count)
  118. +{
  119. +    struct file * file;
  120. +    struct linux_dirent_plus_lite __user * lastdirent;
  121. +    struct getdentspluslite_callback buf;
  122. +    int error;
  123. +
  124. +    error = -EFAULT;
  125. +    if (!access_ok(VERIFY_WRITE, dirent, count))
  126. +        goto out;
  127. +
  128. +    error = -EBADF;
  129. +    file = fget(fd);
  130. +    if (!file)
  131. +        goto out;
  132. +
  133. +    buf.current_dir = dirent;
  134. +    buf.previous = NULL;
  135. +    buf.count = count;
  136. +    buf.error = 0;
  137. +
  138. +    error = vfs_readdirplus_lite(file, lite_mask, filldirpluslite, &buf);
  139. +    if (error < 0)
  140. +        goto out_putf;
  141. +    error = buf.error;
  142. +    lastdirent = buf.previous;
  143. +    if (lastdirent) {
  144. +        typeof(lastdirent->dp_dirent.d_off) d_off = file->f_pos;
  145. +        error = -EFAULT;
  146. +        if (__put_user(d_off, &lastdirent->dp_dirent.d_off))
  147. +            goto out_putf;
  148. +        error = count - buf.count;
  149. +    }
  150. +
  151. +out_putf:
  152. +    fput(file);
  153. +out:
  154. +    return error;
  155. +}
  156. +
  157.  #define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
  158.  
  159.  struct getdents_callback64 {
  160. @@ -531,3 +664,106 @@
  161.  out:
  162.      return error;
  163.  }
  164. +
  165. +struct getdentspluslite_callback64 {
  166. +    struct linux_dirent64_plus_lite __user * current_dir;
  167. +    struct linux_dirent64_plus_lite __user * previous;
  168. +    int count;
  169. +    int error;
  170. +};
  171. +
  172. +static int filldir64_plus_lite(void * __buf, const char * name, int namlen, loff_t offset,
  173. +             ino_t ino, unsigned int d_type, struct kstat_lite *statp)
  174. +{
  175. +    struct linux_dirent64 __user *de;
  176. +    struct linux_dirent64_plus_lite __user *dirent;
  177. +    struct getdentspluslite_callback64 * buf = (struct getdentspluslite_callback64 *) __buf;
  178. +    int err, reclen = ROUND_UP64(NAME_OFFSET(de) + namlen + 1 + DIRENT_OFFSET(dirent));
  179. +
  180. +    buf->error = -EINVAL;    /* only used if we fail.. */
  181. +    if (reclen > buf->count)
  182. +        return -EINVAL;
  183. +    dirent = buf->previous;
  184. +    if (dirent) {
  185. +        if (__put_user(offset, &dirent->dp_dirent.d_off))
  186. +            goto efault;
  187. +    }
  188. +    dirent = buf->current_dir;
  189. +    err = 0;
  190. +    if (IS_ERR(statp)) {
  191. +        err = PTR_ERR(statp);
  192. +        if (__put_user(err, &dirent->dp_stat_lite_err))
  193. +            goto efault;
  194. +    }
  195. +    else {
  196. +        if (__put_user(err, &dirent->dp_stat_lite_err))
  197. +            goto efault;
  198. +#ifdef __ARCH_WANT_STAT64
  199. +        if (cp_new_stat64_lite(statp, &dirent->dp_stat_lite))
  200. +#else
  201. +        if (cp_new_statlite(statp, &dirent->dp_stat_lite))
  202. +#endif
  203. +            goto efault;
  204. +    }
  205. +    if (__put_user(ino, &dirent->dp_dirent.d_ino))
  206. +        goto efault;
  207. +    if (__put_user(0, &dirent->dp_dirent.d_off))
  208. +        goto efault;
  209. +    if (__put_user(reclen, &dirent->dp_dirent.d_reclen))
  210. +        goto efault;
  211. +    if (__put_user(d_type, &dirent->dp_dirent.d_type))
  212. +        goto efault;
  213. +    if (copy_to_user(dirent->dp_dirent.d_name, name, namlen))
  214. +        goto efault;
  215. +    if (__put_user(0, dirent->dp_dirent.d_name + namlen))
  216. +        goto efault;
  217. +    buf->previous = dirent;
  218. +    dirent = (void __user *)dirent + reclen;
  219. +    buf->current_dir = dirent;
  220. +    buf->count -= reclen;
  221. +    return 0;
  222. +efault:
  223. +    buf->error = -EFAULT;
  224. +    return -EFAULT;
  225. +}
  226. +
  227. +asmlinkage long sys_getdents64_plus_lite(unsigned int fd, unsigned long lite_mask, 
  228. +        struct linux_dirent64_plus_lite __user * dirent, unsigned int count)
  229. +{
  230. +    struct file * file;
  231. +    struct linux_dirent64_plus_lite __user * lastdirent;
  232. +    struct getdentspluslite_callback64 buf;
  233. +    int error;
  234. +
  235. +    error = -EFAULT;
  236. +    if (!access_ok(VERIFY_WRITE, dirent, count))
  237. +        goto out;
  238. +
  239. +    error = -EBADF;
  240. +    file = fget(fd);
  241. +    if (!file)
  242. +        goto out;
  243. +
  244. +    buf.current_dir = dirent;
  245. +    buf.previous = NULL;
  246. +    buf.count = count;
  247. +    buf.error = 0;
  248. +
  249. +    error = vfs_readdirplus_lite(file, lite_mask, filldir64_plus_lite, &buf);
  250. +    if (error < 0)
  251. +        goto out_putf;
  252. +    error = buf.error;
  253. +    lastdirent = buf.previous;
  254. +    if (lastdirent) {
  255. +        typeof(lastdirent->dp_dirent.d_off) d_off = file->f_pos;
  256. +        error = -EFAULT;
  257. +        if (__put_user(d_off, &lastdirent->dp_dirent.d_off))
  258. +            goto out_putf;
  259. +        error = count - buf.count;
  260. +    }
  261. +
  262. +out_putf:
  263. +    fput(file);
  264. +out:
  265. +    return error;
  266. +}
  267. diff -Naur --exclude-from=/home/vilayann/redhat/BUILD/kernel-2.6.16/exclude vanilla/include/asm-i386/dirent.h vanilla-new/include/asm-i386/dirent.h
  268. --- vanilla/include/asm-i386/dirent.h    2006-05-24 16:19:07.000000000 -0500
  269. +++ vanilla-new/include/asm-i386/dirent.h    2006-09-04 04:59:36.000000000 -0500
  270. @@ -9,12 +9,24 @@
  271.      struct dirent dp_dirent;
  272.  };
  273.  
  274. +struct dirent_plus_lite {
  275. +    struct stat_lite dp_stat_lite;
  276. +    int              dp_stat_lite_err;
  277. +    struct dirent    dp_dirent;
  278. +};
  279. +
  280.  struct dirent64_plus {
  281.      struct stat64   dp_stat;
  282.      int             dp_stat_err;
  283.      struct dirent64 dp_dirent;
  284.  };
  285.  
  286. +struct dirent64_plus_lite {
  287. +    struct stat64_lite   dp_stat_lite;
  288. +    int                  dp_stat_lite_err;
  289. +    struct dirent64        dp_dirent;
  290. +};
  291. +
  292.  #ifdef __KERNEL__
  293.  
  294.  struct linux_dirent64_plus {
  295. @@ -23,6 +35,12 @@
  296.      struct linux_dirent64 dp_dirent;
  297.  };
  298.  
  299. +struct linux_dirent64_plus_lite {
  300. +    struct stat64_lite    dp_stat_lite;
  301. +    int                   dp_stat_lite_err;
  302. +    struct linux_dirent64 dp_dirent;
  303. +};
  304. +
  305.  #endif
  306.  
  307.  #endif
  308. diff -Naur --exclude-from=/home/vilayann/redhat/BUILD/kernel-2.6.16/exclude vanilla/include/asm-i386/unistd.h vanilla-new/include/asm-i386/unistd.h
  309. --- vanilla/include/asm-i386/unistd.h    2006-08-29 17:56:17.000000000 -0500
  310. +++ vanilla-new/include/asm-i386/unistd.h    2006-09-04 05:04:09.000000000 -0500
  311. @@ -328,8 +328,10 @@
  312.  #define __NR_getdents64_plus 320
  313.  #define __NR_readx      321
  314.  #define __NR_writex     322
  315. +#define __NR_getdents_plus_lite 323
  316. +#define __NR_getdents64_plus_lite 324
  317.  
  318. -#define NR_syscalls 323
  319. +#define NR_syscalls 325
  320.  
  321.  /*
  322.   * user-visible error numbers are in the range -1 - -128: see
  323. diff -Naur --exclude-from=/home/vilayann/redhat/BUILD/kernel-2.6.16/exclude vanilla/include/asm-x86_64/dirent.h vanilla-new/include/asm-x86_64/dirent.h
  324. --- vanilla/include/asm-x86_64/dirent.h    2006-05-24 16:19:07.000000000 -0500
  325. +++ vanilla-new/include/asm-x86_64/dirent.h    2006-09-04 04:57:56.000000000 -0500
  326. @@ -9,12 +9,24 @@
  327.      struct dirent dp_dirent;
  328.  };
  329.  
  330. +struct dirent_plus_lite {
  331. +    struct stat_lite dp_stat_lite;
  332. +    int              dp_stat_lite_err;
  333. +    struct dirent    dp_dirent;
  334. +};
  335. +
  336.  struct dirent64_plus {
  337.      struct stat     dp_stat;
  338.      int             dp_stat_err;
  339.      struct dirent64 dp_dirent;
  340.  };
  341.  
  342. +struct dirent64_plus_lite {
  343. +    struct stat_lite dp_stat_lite;
  344. +    int              dp_stat_lite_err;
  345. +    struct dirent64  dp_dirent;
  346. +};
  347. +
  348.  #ifdef __KERNEL__
  349.  
  350.  struct linux_dirent64_plus {
  351. @@ -23,6 +35,12 @@
  352.      struct linux_dirent64 dp_dirent;
  353.  };
  354.  
  355. +struct linux_dirent64_plus_lite {
  356. +    struct stat_lite      dp_stat_lite;
  357. +    int                   dp_stat_lite_err;
  358. +    struct linux_dirent64 dp_dirent;
  359. +};
  360. +
  361.  #endif
  362.  
  363.  #endif
  364. diff -Naur --exclude-from=/home/vilayann/redhat/BUILD/kernel-2.6.16/exclude vanilla/include/asm-x86_64/unistd.h vanilla-new/include/asm-x86_64/unistd.h
  365. --- vanilla/include/asm-x86_64/unistd.h    2006-08-29 17:56:17.000000000 -0500
  366. +++ vanilla-new/include/asm-x86_64/unistd.h    2006-09-04 05:04:44.000000000 -0500
  367. @@ -623,8 +623,12 @@
  368.  __SYSCALL(__NR_readx, sys_readx)
  369.  #define __NR_writex 281
  370.  __SYSCALL(__NR_writex, sys_writex)
  371. +#define __NR_getdents_plus_lite 282
  372. +__SYSCALL(__NR_getdents_plus_lite, sys_getdents_plus_lite)
  373. +#define __NR_getdents64_plus_lite 283
  374. +__SYSCALL(__NR_getdents64_plus_lite, sys_getdents64_plus_lite)
  375.  
  376. -#define __NR_syscall_max __NR_writex
  377. +#define __NR_syscall_max __NR_getdents64_plus_lite
  378.  
  379.  #ifndef __NO_STUBS
  380.  
  381. diff -Naur --exclude-from=/home/vilayann/redhat/BUILD/kernel-2.6.16/exclude vanilla/include/linux/fs.h vanilla-new/include/linux/fs.h
  382. --- vanilla/include/linux/fs.h    2006-08-29 17:56:17.000000000 -0500
  383. +++ vanilla-new/include/linux/fs.h    2006-09-04 04:55:48.000000000 -0500
  384. @@ -957,6 +957,13 @@
  385.   */
  386.  typedef int (*filldirplus_t)(void *, const char *, int, loff_t, ino_t, unsigned, struct kstat *);
  387.  
  388. +/* 
  389. + * This is the "filldirplus_lite function type, used by readdirplus_lite() to let
  390. + * the kernel specify the kind of dirent layout and the stat_lite information
  391. + * all in one shot
  392. + */
  393. +typedef int (*filldirpluslite_t)(void *, const char *, int, loff_t, ino_t, unsigned, struct kstat_lite *);
  394. +
  395.  struct block_device_operations {
  396.      int (*open) (struct inode *, struct file *);
  397.      int (*release) (struct inode *, struct file *);
  398. @@ -1032,6 +1039,7 @@
  399.      ssize_t (*aio_write) (struct kiocb *, const char __user *, size_t, loff_t);
  400.      int (*readdir) (struct file *, void *, filldir_t);
  401.      int (*readdirplus) (struct file *, void *, filldirplus_t);
  402. +    int (*readdirplus_lite) (struct file *, unsigned long, void *, filldirpluslite_t);
  403.      unsigned int (*poll) (struct file *, struct poll_table_struct *);
  404.      int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
  405.      long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
  406. @@ -1728,6 +1736,7 @@
  407.  
  408.  extern int vfs_readdir(struct file *, filldir_t, void *);
  409.  extern int vfs_readdirplus(struct file *, filldirplus_t, void *);
  410. +extern int vfs_readdirplus_lite(struct file *file, unsigned long, filldirpluslite_t fillerpluslite, void *buf);
  411.  extern int cp_new_stat(struct kstat *stat, struct stat __user *statbuf);
  412.  extern int cp_new_statlite(struct kstat_lite *stat_lite, struct stat_lite __user *statlitebuf);
  413.  #ifdef __ARCH_WANT_STAT64
  414. diff -Naur --exclude-from=/home/vilayann/redhat/BUILD/kernel-2.6.16/exclude vanilla/include/linux/syscalls.h vanilla-new/include/linux/syscalls.h
  415. --- vanilla/include/linux/syscalls.h    2006-08-29 17:56:17.000000000 -0500
  416. +++ vanilla-new/include/linux/syscalls.h    2006-09-04 05:00:20.000000000 -0500
  417. @@ -25,6 +25,8 @@
  418.  struct linux_dirent64;
  419.  struct linux_dirent_plus;
  420.  struct linux_dirent64_plus;
  421. +struct linux_dirent_plus_lite;
  422. +struct linux_dirent64_plus_lite;
  423.  struct list_head;
  424.  struct msgbuf;
  425.  struct msghdr;
  426. @@ -434,9 +436,15 @@
  427.  asmlinkage long sys_getdents_plus(unsigned int fd,
  428.                  struct linux_dirent_plus __user *dirent,
  429.                  unsigned int count);
  430. +asmlinkage long sys_getdents_plus_lite(unsigned int fd, unsigned long lite_mask,
  431. +                struct linux_dirent_plus_lite __user *dirent,
  432. +                unsigned int count);
  433.  asmlinkage long sys_getdents64_plus(unsigned int fd,
  434.                  struct linux_dirent64_plus __user *dirent,
  435.                  unsigned int count);
  436. +asmlinkage long sys_getdents64_plus_lite(unsigned int fd, unsigned long lite_mask,
  437. +                struct linux_dirent64_plus_lite __user *dirent,
  438. +                unsigned int count);
  439.  
  440.  asmlinkage long sys_setsockopt(int fd, int level, int optname,
  441.                  char __user *optval, int optlen);
  442.