#include "../include/lustre_ver.h"
#include "../include/lustre_disk.h" /* for s2sbi */
#include "../include/lustre_eacl.h"
+#include "../include/lustre_linkea.h"
/* for struct cl_lock_descr and struct cl_io */
#include "../include/cl_object.h"
/* llite/xattr.c */
extern const struct xattr_handler *ll_xattr_handlers[];
+#define XATTR_USER_T 1
+#define XATTR_TRUSTED_T 2
+#define XATTR_SECURITY_T 3
+#define XATTR_ACL_ACCESS_T 4
+#define XATTR_ACL_DEFAULT_T 5
+#define XATTR_LUSTRE_T 6
+#define XATTR_OTHER_T 7
+
ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size);
+int ll_xattr_list(struct inode *inode, const char *name, int type,
+ void *buffer, size_t size, __u64 valid);
/**
* Common IO arguments for various VFS I/O interfaces.
int ll_page_sync_io(const struct lu_env *env, struct cl_io *io,
struct cl_page *page, enum cl_req_type crt);
+int ll_getparent(struct file *file, struct getparent __user *arg);
+
/* lcommon_cl.c */
int cl_setattr_ost(struct inode *inode, const struct iattr *attr);
}
up_write(&squash->rsi_sem);
}
+
+/**
+ * Parse linkea content to extract information about a given hardlink
+ *
+ * \param[in] ldata - Initialized linkea data
+ * \param[in] linkno - Link identifier
+ * \param[out] parent_fid - The entry's parent FID
+ * \param[in] size - Entry name destination buffer
+ *
+ * \retval 0 on success
+ * \retval Appropriate negative error code on failure
+ */
+static int ll_linkea_decode(struct linkea_data *ldata, unsigned int linkno,
+ struct lu_fid *parent_fid, struct lu_name *ln)
+{
+ unsigned int idx;
+ int rc;
+
+ rc = linkea_init(ldata);
+ if (rc < 0)
+ return rc;
+
+ if (linkno >= ldata->ld_leh->leh_reccount)
+ /* beyond last link */
+ return -ENODATA;
+
+ linkea_first_entry(ldata);
+ for (idx = 0; ldata->ld_lee; idx++) {
+ linkea_entry_unpack(ldata->ld_lee, &ldata->ld_reclen, ln,
+ parent_fid);
+ if (idx == linkno)
+ break;
+
+ linkea_next_entry(ldata);
+ }
+
+ if (idx < linkno)
+ return -ENODATA;
+
+ return 0;
+}
+
+/**
+ * Get parent FID and name of an identified link. Operation is performed for
+ * a given link number, letting the caller iterate over linkno to list one or
+ * all links of an entry.
+ *
+ * \param[in] file - File descriptor against which to perform the operation
+ * \param[in,out] arg - User-filled structure containing the linkno to operate
+ * on and the available size. It is eventually filled with
+ * the requested information or left untouched on error
+ *
+ * \retval - 0 on success
+ * \retval - Appropriate negative error code on failure
+ */
+int ll_getparent(struct file *file, struct getparent __user *arg)
+{
+ struct inode *inode = file_inode(file);
+ struct linkea_data *ldata;
+ struct lu_fid parent_fid;
+ struct lu_buf buf = {
+ .lb_buf = NULL,
+ .lb_len = 0
+ };
+ struct lu_name ln;
+ u32 name_size;
+ u32 linkno;
+ int rc;
+
+ if (!capable(CFS_CAP_DAC_READ_SEARCH) &&
+ !(ll_i2sbi(inode)->ll_flags & LL_SBI_USER_FID2PATH))
+ return -EPERM;
+
+ if (get_user(name_size, &arg->gp_name_size))
+ return -EFAULT;
+
+ if (get_user(linkno, &arg->gp_linkno))
+ return -EFAULT;
+
+ if (name_size > PATH_MAX)
+ return -EINVAL;
+
+ ldata = kzalloc(sizeof(*ldata), GFP_NOFS);
+ if (!ldata)
+ return -ENOMEM;
+
+ rc = linkea_data_new(ldata, &buf);
+ if (rc < 0)
+ goto ldata_free;
+
+ rc = ll_xattr_list(inode, XATTR_NAME_LINK, XATTR_TRUSTED_T, buf.lb_buf,
+ buf.lb_len, OBD_MD_FLXATTR);
+ if (rc < 0)
+ goto lb_free;
+
+ rc = ll_linkea_decode(ldata, linkno, &parent_fid, &ln);
+ if (rc < 0)
+ goto lb_free;
+
+ if (ln.ln_namelen >= name_size) {
+ rc = -EOVERFLOW;
+ goto lb_free;
+ }
+
+ if (copy_to_user(&arg->gp_fid, &parent_fid, sizeof(arg->gp_fid))) {
+ rc = -EFAULT;
+ goto lb_free;
+ }
+
+ if (copy_to_user(&arg->gp_name, ln.ln_name, ln.ln_namelen)) {
+ rc = -EFAULT;
+ goto lb_free;
+ }
+
+ if (put_user('\0', arg->gp_name + ln.ln_namelen)) {
+ rc = -EFAULT;
+ goto lb_free;
+ }
+
+lb_free:
+ lu_buf_free(&buf);
+ldata_free:
+ kfree(ldata);
+ return rc;
+}
#include "llite_internal.h"
-#define XATTR_USER_T (1)
-#define XATTR_TRUSTED_T (2)
-#define XATTR_SECURITY_T (3)
-#define XATTR_ACL_ACCESS_T (4)
-#define XATTR_ACL_DEFAULT_T (5)
-#define XATTR_LUSTRE_T (6)
-#define XATTR_OTHER_T (7)
-
static
int get_xattr_type(const char *name)
{
flags);
}
-static int
+int
ll_xattr_list(struct inode *inode, const char *name, int type, void *buffer,
size_t size, __u64 valid)
{